Page MenuHomeFreeBSD

D34325.id.diff
No OneTemporary

D34325.id.diff

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

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)

Event Timeline