Fix Bus Device Resets from userland, and specifically from camcontrol.

camcontrol was setup to use the old scheme of going through the xpt(4)
device, which never worked properly (and has been disabled for a while).

camcontrol now sends BDRs through the pass(4) device, and XPT_RESET_DEV
CCBs are put on the device queue in the transport layer, as they should be.

Submitted by:	luoqi
Reviewed by:	ken
This commit is contained in:
ken 1999-10-31 02:39:44 +00:00
parent f66b8ba3d1
commit b57c214bcc
2 changed files with 42 additions and 12 deletions

View File

@ -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);

View File

@ -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: