diff options
-rw-r--r-- | sbin/camcontrol/camcontrol.c | 52 | ||||
-rw-r--r-- | sys/cam/cam_xpt.c | 2 |
2 files changed, 42 insertions, 12 deletions
diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c index f2ac816..c5b2c93 100644 --- a/sbin/camcontrol/camcontrol.c +++ b/sbin/camcontrol/camcontrol.c @@ -1029,6 +1029,7 @@ static int scanlun_or_reset_dev(int bus, int target, int lun, int scan) { union ccb ccb; + struct cam_device *device; int fd; if (bus < 0) { @@ -1046,31 +1047,60 @@ scanlun_or_reset_dev(int bus, int target, int lun, int scan) return(1); } - if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) { - warnx("error opening tranport layer device %s\n", - XPT_DEVICE); - warn("%s", XPT_DEVICE); - return(1); + fd = -1; + + bzero(&ccb, sizeof(union ccb)); + + if (scan) { + if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) { + warnx("error opening tranport layer device %s\n", + XPT_DEVICE); + warn("%s", XPT_DEVICE); + return(1); + } + } else { + device = cam_open_btl(bus, target, lun, O_RDWR, NULL); + if (device == NULL) { + warnx("%s", cam_errbuf); + return(1); + } } ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV; ccb.ccb_h.path_id = bus; ccb.ccb_h.target_id = target; ccb.ccb_h.target_lun = lun; + ccb.ccb_h.timeout = 5000; ccb.crcn.flags = CAM_FLAG_NONE; /* run this at a low priority */ ccb.ccb_h.pinfo.priority = 5; - if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) { - warn("CAMIOCOMMAND ioctl failed"); - close(fd); - return(1); + if (scan) { + if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) { + warn("CAMIOCOMMAND ioctl failed"); + close(fd); + return(1); + } + } else { + if (cam_send_ccb(device, &ccb) < 0) { + warn("error sending XPT_RESET_DEV CCB"); + cam_close_device(device); + return(1); + } } - close(fd); + if (scan) + close(fd); + else + cam_close_device(device); - if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { + /* + * An error code of CAM_BDR_SENT is normal for a BDR request. + */ + if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) + || ((!scan) + && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) { fprintf(stdout, "%s of %d:%d:%d was successful\n", scan? "Re-scan" : "Reset", bus, target, lun); return(0); diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index 466af40..2aad3a7 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -2764,6 +2764,7 @@ xpt_action(union ccb *start_ccb) start_ccb->csio.sense_resid = 0; start_ccb->csio.resid = 0; /* FALLTHROUGH */ + case XPT_RESET_DEV: case XPT_ENG_EXEC: { struct cam_path *path; @@ -2874,7 +2875,6 @@ xpt_action(union ccb *start_ccb) */ /* FALLTHROUGH */ } - case XPT_RESET_DEV: case XPT_ACCEPT_TARGET_IO: case XPT_EN_LUN: case XPT_IMMED_NOTIFY: |