add Bus and Device Reset commands

This commit is contained in:
Matt Jacob 1998-12-20 18:51:56 +00:00
parent 450fefa9f3
commit a2a4483652
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=41962
2 changed files with 47 additions and 27 deletions

View File

@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" $Id: camcontrol.8,v 1.7 1998/10/06 00:32:58 ken Exp $ .\" $Id: camcontrol.8,v 1.8 1998/12/02 22:42:36 billf Exp $
.\" .\"
.Dd September 14, 1998 .Dd September 14, 1998
.Dt CAMCONTROL 8 .Dt CAMCONTROL 8
@ -67,6 +67,9 @@ eject
rescan rescan
.Aq bus Ns Op :target:lun .Aq bus Ns Op :target:lun
.Nm camcontrol .Nm camcontrol
reset
.Aq bus Ns Op :target:lun
.Nm camcontrol
defects defects
.Op generic args .Op generic args
.Aq Fl f Ar format .Aq Fl f Ar format
@ -184,6 +187,12 @@ Tell the kernel to scan the given bus (XPT_SCAN_BUS), or bus:target:lun
(XPT_SCAN_LUN) for new devices or devices that have gone away. The user (XPT_SCAN_LUN) for new devices or devices that have gone away. The user
may only specify a bus to scan, or a lun. Scanning all luns on a target may only specify a bus to scan, or a lun. Scanning all luns on a target
isn't supported. isn't supported.
.It reset
Tell the kernel to reset the given bus (XPT_RESET_BUS) by issuing a SCSI bus
reset for that bus, or to reset the given bus:target:lun
(XPT_RESET_DEV), typically by issuing a BUS DEVICE RESET message after
connecting to that device. Note that this can have a destructive impact
on the system.
.It defects .It defects
Send the SCSI READ DEFECT DATA (10) command (0x37) to the given device, and Send the SCSI READ DEFECT DATA (10) command (0x37) to the given device, and
print out any combination of: the total number of defects, the primary print out any combination of: the total number of defects, the primary

View File

@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: camcontrol.c,v 1.5 1998/10/13 22:02:38 ken Exp $ * $Id: camcontrol.c,v 1.6 1998/11/12 17:47:24 ken Exp $
*/ */
#include <sys/ioctl.h> #include <sys/ioctl.h>
@ -64,6 +64,7 @@ typedef enum {
CAM_ARG_DEVTREE = 0x00000009, CAM_ARG_DEVTREE = 0x00000009,
CAM_ARG_USAGE = 0x0000000a, CAM_ARG_USAGE = 0x0000000a,
CAM_ARG_DEBUG = 0x0000000b, CAM_ARG_DEBUG = 0x0000000b,
CAM_ARG_RESET = 0x0000000c,
CAM_ARG_OPT_MASK = 0x0000000f, CAM_ARG_OPT_MASK = 0x0000000f,
CAM_ARG_VERBOSE = 0x00000010, CAM_ARG_VERBOSE = 0x00000010,
CAM_ARG_DEVICE = 0x00000020, CAM_ARG_DEVICE = 0x00000020,
@ -115,6 +116,7 @@ struct camcontrol_opts option_table[] = {
{"stop", CAM_ARG_STARTSTOP, NULL}, {"stop", CAM_ARG_STARTSTOP, NULL},
{"eject", CAM_ARG_STARTSTOP | CAM_ARG_EJECT, NULL}, {"eject", CAM_ARG_STARTSTOP | CAM_ARG_EJECT, NULL},
{"rescan", CAM_ARG_RESCAN, NULL}, {"rescan", CAM_ARG_RESCAN, NULL},
{"reset", CAM_ARG_RESET, NULL},
{"cmd", CAM_ARG_SCSI_CMD, scsicmd_opts}, {"cmd", CAM_ARG_SCSI_CMD, scsicmd_opts},
{"command", CAM_ARG_SCSI_CMD, scsicmd_opts}, {"command", CAM_ARG_SCSI_CMD, scsicmd_opts},
{"defects", CAM_ARG_READ_DEFECTS, readdefect_opts}, {"defects", CAM_ARG_READ_DEFECTS, readdefect_opts},
@ -150,9 +152,9 @@ static int scsidoinquiry(struct cam_device *device, int argc, char **argv,
static int scsiinquiry(struct cam_device *device, int retry_count, int timeout); static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
static int scsiserial(struct cam_device *device, int retry_count, int timeout); static int scsiserial(struct cam_device *device, int retry_count, int timeout);
static int scsixferrate(struct cam_device *device); static int scsixferrate(struct cam_device *device);
static int dorescan(int argc, char **argv); static int dorescan_or_reset(int argc, char **argv, int rescan);
static int rescanbus(int bus); static int rescan_or_reset_bus(int bus, int rescan);
static int scanlun(int bus, int target, int lun); static int scanlun_or_reset_dev(int bus, int target, int lun, int scan);
static int readdefects(struct cam_device *device, int argc, char **argv, static int readdefects(struct cam_device *device, int argc, char **argv,
char *combinedopt, int retry_count, int timeout); char *combinedopt, int retry_count, int timeout);
static void modepage(struct cam_device *device, int argc, char **argv, static void modepage(struct cam_device *device, int argc, char **argv,
@ -797,14 +799,16 @@ scsixferrate(struct cam_device *device)
} }
static int static int
dorescan(int argc, char **argv) dorescan_or_reset(int argc, char **argv, int rescan)
{ {
static const char *must =
"you must specify a bus, or a bus:target:lun to %s";
int error = 0; int error = 0;
int bus = -1, target = -1, lun = -1; int bus = -1, target = -1, lun = -1;
char *tstr, *tmpstr = NULL; char *tstr, *tmpstr = NULL;
if (argc < 3) { if (argc < 3) {
warnx("you must specify a bus, or a bus:target:lun to rescan"); warnx(must, rescan? "rescan" : "reset");
return(1); return(1);
} }
/* /*
@ -833,13 +837,12 @@ dorescan(int argc, char **argv)
arglist |= CAM_ARG_LUN; arglist |= CAM_ARG_LUN;
} else { } else {
error = 1; error = 1;
warnx("you must specify either a bus or"); warnx(must, rescan? "rescan" : "reset");
warnx("a bus, target and lun for rescanning");
} }
} }
} else { } else {
error = 1; error = 1;
warnx("you must at least specify a bus to rescan"); warnx(must, rescan? "rescan" : "reset");
} }
@ -847,20 +850,19 @@ dorescan(int argc, char **argv)
if ((arglist & CAM_ARG_BUS) if ((arglist & CAM_ARG_BUS)
&& (arglist & CAM_ARG_TARGET) && (arglist & CAM_ARG_TARGET)
&& (arglist & CAM_ARG_LUN)) && (arglist & CAM_ARG_LUN))
error = scanlun(bus, target, lun); error = scanlun_or_reset_dev(bus, target, lun, rescan);
else if (arglist & CAM_ARG_BUS) else if (arglist & CAM_ARG_BUS)
error = rescanbus(bus); error = rescan_or_reset_bus(bus, rescan);
else { else {
error = 1; error = 1;
warnx("you must specify either a bus or"); warnx(must, rescan? "rescan" : "reset");
warnx("a bus, target and lun for rescanning");
} }
} }
return(error); return(error);
} }
static int static int
rescanbus(int bus) rescan_or_reset_bus(int bus, int rescan)
{ {
union ccb ccb; union ccb ccb;
int fd; int fd;
@ -876,7 +878,7 @@ rescanbus(int bus)
return(1); return(1);
} }
ccb.ccb_h.func_code = XPT_SCAN_BUS; ccb.ccb_h.func_code = rescan? XPT_SCAN_BUS : XPT_RESET_BUS;
ccb.ccb_h.path_id = bus; ccb.ccb_h.path_id = bus;
ccb.ccb_h.target_id = CAM_TARGET_WILDCARD; ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
@ -894,17 +896,19 @@ rescanbus(int bus)
close(fd); close(fd);
if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
fprintf(stdout, "Re-scan of bus %d was successful\n", bus); fprintf(stdout, "%s of bus %d was successful\n", bus,
rescan? "Re-scan" : "Reset");
return(0); return(0);
} else { } else {
fprintf(stdout, "Re-scan of bus %d returned error %#x\n", fprintf(stdout, "%s of bus %d returned error %#x\n",
bus, ccb.ccb_h.status & CAM_STATUS_MASK); rescan? "Re-scan" : "Reset", bus,
ccb.ccb_h.status & CAM_STATUS_MASK);
return(1); return(1);
} }
} }
static int static int
scanlun(int bus, int target, int lun) scanlun_or_reset_dev(int bus, int target, int lun, int scan)
{ {
union ccb ccb; union ccb ccb;
int fd; int fd;
@ -931,7 +935,7 @@ scanlun(int bus, int target, int lun)
return(1); return(1);
} }
ccb.ccb_h.func_code = XPT_SCAN_LUN; ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
ccb.ccb_h.path_id = bus; ccb.ccb_h.path_id = bus;
ccb.ccb_h.target_id = target; ccb.ccb_h.target_id = target;
ccb.ccb_h.target_lun = lun; ccb.ccb_h.target_lun = lun;
@ -949,12 +953,13 @@ scanlun(int bus, int target, int lun)
close(fd); close(fd);
if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
fprintf(stdout, "Re-scan of %d:%d:%d was successful\n", fprintf(stdout, "%s of %d:%d:%d was successful\n",
bus, target, lun); scan? "Re-scan" : "Reset", bus, target, lun);
return(0); return(0);
} else { } else {
fprintf(stdout, "Re-scan of %d:%d:%d returned error %#x\n", fprintf(stdout, "%s of %d:%d:%d returned error %#x\n",
bus, target, lun, ccb.ccb_h.status & CAM_STATUS_MASK); scan? "Re-scan" : "Reset", bus, target, lun,
ccb.ccb_h.status & CAM_STATUS_MASK);
return(1); return(1);
} }
} }
@ -1789,6 +1794,7 @@ usage(void)
" camcontrol stop [generic args]\n" " camcontrol stop [generic args]\n"
" camcontrol eject [generic args]\n" " camcontrol eject [generic args]\n"
" camcontrol rescan <bus[:target:lun]>\n" " camcontrol rescan <bus[:target:lun]>\n"
" camcontrol reset <bus[:target:lun]>\n"
" camcontrol defects [generic args] <-f format> [-P][-G]\n" " camcontrol defects [generic args] <-f format> [-P][-G]\n"
" camcontrol modepage [generic args] <-m page> [-P pagectl][-e][-d]\n" " camcontrol modepage [generic args] <-m page> [-P pagectl][-e][-d]\n"
" camcontrol cmd [generic args] <-c cmd [args]> \n" " camcontrol cmd [generic args] <-c cmd [args]> \n"
@ -1803,6 +1809,7 @@ usage(void)
"stop send a Stop Unit command to the device\n" "stop send a Stop Unit command to the device\n"
"eject send a Stop Unit command to the device with the eject bit set\n" "eject send a Stop Unit command to the device with the eject bit set\n"
"rescan rescan the given bus, or bus:target:lun\n" "rescan rescan the given bus, or bus:target:lun\n"
"reset reset the given bus, or bus:target:lun\n"
"defects read the defect list of the specified device\n" "defects read the defect list of the specified device\n"
"modepage display or edit (-e) the given mode page\n" "modepage display or edit (-e) the given mode page\n"
"cmd send the given scsi command, may need -i or -o as well\n" "cmd send the given scsi command, may need -i or -o as well\n"
@ -1989,7 +1996,8 @@ main(int argc, char **argv)
* commands, we don't use a passthrough device at all, just the * commands, we don't use a passthrough device at all, just the
* transport layer device. * transport layer device.
*/ */
if (((arglist & CAM_ARG_OPT_MASK) != CAM_ARG_RESCAN) if (((arglist & CAM_ARG_OPT_MASK) != CAM_ARG_RESCAN)
&& ((arglist & CAM_ARG_OPT_MASK) != CAM_ARG_RESET)
&& ((arglist & CAM_ARG_OPT_MASK) != CAM_ARG_DEVTREE) && ((arglist & CAM_ARG_OPT_MASK) != CAM_ARG_DEVTREE)
&& ((arglist & CAM_ARG_OPT_MASK) != CAM_ARG_USAGE) && ((arglist & CAM_ARG_OPT_MASK) != CAM_ARG_USAGE)
&& ((arglist & CAM_ARG_OPT_MASK) != CAM_ARG_DEBUG)) { && ((arglist & CAM_ARG_OPT_MASK) != CAM_ARG_DEBUG)) {
@ -2026,7 +2034,10 @@ main(int argc, char **argv)
timeout); timeout);
break; break;
case CAM_ARG_RESCAN: case CAM_ARG_RESCAN:
error = dorescan(argc, argv); error = dorescan_or_reset(argc, argv, 1);
break;
case CAM_ARG_RESET:
error = dorescan_or_reset(argc, argv, 0);
break; break;
case CAM_ARG_READ_DEFECTS: case CAM_ARG_READ_DEFECTS:
error = readdefects(cam_dev, argc, argv, combinedopt, error = readdefects(cam_dev, argc, argv, combinedopt,