Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F111374825
D34325.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D34325.id.diff
View Options
diff --git a/sbin/camcontrol/fwdownload.c b/sbin/camcontrol/fwdownload.c
--- a/sbin/camcontrol/fwdownload.c
+++ b/sbin/camcontrol/fwdownload.c
@@ -57,12 +57,15 @@
#include <err.h>
#include <fcntl.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <cam/cam.h>
#include <cam/scsi/scsi_all.h>
+#include <cam/scsi/scsi_pass.h>
#include <cam/scsi/scsi_message.h>
#include <camlib.h>
@@ -759,6 +762,67 @@
return (retval);
}
+/*
+ * After the firmware is downloaded, we know the sense data has changed (or is
+ * likely to change since it contains the firmware version). Rescan the target
+ * with a flag to tell the kernel it's OK. This allows us to continnue using the
+ * old periph/disk in the kernel, which is less disruptive. We rescan the target
+ * because multilun devices usually update all the luns after the first firmware
+ * download.
+ */
+static int
+fw_rescan_lun(struct cam_device *dev, bool printerrors)
+{
+ union ccb ccb;
+ int fd;
+ target_id_t target;
+ uint32_t bus;
+
+ /* Can only send XPT_SCAN_TGT via /dev/xpt, not pass device in *dev */
+ if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
+ warnx("error opening transport layer device %s\n",
+ XPT_DEVICE);
+ warn("%s", XPT_DEVICE);
+ return (1);
+ }
+
+ /* Fill in the bus and target IDs as they don't seem to be in *dev */
+ bzero(&ccb, sizeof(union ccb));
+ ccb.ccb_h.func_code = XPT_GDEVLIST;
+ strlcpy(ccb.cgdl.periph_name, dev->device_name, sizeof(ccb.cgdl.periph_name));
+ ccb.cgdl.unit_number = dev->dev_unit_num;
+ if (cam_send_ccb(dev, &ccb) < 0) {
+ warn("send_ccb GDEVLIST failed\n");
+ close(fd);
+ return (1);
+ }
+ bus = ccb.ccb_h.path_id;
+ target = ccb.ccb_h.target_id;
+
+ /* Rescan the target */
+ bzero(&ccb, sizeof(union ccb));
+ ccb.ccb_h.func_code = XPT_SCAN_TGT;
+ ccb.ccb_h.path_id = bus;
+ ccb.ccb_h.target_id = target;
+ ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
+ ccb.crcn.flags = CAM_EXPECT_INQ_CHANGE;
+ ccb.ccb_h.pinfo.priority = 5; /* run this at a low priority */
+
+ if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
+ warn("CAMIOCOMMAND XPT_SCAN_TGT ioctl failed");
+ close(fd);
+ return (1);
+ }
+ if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
+ warn("Can't send rescan lun");
+ if (printerrors)
+ cam_error_print(dev, &ccb, CAM_ESF_ALL, CAM_EPF_ALL,
+ stderr);
+ return (1);
+ }
+ return (0);
+}
+
/*
* Download firmware stored in buf to cam_dev. If simulation mode
* is enabled, only show what packet sizes would be sent to the
@@ -912,6 +976,9 @@
if (quiet == 0)
progress_complete(&progress, size - img_size);
cam_freeccb(ccb);
+ if (retval == 0 && !sim_mode) {
+ fw_rescan_lun(cam_dev, printerrors);
+ }
return (retval);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Mar 4, 12:09 AM (7 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16956741
Default Alt Text
D34325.id.diff (2 KB)
Attached To
Mode
D34325: camcontrol: Force a rescan of the lun after firmware download.
Attached
Detach File
Event Timeline
Log In to Comment