summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sbin/camcontrol/camcontrol.c52
-rw-r--r--sys/cam/cam_xpt.c2
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:
OpenPOWER on IntegriCloud