2 * Copyright (c) 1997-2007 Kenneth D. Merry
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/ioctl.h>
33 #include <sys/stdint.h>
34 #include <sys/types.h>
35 #include <sys/endian.h>
47 #include <cam/cam_debug.h>
48 #include <cam/cam_ccb.h>
49 #include <cam/scsi/scsi_all.h>
50 #include <cam/scsi/scsi_da.h>
51 #include <cam/scsi/scsi_pass.h>
52 #include <cam/scsi/scsi_message.h>
53 #include <cam/ata/ata_all.h>
55 #include "camcontrol.h"
58 CAM_CMD_NONE = 0x00000000,
59 CAM_CMD_DEVLIST = 0x00000001,
60 CAM_CMD_TUR = 0x00000002,
61 CAM_CMD_INQUIRY = 0x00000003,
62 CAM_CMD_STARTSTOP = 0x00000004,
63 CAM_CMD_RESCAN = 0x00000005,
64 CAM_CMD_READ_DEFECTS = 0x00000006,
65 CAM_CMD_MODE_PAGE = 0x00000007,
66 CAM_CMD_SCSI_CMD = 0x00000008,
67 CAM_CMD_DEVTREE = 0x00000009,
68 CAM_CMD_USAGE = 0x0000000a,
69 CAM_CMD_DEBUG = 0x0000000b,
70 CAM_CMD_RESET = 0x0000000c,
71 CAM_CMD_FORMAT = 0x0000000d,
72 CAM_CMD_TAG = 0x0000000e,
73 CAM_CMD_RATE = 0x0000000f,
74 CAM_CMD_DETACH = 0x00000010,
75 CAM_CMD_REPORTLUNS = 0x00000011,
76 CAM_CMD_READCAP = 0x00000012,
77 CAM_CMD_IDENTIFY = 0x00000013,
78 CAM_CMD_IDLE = 0x00000014,
79 CAM_CMD_STANDBY = 0x00000015,
80 CAM_CMD_SLEEP = 0x00000016
84 CAM_ARG_NONE = 0x00000000,
85 CAM_ARG_VERBOSE = 0x00000001,
86 CAM_ARG_DEVICE = 0x00000002,
87 CAM_ARG_BUS = 0x00000004,
88 CAM_ARG_TARGET = 0x00000008,
89 CAM_ARG_LUN = 0x00000010,
90 CAM_ARG_EJECT = 0x00000020,
91 CAM_ARG_UNIT = 0x00000040,
92 CAM_ARG_FORMAT_BLOCK = 0x00000080,
93 CAM_ARG_FORMAT_BFI = 0x00000100,
94 CAM_ARG_FORMAT_PHYS = 0x00000200,
95 CAM_ARG_PLIST = 0x00000400,
96 CAM_ARG_GLIST = 0x00000800,
97 CAM_ARG_GET_SERIAL = 0x00001000,
98 CAM_ARG_GET_STDINQ = 0x00002000,
99 CAM_ARG_GET_XFERRATE = 0x00004000,
100 CAM_ARG_INQ_MASK = 0x00007000,
101 CAM_ARG_MODE_EDIT = 0x00008000,
102 CAM_ARG_PAGE_CNTL = 0x00010000,
103 CAM_ARG_TIMEOUT = 0x00020000,
104 CAM_ARG_CMD_IN = 0x00040000,
105 CAM_ARG_CMD_OUT = 0x00080000,
106 CAM_ARG_DBD = 0x00100000,
107 CAM_ARG_ERR_RECOVER = 0x00200000,
108 CAM_ARG_RETRIES = 0x00400000,
109 CAM_ARG_START_UNIT = 0x00800000,
110 CAM_ARG_DEBUG_INFO = 0x01000000,
111 CAM_ARG_DEBUG_TRACE = 0x02000000,
112 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
113 CAM_ARG_DEBUG_CDB = 0x08000000,
114 CAM_ARG_DEBUG_XPT = 0x10000000,
115 CAM_ARG_DEBUG_PERIPH = 0x20000000,
118 struct camcontrol_opts {
126 static const char scsicmd_opts[] = "a:c:dfi:o:r";
127 static const char readdefect_opts[] = "f:GP";
128 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
131 struct camcontrol_opts option_table[] = {
133 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
134 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
135 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
136 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
137 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
138 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
139 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
140 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
141 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
142 #endif /* MINIMALISTIC */
143 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
144 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
146 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
147 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
148 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
149 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
150 #endif /* MINIMALISTIC */
151 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, NULL},
153 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
154 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
155 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
156 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
157 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
158 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXc"},
159 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
160 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
161 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
162 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
163 #endif /* MINIMALISTIC */
164 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
165 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
166 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
180 camcontrol_optret getoption(char *arg, cam_cmdmask *cmdnum, cam_argmask *argnum,
181 const char **subopt);
183 static int getdevlist(struct cam_device *device);
184 #endif /* MINIMALISTIC */
185 static int getdevtree(void);
187 static int testunitready(struct cam_device *device, int retry_count,
188 int timeout, int quiet);
189 static int scsistart(struct cam_device *device, int startstop, int loadeject,
190 int retry_count, int timeout);
191 static int scsidoinquiry(struct cam_device *device, int argc, char **argv,
192 char *combinedopt, int retry_count, int timeout);
193 static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
194 static int scsiserial(struct cam_device *device, int retry_count, int timeout);
195 static int camxferrate(struct cam_device *device);
196 #endif /* MINIMALISTIC */
197 static int parse_btl(char *tstr, int *bus, int *target, int *lun,
198 cam_argmask *arglst);
199 static int dorescan_or_reset(int argc, char **argv, int rescan);
200 static int rescan_or_reset_bus(int bus, int rescan);
201 static int scanlun_or_reset_dev(int bus, int target, int lun, int scan);
203 static int readdefects(struct cam_device *device, int argc, char **argv,
204 char *combinedopt, int retry_count, int timeout);
205 static void modepage(struct cam_device *device, int argc, char **argv,
206 char *combinedopt, int retry_count, int timeout);
207 static int scsicmd(struct cam_device *device, int argc, char **argv,
208 char *combinedopt, int retry_count, int timeout);
209 static int tagcontrol(struct cam_device *device, int argc, char **argv,
211 static void cts_print(struct cam_device *device,
212 struct ccb_trans_settings *cts);
213 static void cpi_print(struct ccb_pathinq *cpi);
214 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
215 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
216 static int get_print_cts(struct cam_device *device, int user_settings,
217 int quiet, struct ccb_trans_settings *cts);
218 static int ratecontrol(struct cam_device *device, int retry_count,
219 int timeout, int argc, char **argv, char *combinedopt);
220 static int scsiformat(struct cam_device *device, int argc, char **argv,
221 char *combinedopt, int retry_count, int timeout);
222 static int scsireportluns(struct cam_device *device, int argc, char **argv,
223 char *combinedopt, int retry_count, int timeout);
224 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
225 char *combinedopt, int retry_count, int timeout);
226 static int atapm(struct cam_device *device, int argc, char **argv,
227 char *combinedopt, int retry_count, int timeout);
228 #endif /* MINIMALISTIC */
230 #define min(a,b) (((a)<(b))?(a):(b))
233 #define max(a,b) (((a)>(b))?(a):(b))
237 getoption(char *arg, cam_cmdmask *cmdnum, cam_argmask *argnum,
240 struct camcontrol_opts *opts;
243 for (opts = option_table; (opts != NULL) && (opts->optname != NULL);
245 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
246 *cmdnum = opts->cmdnum;
247 *argnum = opts->argnum;
248 *subopt = opts->subopt;
249 if (++num_matches > 1)
250 return(CC_OR_AMBIGUOUS);
257 return(CC_OR_NOT_FOUND);
262 getdevlist(struct cam_device *device)
268 ccb = cam_getccb(device);
270 ccb->ccb_h.func_code = XPT_GDEVLIST;
271 ccb->ccb_h.flags = CAM_DIR_NONE;
272 ccb->ccb_h.retry_count = 1;
274 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
275 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
276 if (cam_send_ccb(device, ccb) < 0) {
277 perror("error getting device list");
284 switch (ccb->cgdl.status) {
285 case CAM_GDEVLIST_MORE_DEVS:
286 strcpy(status, "MORE");
288 case CAM_GDEVLIST_LAST_DEVICE:
289 strcpy(status, "LAST");
291 case CAM_GDEVLIST_LIST_CHANGED:
292 strcpy(status, "CHANGED");
294 case CAM_GDEVLIST_ERROR:
295 strcpy(status, "ERROR");
300 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
301 ccb->cgdl.periph_name,
302 ccb->cgdl.unit_number,
303 ccb->cgdl.generation,
308 * If the list has changed, we need to start over from the
311 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
319 #endif /* MINIMALISTIC */
331 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
332 warn("couldn't open %s", XPT_DEVICE);
336 bzero(&ccb, sizeof(union ccb));
338 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
339 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
340 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
342 ccb.ccb_h.func_code = XPT_DEV_MATCH;
343 bufsize = sizeof(struct dev_match_result) * 100;
344 ccb.cdm.match_buf_len = bufsize;
345 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
346 if (ccb.cdm.matches == NULL) {
347 warnx("can't malloc memory for matches");
351 ccb.cdm.num_matches = 0;
354 * We fetch all nodes, since we display most of them in the default
355 * case, and all in the verbose case.
357 ccb.cdm.num_patterns = 0;
358 ccb.cdm.pattern_buf_len = 0;
361 * We do the ioctl multiple times if necessary, in case there are
362 * more than 100 nodes in the EDT.
365 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
366 warn("error sending CAMIOCOMMAND ioctl");
371 if ((ccb.ccb_h.status != CAM_REQ_CMP)
372 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
373 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
374 warnx("got CAM error %#x, CDM error %d\n",
375 ccb.ccb_h.status, ccb.cdm.status);
380 for (i = 0; i < ccb.cdm.num_matches; i++) {
381 switch (ccb.cdm.matches[i].type) {
382 case DEV_MATCH_BUS: {
383 struct bus_match_result *bus_result;
386 * Only print the bus information if the
387 * user turns on the verbose flag.
389 if ((arglist & CAM_ARG_VERBOSE) == 0)
393 &ccb.cdm.matches[i].result.bus_result;
396 fprintf(stdout, ")\n");
400 fprintf(stdout, "scbus%d on %s%d bus %d:\n",
402 bus_result->dev_name,
403 bus_result->unit_number,
407 case DEV_MATCH_DEVICE: {
408 struct device_match_result *dev_result;
409 char vendor[16], product[48], revision[16];
413 &ccb.cdm.matches[i].result.device_result;
415 if ((dev_result->flags
416 & DEV_RESULT_UNCONFIGURED)
417 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
423 if (dev_result->protocol == PROTO_SCSI) {
424 cam_strvis(vendor, dev_result->inq_data.vendor,
425 sizeof(dev_result->inq_data.vendor),
428 dev_result->inq_data.product,
429 sizeof(dev_result->inq_data.product),
432 dev_result->inq_data.revision,
433 sizeof(dev_result->inq_data.revision),
435 sprintf(tmpstr, "<%s %s %s>", vendor, product,
437 } else if (dev_result->protocol == PROTO_ATA ||
438 dev_result->protocol == PROTO_SATAPM) {
440 dev_result->ident_data.model,
441 sizeof(dev_result->ident_data.model),
444 dev_result->ident_data.revision,
445 sizeof(dev_result->ident_data.revision),
447 sprintf(tmpstr, "<%s %s>", product,
450 sprintf(tmpstr, "<>");
453 fprintf(stdout, ")\n");
457 fprintf(stdout, "%-33s at scbus%d "
458 "target %d lun %d (",
461 dev_result->target_id,
462 dev_result->target_lun);
468 case DEV_MATCH_PERIPH: {
469 struct periph_match_result *periph_result;
472 &ccb.cdm.matches[i].result.periph_result;
474 if (skip_device != 0)
478 fprintf(stdout, ",");
480 fprintf(stdout, "%s%d",
481 periph_result->periph_name,
482 periph_result->unit_number);
488 fprintf(stdout, "unknown match type\n");
493 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
494 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
497 fprintf(stdout, ")\n");
506 testunitready(struct cam_device *device, int retry_count, int timeout,
512 ccb = cam_getccb(device);
514 scsi_test_unit_ready(&ccb->csio,
515 /* retries */ retry_count,
517 /* tag_action */ MSG_SIMPLE_Q_TAG,
518 /* sense_len */ SSD_FULL_SIZE,
519 /* timeout */ timeout ? timeout : 5000);
521 /* Disable freezing the device queue */
522 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
524 if (arglist & CAM_ARG_ERR_RECOVER)
525 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
527 if (cam_send_ccb(device, ccb) < 0) {
529 perror("error sending test unit ready");
531 if (arglist & CAM_ARG_VERBOSE) {
532 cam_error_print(device, ccb, CAM_ESF_ALL,
533 CAM_EPF_ALL, stderr);
540 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
542 fprintf(stdout, "Unit is ready\n");
545 fprintf(stdout, "Unit is not ready\n");
548 if (arglist & CAM_ARG_VERBOSE) {
549 cam_error_print(device, ccb, CAM_ESF_ALL,
550 CAM_EPF_ALL, stderr);
560 scsistart(struct cam_device *device, int startstop, int loadeject,
561 int retry_count, int timeout)
566 ccb = cam_getccb(device);
569 * If we're stopping, send an ordered tag so the drive in question
570 * will finish any previously queued writes before stopping. If
571 * the device isn't capable of tagged queueing, or if tagged
572 * queueing is turned off, the tag action is a no-op.
574 scsi_start_stop(&ccb->csio,
575 /* retries */ retry_count,
577 /* tag_action */ startstop ? MSG_SIMPLE_Q_TAG :
579 /* start/stop */ startstop,
580 /* load_eject */ loadeject,
582 /* sense_len */ SSD_FULL_SIZE,
583 /* timeout */ timeout ? timeout : 120000);
585 /* Disable freezing the device queue */
586 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
588 if (arglist & CAM_ARG_ERR_RECOVER)
589 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
591 if (cam_send_ccb(device, ccb) < 0) {
592 perror("error sending start unit");
594 if (arglist & CAM_ARG_VERBOSE) {
595 cam_error_print(device, ccb, CAM_ESF_ALL,
596 CAM_EPF_ALL, stderr);
603 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
605 fprintf(stdout, "Unit started successfully");
607 fprintf(stdout,", Media loaded\n");
609 fprintf(stdout,"\n");
611 fprintf(stdout, "Unit stopped successfully");
613 fprintf(stdout, ", Media ejected\n");
615 fprintf(stdout, "\n");
621 "Error received from start unit command\n");
624 "Error received from stop unit command\n");
626 if (arglist & CAM_ARG_VERBOSE) {
627 cam_error_print(device, ccb, CAM_ESF_ALL,
628 CAM_EPF_ALL, stderr);
638 scsidoinquiry(struct cam_device *device, int argc, char **argv,
639 char *combinedopt, int retry_count, int timeout)
644 while ((c = getopt(argc, argv, combinedopt)) != -1) {
647 arglist |= CAM_ARG_GET_STDINQ;
650 arglist |= CAM_ARG_GET_XFERRATE;
653 arglist |= CAM_ARG_GET_SERIAL;
661 * If the user didn't specify any inquiry options, he wants all of
664 if ((arglist & CAM_ARG_INQ_MASK) == 0)
665 arglist |= CAM_ARG_INQ_MASK;
667 if (arglist & CAM_ARG_GET_STDINQ)
668 error = scsiinquiry(device, retry_count, timeout);
673 if (arglist & CAM_ARG_GET_SERIAL)
674 scsiserial(device, retry_count, timeout);
679 if (arglist & CAM_ARG_GET_XFERRATE)
680 error = camxferrate(device);
686 scsiinquiry(struct cam_device *device, int retry_count, int timeout)
689 struct scsi_inquiry_data *inq_buf;
692 ccb = cam_getccb(device);
695 warnx("couldn't allocate CCB");
699 /* cam_getccb cleans up the header, caller has to zero the payload */
700 bzero(&(&ccb->ccb_h)[1],
701 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
703 inq_buf = (struct scsi_inquiry_data *)malloc(
704 sizeof(struct scsi_inquiry_data));
706 if (inq_buf == NULL) {
708 warnx("can't malloc memory for inquiry\n");
711 bzero(inq_buf, sizeof(*inq_buf));
714 * Note that although the size of the inquiry buffer is the full
715 * 256 bytes specified in the SCSI spec, we only tell the device
716 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
717 * two reasons for this:
719 * - The SCSI spec says that when a length field is only 1 byte,
720 * a value of 0 will be interpreted as 256. Therefore
721 * scsi_inquiry() will convert an inq_len (which is passed in as
722 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
723 * to 0. Evidently, very few devices meet the spec in that
724 * regard. Some devices, like many Seagate disks, take the 0 as
725 * 0, and don't return any data. One Pioneer DVD-R drive
726 * returns more data than the command asked for.
728 * So, since there are numerous devices that just don't work
729 * right with the full inquiry size, we don't send the full size.
731 * - The second reason not to use the full inquiry data length is
732 * that we don't need it here. The only reason we issue a
733 * standard inquiry is to get the vendor name, device name,
734 * and revision so scsi_print_inquiry() can print them.
736 * If, at some point in the future, more inquiry data is needed for
737 * some reason, this code should use a procedure similar to the
738 * probe code. i.e., issue a short inquiry, and determine from
739 * the additional length passed back from the device how much
740 * inquiry data the device supports. Once the amount the device
741 * supports is determined, issue an inquiry for that amount and no
746 scsi_inquiry(&ccb->csio,
747 /* retries */ retry_count,
749 /* tag_action */ MSG_SIMPLE_Q_TAG,
750 /* inq_buf */ (u_int8_t *)inq_buf,
751 /* inq_len */ SHORT_INQUIRY_LENGTH,
754 /* sense_len */ SSD_FULL_SIZE,
755 /* timeout */ timeout ? timeout : 5000);
757 /* Disable freezing the device queue */
758 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
760 if (arglist & CAM_ARG_ERR_RECOVER)
761 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
763 if (cam_send_ccb(device, ccb) < 0) {
764 perror("error sending SCSI inquiry");
766 if (arglist & CAM_ARG_VERBOSE) {
767 cam_error_print(device, ccb, CAM_ESF_ALL,
768 CAM_EPF_ALL, stderr);
775 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
778 if (arglist & CAM_ARG_VERBOSE) {
779 cam_error_print(device, ccb, CAM_ESF_ALL,
780 CAM_EPF_ALL, stderr);
791 fprintf(stdout, "%s%d: ", device->device_name,
792 device->dev_unit_num);
793 scsi_print_inquiry(inq_buf);
801 scsiserial(struct cam_device *device, int retry_count, int timeout)
804 struct scsi_vpd_unit_serial_number *serial_buf;
805 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
808 ccb = cam_getccb(device);
811 warnx("couldn't allocate CCB");
815 /* cam_getccb cleans up the header, caller has to zero the payload */
816 bzero(&(&ccb->ccb_h)[1],
817 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
819 serial_buf = (struct scsi_vpd_unit_serial_number *)
820 malloc(sizeof(*serial_buf));
822 if (serial_buf == NULL) {
824 warnx("can't malloc memory for serial number");
828 scsi_inquiry(&ccb->csio,
829 /*retries*/ retry_count,
831 /* tag_action */ MSG_SIMPLE_Q_TAG,
832 /* inq_buf */ (u_int8_t *)serial_buf,
833 /* inq_len */ sizeof(*serial_buf),
835 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
836 /* sense_len */ SSD_FULL_SIZE,
837 /* timeout */ timeout ? timeout : 5000);
839 /* Disable freezing the device queue */
840 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
842 if (arglist & CAM_ARG_ERR_RECOVER)
843 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
845 if (cam_send_ccb(device, ccb) < 0) {
846 warn("error getting serial number");
848 if (arglist & CAM_ARG_VERBOSE) {
849 cam_error_print(device, ccb, CAM_ESF_ALL,
850 CAM_EPF_ALL, stderr);
858 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
861 if (arglist & CAM_ARG_VERBOSE) {
862 cam_error_print(device, ccb, CAM_ESF_ALL,
863 CAM_EPF_ALL, stderr);
874 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
875 serial_num[serial_buf->length] = '\0';
877 if ((arglist & CAM_ARG_GET_STDINQ)
878 || (arglist & CAM_ARG_GET_XFERRATE))
879 fprintf(stdout, "%s%d: Serial Number ",
880 device->device_name, device->dev_unit_num);
882 fprintf(stdout, "%.60s\n", serial_num);
890 camxferrate(struct cam_device *device)
892 struct ccb_pathinq cpi;
899 if ((retval = get_cpi(device, &cpi)) != 0)
902 ccb = cam_getccb(device);
905 warnx("couldn't allocate CCB");
909 bzero(&(&ccb->ccb_h)[1],
910 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
912 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
913 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
915 if (((retval = cam_send_ccb(device, ccb)) < 0)
916 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
917 const char error_string[] = "error getting transfer settings";
924 if (arglist & CAM_ARG_VERBOSE)
925 cam_error_print(device, ccb, CAM_ESF_ALL,
926 CAM_EPF_ALL, stderr);
930 goto xferrate_bailout;
934 speed = cpi.base_transfer_speed;
936 if (ccb->cts.transport == XPORT_SPI) {
937 struct ccb_trans_settings_spi *spi =
938 &ccb->cts.xport_specific.spi;
940 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
941 freq = scsi_calc_syncsrate(spi->sync_period);
944 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
945 speed *= (0x01 << spi->bus_width);
947 } else if (ccb->cts.transport == XPORT_FC) {
948 struct ccb_trans_settings_fc *fc =
949 &ccb->cts.xport_specific.fc;
951 if (fc->valid & CTS_FC_VALID_SPEED)
953 } else if (ccb->cts.transport == XPORT_SAS) {
954 struct ccb_trans_settings_sas *sas =
955 &ccb->cts.xport_specific.sas;
957 if (sas->valid & CTS_SAS_VALID_SPEED)
958 speed = sas->bitrate;
959 } else if (ccb->cts.transport == XPORT_ATA) {
960 struct ccb_trans_settings_ata *ata =
961 &ccb->cts.xport_specific.ata;
963 if (ata->valid & CTS_ATA_VALID_MODE)
964 speed = ata_mode2speed(ata->mode);
965 } else if (ccb->cts.transport == XPORT_SATA) {
966 struct ccb_trans_settings_sata *sata =
967 &ccb->cts.xport_specific.sata;
969 if (sata->valid & CTS_SATA_VALID_REVISION)
970 speed = ata_revision2speed(sata->revision);
975 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
976 device->device_name, device->dev_unit_num,
979 fprintf(stdout, "%s%d: %dKB/s transfers",
980 device->device_name, device->dev_unit_num,
984 if (ccb->cts.transport == XPORT_SPI) {
985 struct ccb_trans_settings_spi *spi =
986 &ccb->cts.xport_specific.spi;
988 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
989 && (spi->sync_offset != 0))
990 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
991 freq % 1000, spi->sync_offset);
993 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
994 && (spi->bus_width > 0)) {
995 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
996 && (spi->sync_offset != 0)) {
997 fprintf(stdout, ", ");
999 fprintf(stdout, " (");
1001 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1002 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1003 && (spi->sync_offset != 0)) {
1004 fprintf(stdout, ")");
1006 } else if (ccb->cts.transport == XPORT_ATA) {
1007 struct ccb_trans_settings_ata *ata =
1008 &ccb->cts.xport_specific.ata;
1011 if (ata->valid & CTS_ATA_VALID_MODE)
1012 printf("%s, ", ata_mode2string(ata->mode));
1013 if ((ata->valid & CTS_ATA_VALID_ATAPI) && ata->atapi != 0)
1014 printf("ATAPI %dbytes, ", ata->atapi);
1015 if (ata->valid & CTS_ATA_VALID_BYTECOUNT)
1016 printf("PIO %dbytes", ata->bytecount);
1018 } else if (ccb->cts.transport == XPORT_SATA) {
1019 struct ccb_trans_settings_sata *sata =
1020 &ccb->cts.xport_specific.sata;
1023 if (sata->valid & CTS_SATA_VALID_REVISION)
1024 printf("SATA %d.x, ", sata->revision);
1027 if (sata->valid & CTS_SATA_VALID_MODE)
1028 printf("%s, ", ata_mode2string(sata->mode));
1029 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1030 printf("ATAPI %dbytes, ", sata->atapi);
1031 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1032 printf("PIO %dbytes", sata->bytecount);
1036 if (ccb->cts.protocol == PROTO_SCSI) {
1037 struct ccb_trans_settings_scsi *scsi =
1038 &ccb->cts.proto_specific.scsi;
1039 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1040 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1041 fprintf(stdout, ", Command Queueing Enabled");
1046 fprintf(stdout, "\n");
1056 atacapprint(struct ata_params *parm)
1058 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1059 ((u_int32_t)parm->lba_size_2 << 16);
1061 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1062 ((u_int64_t)parm->lba_size48_2 << 16) |
1063 ((u_int64_t)parm->lba_size48_3 << 32) |
1064 ((u_int64_t)parm->lba_size48_4 << 48);
1067 printf("protocol ");
1068 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1069 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1070 if (parm->satacapabilities & ATA_SATA_GEN3)
1071 printf(" SATA 3.x\n");
1072 else if (parm->satacapabilities & ATA_SATA_GEN2)
1073 printf(" SATA 2.x\n");
1074 else if (parm->satacapabilities & ATA_SATA_GEN1)
1075 printf(" SATA 1.x\n");
1081 printf("device model %.40s\n", parm->model);
1082 printf("firmware revision %.8s\n", parm->revision);
1083 printf("serial number %.20s\n", parm->serial);
1084 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1085 printf("WWN %02x%02x%02x%02x\n",
1086 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1088 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1089 printf("media serial number %.30s\n",
1090 parm->media_serial);
1093 printf("cylinders %d\n", parm->cylinders);
1094 printf("heads %d\n", parm->heads);
1095 printf("sectors/track %d\n", parm->sectors);
1096 printf("sector size logical %u, physical %lu, offset %lu\n",
1097 ata_logical_sector_size(parm),
1098 (unsigned long)ata_physical_sector_size(parm),
1099 (unsigned long)ata_logical_sector_offset(parm));
1101 if (parm->config == ATA_PROTO_CFA ||
1102 (parm->support.command2 & ATA_SUPPORT_CFA))
1103 printf("CFA supported\n");
1105 printf("LBA%ssupported ",
1106 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1108 printf("%d sectors\n", lbasize);
1112 printf("LBA48%ssupported ",
1113 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1115 printf("%ju sectors\n", (uintmax_t)lbasize48);
1119 printf("PIO supported PIO");
1120 switch (ata_max_pmode(parm)) {
1136 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1137 printf(" w/o IORDY");
1140 printf("DMA%ssupported ",
1141 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1142 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1143 if (parm->mwdmamodes & 0xff) {
1145 if (parm->mwdmamodes & 0x04)
1147 else if (parm->mwdmamodes & 0x02)
1149 else if (parm->mwdmamodes & 0x01)
1153 if ((parm->atavalid & ATA_FLAG_88) &&
1154 (parm->udmamodes & 0xff)) {
1156 if (parm->udmamodes & 0x40)
1158 else if (parm->udmamodes & 0x20)
1160 else if (parm->udmamodes & 0x10)
1162 else if (parm->udmamodes & 0x08)
1164 else if (parm->udmamodes & 0x04)
1166 else if (parm->udmamodes & 0x02)
1168 else if (parm->udmamodes & 0x01)
1175 if (parm->media_rotation_rate == 1) {
1176 printf("media RPM non-rotating\n");
1177 } else if (parm->media_rotation_rate >= 0x0401 &&
1178 parm->media_rotation_rate <= 0xFFFE) {
1179 printf("media RPM %d\n",
1180 parm->media_rotation_rate);
1184 "Support Enabled Value Vendor\n");
1185 printf("read ahead %s %s\n",
1186 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1187 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1188 printf("write cache %s %s\n",
1189 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1190 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1191 printf("flush cache %s %s\n",
1192 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1193 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1194 printf("overlap %s\n",
1195 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1196 printf("Tagged Command Queuing (TCQ) %s %s",
1197 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1198 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1199 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1200 printf(" %d tags\n",
1201 ATA_QUEUE_LEN(parm->queue) + 1);
1204 printf("Native Command Queuing (NCQ) ");
1205 if (parm->satacapabilities != 0xffff &&
1206 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1207 printf("yes %d tags\n",
1208 ATA_QUEUE_LEN(parm->queue) + 1);
1211 printf("SMART %s %s\n",
1212 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1213 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1214 printf("microcode download %s %s\n",
1215 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1216 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1217 printf("security %s %s\n",
1218 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1219 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1220 printf("power management %s %s\n",
1221 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1222 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1223 printf("advanced power management %s %s",
1224 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1225 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1226 if (parm->support.command2 & ATA_SUPPORT_APM) {
1227 printf(" %d/0x%02X\n",
1228 parm->apm_value, parm->apm_value);
1231 printf("automatic acoustic management %s %s",
1232 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1233 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1234 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1235 printf(" %d/0x%02X %d/0x%02X\n",
1236 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1237 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1238 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1239 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1242 printf("media status notification %s %s\n",
1243 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1244 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1245 printf("power-up in Standby %s %s\n",
1246 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1247 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1248 printf("write-read-verify %s %s",
1249 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1250 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1251 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1252 printf(" %d/0x%x\n",
1253 parm->wrv_mode, parm->wrv_mode);
1256 printf("unload %s %s\n",
1257 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1258 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1259 printf("free-fall %s %s\n",
1260 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1261 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1262 printf("data set management (TRIM) %s\n",
1263 parm->support_dsm & ATA_SUPPORT_DSM_TRIM ? "yes" : "no");
1267 ataidentify(struct cam_device *device, int retry_count, int timeout)
1270 struct ata_params *ident_buf;
1271 struct ccb_getdev cgd;
1275 if (get_cgd(device, &cgd) != 0) {
1276 warnx("couldn't get CGD");
1279 ccb = cam_getccb(device);
1282 warnx("couldn't allocate CCB");
1286 /* cam_getccb cleans up the header, caller has to zero the payload */
1287 bzero(&(&ccb->ccb_h)[1],
1288 sizeof(struct ccb_ataio) - sizeof(struct ccb_hdr));
1290 ptr = (uint16_t *)malloc(sizeof(struct ata_params));
1294 warnx("can't malloc memory for identify\n");
1297 bzero(ptr, sizeof(struct ata_params));
1299 cam_fill_ataio(&ccb->ataio,
1302 /*flags*/CAM_DIR_IN,
1304 /*data_ptr*/(u_int8_t *)ptr,
1305 /*dxfer_len*/sizeof(struct ata_params),
1306 timeout ? timeout : 30 * 1000);
1307 if (cgd.protocol == PROTO_ATA)
1308 ata_28bit_cmd(&ccb->ataio, ATA_ATA_IDENTIFY, 0, 0, 0);
1310 ata_28bit_cmd(&ccb->ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0);
1312 /* Disable freezing the device queue */
1313 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1315 if (arglist & CAM_ARG_ERR_RECOVER)
1316 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1318 if (cam_send_ccb(device, ccb) < 0) {
1319 perror("error sending ATA identify");
1321 if (arglist & CAM_ARG_VERBOSE) {
1322 cam_error_print(device, ccb, CAM_ESF_ALL,
1323 CAM_EPF_ALL, stderr);
1331 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1334 if (arglist & CAM_ARG_VERBOSE) {
1335 cam_error_print(device, ccb, CAM_ESF_ALL,
1336 CAM_EPF_ALL, stderr);
1347 for (i = 0; i < sizeof(struct ata_params) / 2; i++)
1348 ptr[i] = le16toh(ptr[i]);
1349 if (arglist & CAM_ARG_VERBOSE) {
1350 fprintf(stdout, "%s%d: Raw identify data:\n",
1351 device->device_name, device->dev_unit_num);
1352 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
1354 fprintf(stdout, " %3d: ", i);
1355 fprintf(stdout, "%04x ", (uint16_t)ptr[i]);
1357 fprintf(stdout, "\n");
1360 ident_buf = (struct ata_params *)ptr;
1361 if (strncmp(ident_buf->model, "FX", 2) &&
1362 strncmp(ident_buf->model, "NEC", 3) &&
1363 strncmp(ident_buf->model, "Pioneer", 7) &&
1364 strncmp(ident_buf->model, "SHARP", 5)) {
1365 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
1366 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
1367 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
1368 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
1370 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
1371 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
1372 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
1373 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
1374 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
1375 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
1376 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
1377 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
1378 sizeof(ident_buf->media_serial));
1380 fprintf(stdout, "%s%d: ", device->device_name,
1381 device->dev_unit_num);
1382 ata_print_ident(ident_buf);
1383 camxferrate(device);
1384 atacapprint(ident_buf);
1390 #endif /* MINIMALISTIC */
1393 * Parse out a bus, or a bus, target and lun in the following
1399 * Returns the number of parsed components, or 0.
1402 parse_btl(char *tstr, int *bus, int *target, int *lun, cam_argmask *arglst)
1407 while (isspace(*tstr) && (*tstr != '\0'))
1410 tmpstr = (char *)strtok(tstr, ":");
1411 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
1412 *bus = strtol(tmpstr, NULL, 0);
1413 *arglst |= CAM_ARG_BUS;
1415 tmpstr = (char *)strtok(NULL, ":");
1416 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
1417 *target = strtol(tmpstr, NULL, 0);
1418 *arglst |= CAM_ARG_TARGET;
1420 tmpstr = (char *)strtok(NULL, ":");
1421 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
1422 *lun = strtol(tmpstr, NULL, 0);
1423 *arglst |= CAM_ARG_LUN;
1433 dorescan_or_reset(int argc, char **argv, int rescan)
1435 static const char must[] =
1436 "you must specify \"all\", a bus, or a bus:target:lun to %s";
1438 int bus = -1, target = -1, lun = -1;
1442 warnx(must, rescan? "rescan" : "reset");
1446 tstr = argv[optind];
1447 while (isspace(*tstr) && (*tstr != '\0'))
1449 if (strncasecmp(tstr, "all", strlen("all")) == 0)
1450 arglist |= CAM_ARG_BUS;
1452 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
1453 if (rv != 1 && rv != 3) {
1454 warnx(must, rescan? "rescan" : "reset");
1459 if ((arglist & CAM_ARG_BUS)
1460 && (arglist & CAM_ARG_TARGET)
1461 && (arglist & CAM_ARG_LUN))
1462 error = scanlun_or_reset_dev(bus, target, lun, rescan);
1464 error = rescan_or_reset_bus(bus, rescan);
1470 rescan_or_reset_bus(int bus, int rescan)
1472 union ccb ccb, matchccb;
1478 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
1479 warnx("error opening transport layer device %s", XPT_DEVICE);
1480 warn("%s", XPT_DEVICE);
1485 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
1486 ccb.ccb_h.path_id = bus;
1487 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
1488 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
1489 ccb.crcn.flags = CAM_FLAG_NONE;
1491 /* run this at a low priority */
1492 ccb.ccb_h.pinfo.priority = 5;
1494 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
1495 warn("CAMIOCOMMAND ioctl failed");
1500 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
1501 fprintf(stdout, "%s of bus %d was successful\n",
1502 rescan ? "Re-scan" : "Reset", bus);
1504 fprintf(stdout, "%s of bus %d returned error %#x\n",
1505 rescan ? "Re-scan" : "Reset", bus,
1506 ccb.ccb_h.status & CAM_STATUS_MASK);
1517 * The right way to handle this is to modify the xpt so that it can
1518 * handle a wildcarded bus in a rescan or reset CCB. At the moment
1519 * that isn't implemented, so instead we enumerate the busses and
1520 * send the rescan or reset to those busses in the case where the
1521 * given bus is -1 (wildcard). We don't send a rescan or reset
1522 * to the xpt bus; sending a rescan to the xpt bus is effectively a
1523 * no-op, sending a rescan to the xpt bus would result in a status of
1526 bzero(&(&matchccb.ccb_h)[1],
1527 sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr));
1528 matchccb.ccb_h.func_code = XPT_DEV_MATCH;
1529 bufsize = sizeof(struct dev_match_result) * 20;
1530 matchccb.cdm.match_buf_len = bufsize;
1531 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
1532 if (matchccb.cdm.matches == NULL) {
1533 warnx("can't malloc memory for matches");
1537 matchccb.cdm.num_matches = 0;
1539 matchccb.cdm.num_patterns = 1;
1540 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
1542 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
1543 matchccb.cdm.pattern_buf_len);
1544 if (matchccb.cdm.patterns == NULL) {
1545 warnx("can't malloc memory for patterns");
1549 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
1550 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
1555 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
1556 warn("CAMIOCOMMAND ioctl failed");
1561 if ((matchccb.ccb_h.status != CAM_REQ_CMP)
1562 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
1563 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
1564 warnx("got CAM error %#x, CDM error %d\n",
1565 matchccb.ccb_h.status, matchccb.cdm.status);
1570 for (i = 0; i < matchccb.cdm.num_matches; i++) {
1571 struct bus_match_result *bus_result;
1573 /* This shouldn't happen. */
1574 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
1577 bus_result = &matchccb.cdm.matches[i].result.bus_result;
1580 * We don't want to rescan or reset the xpt bus.
1583 if ((int)bus_result->path_id == -1)
1586 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
1588 ccb.ccb_h.path_id = bus_result->path_id;
1589 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
1590 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
1591 ccb.crcn.flags = CAM_FLAG_NONE;
1593 /* run this at a low priority */
1594 ccb.ccb_h.pinfo.priority = 5;
1596 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
1597 warn("CAMIOCOMMAND ioctl failed");
1602 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
1603 fprintf(stdout, "%s of bus %d was successful\n",
1604 rescan? "Re-scan" : "Reset",
1605 bus_result->path_id);
1608 * Don't bail out just yet, maybe the other
1609 * rescan or reset commands will complete
1612 fprintf(stderr, "%s of bus %d returned error "
1613 "%#x\n", rescan? "Re-scan" : "Reset",
1614 bus_result->path_id,
1615 ccb.ccb_h.status & CAM_STATUS_MASK);
1619 } while ((matchccb.ccb_h.status == CAM_REQ_CMP)
1620 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
1627 if (matchccb.cdm.patterns != NULL)
1628 free(matchccb.cdm.patterns);
1629 if (matchccb.cdm.matches != NULL)
1630 free(matchccb.cdm.matches);
1636 scanlun_or_reset_dev(int bus, int target, int lun, int scan)
1639 struct cam_device *device;
1645 warnx("invalid bus number %d", bus);
1650 warnx("invalid target number %d", target);
1655 warnx("invalid lun number %d", lun);
1661 bzero(&ccb, sizeof(union ccb));
1664 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
1665 warnx("error opening transport layer device %s\n",
1667 warn("%s", XPT_DEVICE);
1671 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
1672 if (device == NULL) {
1673 warnx("%s", cam_errbuf);
1678 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
1679 ccb.ccb_h.path_id = bus;
1680 ccb.ccb_h.target_id = target;
1681 ccb.ccb_h.target_lun = lun;
1682 ccb.ccb_h.timeout = 5000;
1683 ccb.crcn.flags = CAM_FLAG_NONE;
1685 /* run this at a low priority */
1686 ccb.ccb_h.pinfo.priority = 5;
1689 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
1690 warn("CAMIOCOMMAND ioctl failed");
1695 if (cam_send_ccb(device, &ccb) < 0) {
1696 warn("error sending XPT_RESET_DEV CCB");
1697 cam_close_device(device);
1705 cam_close_device(device);
1708 * An error code of CAM_BDR_SENT is normal for a BDR request.
1710 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
1712 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
1713 fprintf(stdout, "%s of %d:%d:%d was successful\n",
1714 scan? "Re-scan" : "Reset", bus, target, lun);
1717 fprintf(stdout, "%s of %d:%d:%d returned error %#x\n",
1718 scan? "Re-scan" : "Reset", bus, target, lun,
1719 ccb.ccb_h.status & CAM_STATUS_MASK);
1724 #ifndef MINIMALISTIC
1726 readdefects(struct cam_device *device, int argc, char **argv,
1727 char *combinedopt, int retry_count, int timeout)
1729 union ccb *ccb = NULL;
1730 struct scsi_read_defect_data_10 *rdd_cdb;
1731 u_int8_t *defect_list = NULL;
1732 u_int32_t dlist_length = 65000;
1733 u_int32_t returned_length = 0;
1734 u_int32_t num_returned = 0;
1735 u_int8_t returned_format;
1738 int lists_specified = 0;
1740 while ((c = getopt(argc, argv, combinedopt)) != -1) {
1746 while (isspace(*tstr) && (*tstr != '\0'))
1748 if (strcmp(tstr, "block") == 0)
1749 arglist |= CAM_ARG_FORMAT_BLOCK;
1750 else if (strcmp(tstr, "bfi") == 0)
1751 arglist |= CAM_ARG_FORMAT_BFI;
1752 else if (strcmp(tstr, "phys") == 0)
1753 arglist |= CAM_ARG_FORMAT_PHYS;
1756 warnx("invalid defect format %s", tstr);
1757 goto defect_bailout;
1762 arglist |= CAM_ARG_GLIST;
1765 arglist |= CAM_ARG_PLIST;
1772 ccb = cam_getccb(device);
1775 * Hopefully 65000 bytes is enough to hold the defect list. If it
1776 * isn't, the disk is probably dead already. We'd have to go with
1777 * 12 byte command (i.e. alloc_length is 32 bits instead of 16)
1780 defect_list = malloc(dlist_length);
1781 if (defect_list == NULL) {
1782 warnx("can't malloc memory for defect list");
1784 goto defect_bailout;
1787 rdd_cdb =(struct scsi_read_defect_data_10 *)&ccb->csio.cdb_io.cdb_bytes;
1790 * cam_getccb() zeros the CCB header only. So we need to zero the
1791 * payload portion of the ccb.
1793 bzero(&(&ccb->ccb_h)[1],
1794 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1796 cam_fill_csio(&ccb->csio,
1797 /*retries*/ retry_count,
1799 /*flags*/ CAM_DIR_IN | ((arglist & CAM_ARG_ERR_RECOVER) ?
1800 CAM_PASS_ERR_RECOVER : 0),
1801 /*tag_action*/ MSG_SIMPLE_Q_TAG,
1802 /*data_ptr*/ defect_list,
1803 /*dxfer_len*/ dlist_length,
1804 /*sense_len*/ SSD_FULL_SIZE,
1805 /*cdb_len*/ sizeof(struct scsi_read_defect_data_10),
1806 /*timeout*/ timeout ? timeout : 5000);
1808 rdd_cdb->opcode = READ_DEFECT_DATA_10;
1809 if (arglist & CAM_ARG_FORMAT_BLOCK)
1810 rdd_cdb->format = SRDD10_BLOCK_FORMAT;
1811 else if (arglist & CAM_ARG_FORMAT_BFI)
1812 rdd_cdb->format = SRDD10_BYTES_FROM_INDEX_FORMAT;
1813 else if (arglist & CAM_ARG_FORMAT_PHYS)
1814 rdd_cdb->format = SRDD10_PHYSICAL_SECTOR_FORMAT;
1817 warnx("no defect list format specified");
1818 goto defect_bailout;
1820 if (arglist & CAM_ARG_PLIST) {
1821 rdd_cdb->format |= SRDD10_PLIST;
1825 if (arglist & CAM_ARG_GLIST) {
1826 rdd_cdb->format |= SRDD10_GLIST;
1830 scsi_ulto2b(dlist_length, rdd_cdb->alloc_length);
1832 /* Disable freezing the device queue */
1833 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1835 if (cam_send_ccb(device, ccb) < 0) {
1836 perror("error reading defect list");
1838 if (arglist & CAM_ARG_VERBOSE) {
1839 cam_error_print(device, ccb, CAM_ESF_ALL,
1840 CAM_EPF_ALL, stderr);
1844 goto defect_bailout;
1847 returned_length = scsi_2btoul(((struct
1848 scsi_read_defect_data_hdr_10 *)defect_list)->length);
1850 returned_format = ((struct scsi_read_defect_data_hdr_10 *)
1851 defect_list)->format;
1853 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
1854 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
1855 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
1856 struct scsi_sense_data *sense;
1857 int error_code, sense_key, asc, ascq;
1859 sense = &ccb->csio.sense_data;
1860 scsi_extract_sense(sense, &error_code, &sense_key, &asc, &ascq);
1863 * According to the SCSI spec, if the disk doesn't support
1864 * the requested format, it will generally return a sense
1865 * key of RECOVERED ERROR, and an additional sense code
1866 * of "DEFECT LIST NOT FOUND". So, we check for that, and
1867 * also check to make sure that the returned length is
1868 * greater than 0, and then print out whatever format the
1871 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
1872 && (asc == 0x1c) && (ascq == 0x00)
1873 && (returned_length > 0)) {
1874 warnx("requested defect format not available");
1875 switch(returned_format & SRDDH10_DLIST_FORMAT_MASK) {
1876 case SRDD10_BLOCK_FORMAT:
1877 warnx("Device returned block format");
1879 case SRDD10_BYTES_FROM_INDEX_FORMAT:
1880 warnx("Device returned bytes from index"
1883 case SRDD10_PHYSICAL_SECTOR_FORMAT:
1884 warnx("Device returned physical sector format");
1888 warnx("Device returned unknown defect"
1889 " data format %#x", returned_format);
1890 goto defect_bailout;
1891 break; /* NOTREACHED */
1895 warnx("Error returned from read defect data command");
1896 if (arglist & CAM_ARG_VERBOSE)
1897 cam_error_print(device, ccb, CAM_ESF_ALL,
1898 CAM_EPF_ALL, stderr);
1899 goto defect_bailout;
1901 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1903 warnx("Error returned from read defect data command");
1904 if (arglist & CAM_ARG_VERBOSE)
1905 cam_error_print(device, ccb, CAM_ESF_ALL,
1906 CAM_EPF_ALL, stderr);
1907 goto defect_bailout;
1911 * XXX KDM I should probably clean up the printout format for the
1914 switch (returned_format & SRDDH10_DLIST_FORMAT_MASK){
1915 case SRDDH10_PHYSICAL_SECTOR_FORMAT:
1917 struct scsi_defect_desc_phys_sector *dlist;
1919 dlist = (struct scsi_defect_desc_phys_sector *)
1921 sizeof(struct scsi_read_defect_data_hdr_10));
1923 num_returned = returned_length /
1924 sizeof(struct scsi_defect_desc_phys_sector);
1926 fprintf(stderr, "Got %d defect", num_returned);
1928 if ((lists_specified == 0) || (num_returned == 0)) {
1929 fprintf(stderr, "s.\n");
1931 } else if (num_returned == 1)
1932 fprintf(stderr, ":\n");
1934 fprintf(stderr, "s:\n");
1936 for (i = 0; i < num_returned; i++) {
1937 fprintf(stdout, "%d:%d:%d\n",
1938 scsi_3btoul(dlist[i].cylinder),
1940 scsi_4btoul(dlist[i].sector));
1944 case SRDDH10_BYTES_FROM_INDEX_FORMAT:
1946 struct scsi_defect_desc_bytes_from_index *dlist;
1948 dlist = (struct scsi_defect_desc_bytes_from_index *)
1950 sizeof(struct scsi_read_defect_data_hdr_10));
1952 num_returned = returned_length /
1953 sizeof(struct scsi_defect_desc_bytes_from_index);
1955 fprintf(stderr, "Got %d defect", num_returned);
1957 if ((lists_specified == 0) || (num_returned == 0)) {
1958 fprintf(stderr, "s.\n");
1960 } else if (num_returned == 1)
1961 fprintf(stderr, ":\n");
1963 fprintf(stderr, "s:\n");
1965 for (i = 0; i < num_returned; i++) {
1966 fprintf(stdout, "%d:%d:%d\n",
1967 scsi_3btoul(dlist[i].cylinder),
1969 scsi_4btoul(dlist[i].bytes_from_index));
1973 case SRDDH10_BLOCK_FORMAT:
1975 struct scsi_defect_desc_block *dlist;
1977 dlist = (struct scsi_defect_desc_block *)(defect_list +
1978 sizeof(struct scsi_read_defect_data_hdr_10));
1980 num_returned = returned_length /
1981 sizeof(struct scsi_defect_desc_block);
1983 fprintf(stderr, "Got %d defect", num_returned);
1985 if ((lists_specified == 0) || (num_returned == 0)) {
1986 fprintf(stderr, "s.\n");
1988 } else if (num_returned == 1)
1989 fprintf(stderr, ":\n");
1991 fprintf(stderr, "s:\n");
1993 for (i = 0; i < num_returned; i++)
1994 fprintf(stdout, "%u\n",
1995 scsi_4btoul(dlist[i].address));
1999 fprintf(stderr, "Unknown defect format %d\n",
2000 returned_format & SRDDH10_DLIST_FORMAT_MASK);
2006 if (defect_list != NULL)
2014 #endif /* MINIMALISTIC */
2018 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
2022 ccb = cam_getccb(device);
2028 #ifndef MINIMALISTIC
2030 mode_sense(struct cam_device *device, int mode_page, int page_control,
2031 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
2036 ccb = cam_getccb(device);
2039 errx(1, "mode_sense: couldn't allocate CCB");
2041 bzero(&(&ccb->ccb_h)[1],
2042 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
2044 scsi_mode_sense(&ccb->csio,
2045 /* retries */ retry_count,
2047 /* tag_action */ MSG_SIMPLE_Q_TAG,
2049 /* page_code */ page_control << 6,
2050 /* page */ mode_page,
2051 /* param_buf */ data,
2052 /* param_len */ datalen,
2053 /* sense_len */ SSD_FULL_SIZE,
2054 /* timeout */ timeout ? timeout : 5000);
2056 if (arglist & CAM_ARG_ERR_RECOVER)
2057 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
2059 /* Disable freezing the device queue */
2060 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
2062 if (((retval = cam_send_ccb(device, ccb)) < 0)
2063 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
2064 if (arglist & CAM_ARG_VERBOSE) {
2065 cam_error_print(device, ccb, CAM_ESF_ALL,
2066 CAM_EPF_ALL, stderr);
2069 cam_close_device(device);
2071 err(1, "error sending mode sense command");
2073 errx(1, "error sending mode sense command");
2080 mode_select(struct cam_device *device, int save_pages, int retry_count,
2081 int timeout, u_int8_t *data, int datalen)
2086 ccb = cam_getccb(device);
2089 errx(1, "mode_select: couldn't allocate CCB");
2091 bzero(&(&ccb->ccb_h)[1],
2092 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
2094 scsi_mode_select(&ccb->csio,
2095 /* retries */ retry_count,
2097 /* tag_action */ MSG_SIMPLE_Q_TAG,
2098 /* scsi_page_fmt */ 1,
2099 /* save_pages */ save_pages,
2100 /* param_buf */ data,
2101 /* param_len */ datalen,
2102 /* sense_len */ SSD_FULL_SIZE,
2103 /* timeout */ timeout ? timeout : 5000);
2105 if (arglist & CAM_ARG_ERR_RECOVER)
2106 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
2108 /* Disable freezing the device queue */
2109 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
2111 if (((retval = cam_send_ccb(device, ccb)) < 0)
2112 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
2113 if (arglist & CAM_ARG_VERBOSE) {
2114 cam_error_print(device, ccb, CAM_ESF_ALL,
2115 CAM_EPF_ALL, stderr);
2118 cam_close_device(device);
2121 err(1, "error sending mode select command");
2123 errx(1, "error sending mode select command");
2131 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
2132 int retry_count, int timeout)
2134 int c, mode_page = -1, page_control = 0;
2135 int binary = 0, list = 0;
2137 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2143 arglist |= CAM_ARG_DBD;
2146 arglist |= CAM_ARG_MODE_EDIT;
2152 mode_page = strtol(optarg, NULL, 0);
2154 errx(1, "invalid mode page %d", mode_page);
2157 page_control = strtol(optarg, NULL, 0);
2158 if ((page_control < 0) || (page_control > 3))
2159 errx(1, "invalid page control field %d",
2161 arglist |= CAM_ARG_PAGE_CNTL;
2168 if (mode_page == -1 && list == 0)
2169 errx(1, "you must specify a mode page!");
2172 mode_list(device, page_control, arglist & CAM_ARG_DBD,
2173 retry_count, timeout);
2175 mode_edit(device, mode_page, page_control,
2176 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
2177 retry_count, timeout);
2182 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
2183 int retry_count, int timeout)
2186 u_int32_t flags = CAM_DIR_NONE;
2187 u_int8_t *data_ptr = NULL;
2189 u_int8_t atacmd[12];
2190 struct get_hook hook;
2191 int c, data_bytes = 0;
2197 char *datastr = NULL, *tstr, *resstr = NULL;
2199 int fd_data = 0, fd_res = 0;
2202 ccb = cam_getccb(device);
2205 warnx("scsicmd: error allocating ccb");
2209 bzero(&(&ccb->ccb_h)[1],
2210 sizeof(union ccb) - sizeof(struct ccb_hdr));
2212 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2216 while (isspace(*tstr) && (*tstr != '\0'))
2218 hook.argc = argc - optind;
2219 hook.argv = argv + optind;
2221 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
2224 * Increment optind by the number of arguments the
2225 * encoding routine processed. After each call to
2226 * getopt(3), optind points to the argument that
2227 * getopt should process _next_. In this case,
2228 * that means it points to the first command string
2229 * argument, if there is one. Once we increment
2230 * this, it should point to either the next command
2231 * line argument, or it should be past the end of
2238 while (isspace(*tstr) && (*tstr != '\0'))
2240 hook.argc = argc - optind;
2241 hook.argv = argv + optind;
2243 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
2246 * Increment optind by the number of arguments the
2247 * encoding routine processed. After each call to
2248 * getopt(3), optind points to the argument that
2249 * getopt should process _next_. In this case,
2250 * that means it points to the first command string
2251 * argument, if there is one. Once we increment
2252 * this, it should point to either the next command
2253 * line argument, or it should be past the end of
2265 if (arglist & CAM_ARG_CMD_OUT) {
2266 warnx("command must either be "
2267 "read or write, not both");
2269 goto scsicmd_bailout;
2271 arglist |= CAM_ARG_CMD_IN;
2273 data_bytes = strtol(optarg, NULL, 0);
2274 if (data_bytes <= 0) {
2275 warnx("invalid number of input bytes %d",
2278 goto scsicmd_bailout;
2280 hook.argc = argc - optind;
2281 hook.argv = argv + optind;
2284 datastr = cget(&hook, NULL);
2286 * If the user supplied "-" instead of a format, he
2287 * wants the data to be written to stdout.
2289 if ((datastr != NULL)
2290 && (datastr[0] == '-'))
2293 data_ptr = (u_int8_t *)malloc(data_bytes);
2294 if (data_ptr == NULL) {
2295 warnx("can't malloc memory for data_ptr");
2297 goto scsicmd_bailout;
2301 if (arglist & CAM_ARG_CMD_IN) {
2302 warnx("command must either be "
2303 "read or write, not both");
2305 goto scsicmd_bailout;
2307 arglist |= CAM_ARG_CMD_OUT;
2308 flags = CAM_DIR_OUT;
2309 data_bytes = strtol(optarg, NULL, 0);
2310 if (data_bytes <= 0) {
2311 warnx("invalid number of output bytes %d",
2314 goto scsicmd_bailout;
2316 hook.argc = argc - optind;
2317 hook.argv = argv + optind;
2319 datastr = cget(&hook, NULL);
2320 data_ptr = (u_int8_t *)malloc(data_bytes);
2321 if (data_ptr == NULL) {
2322 warnx("can't malloc memory for data_ptr");
2324 goto scsicmd_bailout;
2326 bzero(data_ptr, data_bytes);
2328 * If the user supplied "-" instead of a format, he
2329 * wants the data to be read from stdin.
2331 if ((datastr != NULL)
2332 && (datastr[0] == '-'))
2335 buff_encode_visit(data_ptr, data_bytes, datastr,
2341 hook.argc = argc - optind;
2342 hook.argv = argv + optind;
2344 resstr = cget(&hook, NULL);
2345 if ((resstr != NULL) && (resstr[0] == '-'))
2355 * If fd_data is set, and we're writing to the device, we need to
2356 * read the data the user wants written from stdin.
2358 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
2360 int amt_to_read = data_bytes;
2361 u_int8_t *buf_ptr = data_ptr;
2363 for (amt_read = 0; amt_to_read > 0;
2364 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
2365 if (amt_read == -1) {
2366 warn("error reading data from stdin");
2368 goto scsicmd_bailout;
2370 amt_to_read -= amt_read;
2371 buf_ptr += amt_read;
2375 if (arglist & CAM_ARG_ERR_RECOVER)
2376 flags |= CAM_PASS_ERR_RECOVER;
2378 /* Disable freezing the device queue */
2379 flags |= CAM_DEV_QFRZDIS;
2383 * This is taken from the SCSI-3 draft spec.
2384 * (T10/1157D revision 0.3)
2385 * The top 3 bits of an opcode are the group code.
2386 * The next 5 bits are the command code.
2387 * Group 0: six byte commands
2388 * Group 1: ten byte commands
2389 * Group 2: ten byte commands
2391 * Group 4: sixteen byte commands
2392 * Group 5: twelve byte commands
2393 * Group 6: vendor specific
2394 * Group 7: vendor specific
2396 switch((cdb[0] >> 5) & 0x7) {
2407 /* computed by buff_encode_visit */
2418 * We should probably use csio_build_visit or something like that
2419 * here, but it's easier to encode arguments as you go. The
2420 * alternative would be skipping the CDB argument and then encoding
2421 * it here, since we've got the data buffer argument by now.
2423 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
2425 cam_fill_csio(&ccb->csio,
2426 /*retries*/ retry_count,
2429 /*tag_action*/ MSG_SIMPLE_Q_TAG,
2430 /*data_ptr*/ data_ptr,
2431 /*dxfer_len*/ data_bytes,
2432 /*sense_len*/ SSD_FULL_SIZE,
2433 /*cdb_len*/ cdb_len,
2434 /*timeout*/ timeout ? timeout : 5000);
2437 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
2439 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
2441 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
2443 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
2445 cam_fill_ataio(&ccb->ataio,
2446 /*retries*/ retry_count,
2450 /*data_ptr*/ data_ptr,
2451 /*dxfer_len*/ data_bytes,
2452 /*timeout*/ timeout ? timeout : 5000);
2455 if (((retval = cam_send_ccb(device, ccb)) < 0)
2456 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
2458 warn("error sending command");
2460 warnx("error sending command");
2462 if (arglist & CAM_ARG_VERBOSE) {
2463 cam_error_print(device, ccb, CAM_ESF_ALL,
2464 CAM_EPF_ALL, stderr);
2468 goto scsicmd_bailout;
2471 if (atacmd_len && need_res) {
2473 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
2475 fprintf(stdout, "\n");
2478 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
2479 ccb->ataio.res.status,
2480 ccb->ataio.res.error,
2481 ccb->ataio.res.lba_low,
2482 ccb->ataio.res.lba_mid,
2483 ccb->ataio.res.lba_high,
2484 ccb->ataio.res.device,
2485 ccb->ataio.res.lba_low_exp,
2486 ccb->ataio.res.lba_mid_exp,
2487 ccb->ataio.res.lba_high_exp,
2488 ccb->ataio.res.sector_count,
2489 ccb->ataio.res.sector_count_exp);
2494 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
2495 && (arglist & CAM_ARG_CMD_IN)
2496 && (data_bytes > 0)) {
2498 buff_decode_visit(data_ptr, data_bytes, datastr,
2500 fprintf(stdout, "\n");
2502 ssize_t amt_written;
2503 int amt_to_write = data_bytes;
2504 u_int8_t *buf_ptr = data_ptr;
2506 for (amt_written = 0; (amt_to_write > 0) &&
2507 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
2508 amt_to_write -= amt_written;
2509 buf_ptr += amt_written;
2511 if (amt_written == -1) {
2512 warn("error writing data to stdout");
2514 goto scsicmd_bailout;
2515 } else if ((amt_written == 0)
2516 && (amt_to_write > 0)) {
2517 warnx("only wrote %u bytes out of %u",
2518 data_bytes - amt_to_write, data_bytes);
2525 if ((data_bytes > 0) && (data_ptr != NULL))
2534 camdebug(int argc, char **argv, char *combinedopt)
2537 int bus = -1, target = -1, lun = -1;
2538 char *tstr, *tmpstr = NULL;
2542 bzero(&ccb, sizeof(union ccb));
2544 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2547 arglist |= CAM_ARG_DEBUG_INFO;
2548 ccb.cdbg.flags |= CAM_DEBUG_INFO;
2551 arglist |= CAM_ARG_DEBUG_PERIPH;
2552 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
2555 arglist |= CAM_ARG_DEBUG_SUBTRACE;
2556 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
2559 arglist |= CAM_ARG_DEBUG_TRACE;
2560 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
2563 arglist |= CAM_ARG_DEBUG_XPT;
2564 ccb.cdbg.flags |= CAM_DEBUG_XPT;
2567 arglist |= CAM_ARG_DEBUG_CDB;
2568 ccb.cdbg.flags |= CAM_DEBUG_CDB;
2575 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
2576 warnx("error opening transport layer device %s", XPT_DEVICE);
2577 warn("%s", XPT_DEVICE);
2584 warnx("you must specify \"off\", \"all\" or a bus,");
2585 warnx("bus:target, or bus:target:lun");
2592 while (isspace(*tstr) && (*tstr != '\0'))
2595 if (strncmp(tstr, "off", 3) == 0) {
2596 ccb.cdbg.flags = CAM_DEBUG_NONE;
2597 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
2598 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
2600 } else if (strncmp(tstr, "all", 3) != 0) {
2601 tmpstr = (char *)strtok(tstr, ":");
2602 if ((tmpstr != NULL) && (*tmpstr != '\0')){
2603 bus = strtol(tmpstr, NULL, 0);
2604 arglist |= CAM_ARG_BUS;
2605 tmpstr = (char *)strtok(NULL, ":");
2606 if ((tmpstr != NULL) && (*tmpstr != '\0')){
2607 target = strtol(tmpstr, NULL, 0);
2608 arglist |= CAM_ARG_TARGET;
2609 tmpstr = (char *)strtok(NULL, ":");
2610 if ((tmpstr != NULL) && (*tmpstr != '\0')){
2611 lun = strtol(tmpstr, NULL, 0);
2612 arglist |= CAM_ARG_LUN;
2617 warnx("you must specify \"all\", \"off\", or a bus,");
2618 warnx("bus:target, or bus:target:lun to debug");
2624 ccb.ccb_h.func_code = XPT_DEBUG;
2625 ccb.ccb_h.path_id = bus;
2626 ccb.ccb_h.target_id = target;
2627 ccb.ccb_h.target_lun = lun;
2629 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
2630 warn("CAMIOCOMMAND ioctl failed");
2635 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
2636 CAM_FUNC_NOTAVAIL) {
2637 warnx("CAM debugging not available");
2638 warnx("you need to put options CAMDEBUG in"
2639 " your kernel config file!");
2641 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
2643 warnx("XPT_DEBUG CCB failed with status %#x",
2647 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
2649 "Debugging turned off\n");
2652 "Debugging enabled for "
2665 tagcontrol(struct cam_device *device, int argc, char **argv,
2675 ccb = cam_getccb(device);
2678 warnx("tagcontrol: error allocating ccb");
2682 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2685 numtags = strtol(optarg, NULL, 0);
2687 warnx("tag count %d is < 0", numtags);
2689 goto tagcontrol_bailout;
2700 cam_path_string(device, pathstr, sizeof(pathstr));
2703 bzero(&(&ccb->ccb_h)[1],
2704 sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
2705 ccb->ccb_h.func_code = XPT_REL_SIMQ;
2706 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
2707 ccb->crs.openings = numtags;
2710 if (cam_send_ccb(device, ccb) < 0) {
2711 perror("error sending XPT_REL_SIMQ CCB");
2713 goto tagcontrol_bailout;
2716 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2717 warnx("XPT_REL_SIMQ CCB failed");
2718 cam_error_print(device, ccb, CAM_ESF_ALL,
2719 CAM_EPF_ALL, stderr);
2721 goto tagcontrol_bailout;
2726 fprintf(stdout, "%stagged openings now %d\n",
2727 pathstr, ccb->crs.openings);
2730 bzero(&(&ccb->ccb_h)[1],
2731 sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr));
2733 ccb->ccb_h.func_code = XPT_GDEV_STATS;
2735 if (cam_send_ccb(device, ccb) < 0) {
2736 perror("error sending XPT_GDEV_STATS CCB");
2738 goto tagcontrol_bailout;
2741 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2742 warnx("XPT_GDEV_STATS CCB failed");
2743 cam_error_print(device, ccb, CAM_ESF_ALL,
2744 CAM_EPF_ALL, stderr);
2746 goto tagcontrol_bailout;
2749 if (arglist & CAM_ARG_VERBOSE) {
2750 fprintf(stdout, "%s", pathstr);
2751 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
2752 fprintf(stdout, "%s", pathstr);
2753 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
2754 fprintf(stdout, "%s", pathstr);
2755 fprintf(stdout, "devq_openings %d\n", ccb->cgds.devq_openings);
2756 fprintf(stdout, "%s", pathstr);
2757 fprintf(stdout, "devq_queued %d\n", ccb->cgds.devq_queued);
2758 fprintf(stdout, "%s", pathstr);
2759 fprintf(stdout, "held %d\n", ccb->cgds.held);
2760 fprintf(stdout, "%s", pathstr);
2761 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
2762 fprintf(stdout, "%s", pathstr);
2763 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
2766 fprintf(stdout, "%s", pathstr);
2767 fprintf(stdout, "device openings: ");
2769 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
2770 ccb->cgds.dev_active);
2780 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
2784 cam_path_string(device, pathstr, sizeof(pathstr));
2786 if (cts->transport == XPORT_SPI) {
2787 struct ccb_trans_settings_spi *spi =
2788 &cts->xport_specific.spi;
2790 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
2792 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
2795 if (spi->sync_offset != 0) {
2798 freq = scsi_calc_syncsrate(spi->sync_period);
2799 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
2800 pathstr, freq / 1000, freq % 1000);
2804 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
2805 fprintf(stdout, "%soffset: %d\n", pathstr,
2809 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
2810 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
2811 (0x01 << spi->bus_width) * 8);
2814 if (spi->valid & CTS_SPI_VALID_DISC) {
2815 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
2816 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
2817 "enabled" : "disabled");
2820 if (cts->transport == XPORT_ATA) {
2821 struct ccb_trans_settings_ata *ata =
2822 &cts->xport_specific.ata;
2824 if ((ata->valid & CTS_ATA_VALID_MODE) != 0) {
2825 fprintf(stdout, "%sATA mode: %s\n", pathstr,
2826 ata_mode2string(ata->mode));
2828 if ((ata->valid & CTS_ATA_VALID_ATAPI) != 0) {
2829 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
2832 if ((ata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
2833 fprintf(stdout, "%sPIO transaction length: %d\n",
2834 pathstr, ata->bytecount);
2837 if (cts->transport == XPORT_SATA) {
2838 struct ccb_trans_settings_sata *sata =
2839 &cts->xport_specific.sata;
2841 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
2842 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
2845 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
2846 fprintf(stdout, "%sATA mode: %s\n", pathstr,
2847 ata_mode2string(sata->mode));
2849 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
2850 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
2853 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
2854 fprintf(stdout, "%sPIO transaction length: %d\n",
2855 pathstr, sata->bytecount);
2857 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
2858 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
2861 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
2862 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
2865 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
2866 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
2870 if (cts->protocol == PROTO_SCSI) {
2871 struct ccb_trans_settings_scsi *scsi=
2872 &cts->proto_specific.scsi;
2874 if (scsi->valid & CTS_SCSI_VALID_TQ) {
2875 fprintf(stdout, "%stagged queueing is %s\n", pathstr,
2876 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
2877 "enabled" : "disabled");
2884 * Get a path inquiry CCB for the specified device.
2887 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
2892 ccb = cam_getccb(device);
2894 warnx("get_cpi: couldn't allocate CCB");
2897 bzero(&(&ccb->ccb_h)[1],
2898 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
2899 ccb->ccb_h.func_code = XPT_PATH_INQ;
2900 if (cam_send_ccb(device, ccb) < 0) {
2901 warn("get_cpi: error sending Path Inquiry CCB");
2902 if (arglist & CAM_ARG_VERBOSE)
2903 cam_error_print(device, ccb, CAM_ESF_ALL,
2904 CAM_EPF_ALL, stderr);
2906 goto get_cpi_bailout;
2908 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2909 if (arglist & CAM_ARG_VERBOSE)
2910 cam_error_print(device, ccb, CAM_ESF_ALL,
2911 CAM_EPF_ALL, stderr);
2913 goto get_cpi_bailout;
2915 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
2923 * Get a get device CCB for the specified device.
2926 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
2931 ccb = cam_getccb(device);
2933 warnx("get_cgd: couldn't allocate CCB");
2936 bzero(&(&ccb->ccb_h)[1],
2937 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
2938 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
2939 if (cam_send_ccb(device, ccb) < 0) {
2940 warn("get_cgd: error sending Path Inquiry CCB");
2941 if (arglist & CAM_ARG_VERBOSE)
2942 cam_error_print(device, ccb, CAM_ESF_ALL,
2943 CAM_EPF_ALL, stderr);
2945 goto get_cgd_bailout;
2947 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2948 if (arglist & CAM_ARG_VERBOSE)
2949 cam_error_print(device, ccb, CAM_ESF_ALL,
2950 CAM_EPF_ALL, stderr);
2952 goto get_cgd_bailout;
2954 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
2962 cpi_print(struct ccb_pathinq *cpi)
2964 char adapter_str[1024];
2967 snprintf(adapter_str, sizeof(adapter_str),
2968 "%s%d:", cpi->dev_name, cpi->unit_number);
2970 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
2973 for (i = 1; i < 0xff; i = i << 1) {
2976 if ((i & cpi->hba_inquiry) == 0)
2979 fprintf(stdout, "%s supports ", adapter_str);
2983 str = "MDP message";
2986 str = "32 bit wide SCSI";
2989 str = "16 bit wide SCSI";
2992 str = "SDTR message";
2995 str = "linked CDBs";
2998 str = "tag queue messages";
3001 str = "soft reset alternative";
3004 str = "SATA Port Multiplier";
3007 str = "unknown PI bit set";
3010 fprintf(stdout, "%s\n", str);
3013 for (i = 1; i < 0xff; i = i << 1) {
3016 if ((i & cpi->hba_misc) == 0)
3019 fprintf(stdout, "%s ", adapter_str);
3023 str = "bus scans from high ID to low ID";
3026 str = "removable devices not included in scan";
3028 case PIM_NOINITIATOR:
3029 str = "initiator role not supported";
3031 case PIM_NOBUSRESET:
3032 str = "user has disabled initial BUS RESET or"
3033 " controller is in target/mixed mode";
3036 str = "do not send 6-byte commands";
3039 str = "scan bus sequentially";
3042 str = "unknown PIM bit set";
3045 fprintf(stdout, "%s\n", str);
3048 for (i = 1; i < 0xff; i = i << 1) {
3051 if ((i & cpi->target_sprt) == 0)
3054 fprintf(stdout, "%s supports ", adapter_str);
3057 str = "target mode processor mode";
3060 str = "target mode phase cog. mode";
3062 case PIT_DISCONNECT:
3063 str = "disconnects in target mode";
3066 str = "terminate I/O message in target mode";
3069 str = "group 6 commands in target mode";
3072 str = "group 7 commands in target mode";
3075 str = "unknown PIT bit set";
3079 fprintf(stdout, "%s\n", str);
3081 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
3083 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
3085 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
3087 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
3088 adapter_str, cpi->hpath_id);
3089 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
3091 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
3092 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
3093 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
3094 adapter_str, cpi->hba_vendor);
3095 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
3096 adapter_str, cpi->hba_device);
3097 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
3098 adapter_str, cpi->hba_subvendor);
3099 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
3100 adapter_str, cpi->hba_subdevice);
3101 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
3102 fprintf(stdout, "%s base transfer speed: ", adapter_str);
3103 if (cpi->base_transfer_speed > 1000)
3104 fprintf(stdout, "%d.%03dMB/sec\n",
3105 cpi->base_transfer_speed / 1000,
3106 cpi->base_transfer_speed % 1000);
3108 fprintf(stdout, "%dKB/sec\n",
3109 (cpi->base_transfer_speed % 1000) * 1000);
3110 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
3111 adapter_str, cpi->maxio);
3115 get_print_cts(struct cam_device *device, int user_settings, int quiet,
3116 struct ccb_trans_settings *cts)
3122 ccb = cam_getccb(device);
3125 warnx("get_print_cts: error allocating ccb");
3129 bzero(&(&ccb->ccb_h)[1],
3130 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
3132 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
3134 if (user_settings == 0)
3135 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
3137 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
3139 if (cam_send_ccb(device, ccb) < 0) {
3140 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
3141 if (arglist & CAM_ARG_VERBOSE)
3142 cam_error_print(device, ccb, CAM_ESF_ALL,
3143 CAM_EPF_ALL, stderr);
3145 goto get_print_cts_bailout;
3148 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3149 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
3150 if (arglist & CAM_ARG_VERBOSE)
3151 cam_error_print(device, ccb, CAM_ESF_ALL,
3152 CAM_EPF_ALL, stderr);
3154 goto get_print_cts_bailout;
3158 cts_print(device, &ccb->cts);
3161 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
3163 get_print_cts_bailout:
3171 ratecontrol(struct cam_device *device, int retry_count, int timeout,
3172 int argc, char **argv, char *combinedopt)
3176 int user_settings = 0;
3178 int disc_enable = -1, tag_enable = -1;
3181 double syncrate = -1;
3184 int change_settings = 0, send_tur = 0;
3185 struct ccb_pathinq cpi;
3187 ccb = cam_getccb(device);
3189 warnx("ratecontrol: error allocating ccb");
3192 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3201 if (strncasecmp(optarg, "enable", 6) == 0)
3203 else if (strncasecmp(optarg, "disable", 7) == 0)
3206 warnx("-D argument \"%s\" is unknown", optarg);
3208 goto ratecontrol_bailout;
3210 change_settings = 1;
3213 mode = ata_string2mode(optarg);
3215 warnx("unknown mode '%s'", optarg);
3217 goto ratecontrol_bailout;
3219 change_settings = 1;
3222 offset = strtol(optarg, NULL, 0);
3224 warnx("offset value %d is < 0", offset);
3226 goto ratecontrol_bailout;
3228 change_settings = 1;
3234 syncrate = atof(optarg);
3236 warnx("sync rate %f is < 0", syncrate);
3238 goto ratecontrol_bailout;
3240 change_settings = 1;
3243 if (strncasecmp(optarg, "enable", 6) == 0)
3245 else if (strncasecmp(optarg, "disable", 7) == 0)
3248 warnx("-T argument \"%s\" is unknown", optarg);
3250 goto ratecontrol_bailout;
3252 change_settings = 1;
3258 bus_width = strtol(optarg, NULL, 0);
3259 if (bus_width < 0) {
3260 warnx("bus width %d is < 0", bus_width);
3262 goto ratecontrol_bailout;
3264 change_settings = 1;
3270 bzero(&(&ccb->ccb_h)[1],
3271 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
3273 * Grab path inquiry information, so we can determine whether
3274 * or not the initiator is capable of the things that the user
3277 ccb->ccb_h.func_code = XPT_PATH_INQ;
3278 if (cam_send_ccb(device, ccb) < 0) {
3279 perror("error sending XPT_PATH_INQ CCB");
3280 if (arglist & CAM_ARG_VERBOSE) {
3281 cam_error_print(device, ccb, CAM_ESF_ALL,
3282 CAM_EPF_ALL, stderr);
3285 goto ratecontrol_bailout;
3287 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3288 warnx("XPT_PATH_INQ CCB failed");
3289 if (arglist & CAM_ARG_VERBOSE) {
3290 cam_error_print(device, ccb, CAM_ESF_ALL,
3291 CAM_EPF_ALL, stderr);
3294 goto ratecontrol_bailout;
3296 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
3297 bzero(&(&ccb->ccb_h)[1],
3298 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
3300 fprintf(stdout, "%s parameters:\n",
3301 user_settings ? "User" : "Current");
3303 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
3305 goto ratecontrol_bailout;
3307 if (arglist & CAM_ARG_VERBOSE)
3310 if (change_settings) {
3311 int didsettings = 0;
3312 struct ccb_trans_settings_spi *spi = NULL;
3313 struct ccb_trans_settings_ata *ata = NULL;
3314 struct ccb_trans_settings_sata *sata = NULL;
3315 struct ccb_trans_settings_scsi *scsi = NULL;
3317 if (ccb->cts.transport == XPORT_SPI)
3318 spi = &ccb->cts.xport_specific.spi;
3319 if (ccb->cts.transport == XPORT_ATA)
3320 ata = &ccb->cts.xport_specific.ata;
3321 if (ccb->cts.transport == XPORT_SATA)
3322 sata = &ccb->cts.xport_specific.sata;
3323 if (ccb->cts.protocol == PROTO_SCSI)
3324 scsi = &ccb->cts.proto_specific.scsi;
3325 ccb->cts.xport_specific.valid = 0;
3326 ccb->cts.proto_specific.valid = 0;
3327 if (spi && disc_enable != -1) {
3328 spi->valid |= CTS_SPI_VALID_DISC;
3329 if (disc_enable == 0)
3330 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
3332 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
3334 if (scsi && tag_enable != -1) {
3335 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
3336 warnx("HBA does not support tagged queueing, "
3337 "so you cannot modify tag settings");
3339 goto ratecontrol_bailout;
3341 scsi->valid |= CTS_SCSI_VALID_TQ;
3342 if (tag_enable == 0)
3343 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
3345 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
3348 if (spi && offset != -1) {
3349 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3350 warnx("HBA is not capable of changing offset");
3352 goto ratecontrol_bailout;
3354 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
3355 spi->sync_offset = offset;
3358 if (spi && syncrate != -1) {
3359 int prelim_sync_period;
3362 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3363 warnx("HBA is not capable of changing "
3366 goto ratecontrol_bailout;
3368 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
3370 * The sync rate the user gives us is in MHz.
3371 * We need to translate it into KHz for this
3376 * Next, we calculate a "preliminary" sync period
3377 * in tenths of a nanosecond.
3380 prelim_sync_period = 0;
3382 prelim_sync_period = 10000000 / syncrate;
3384 scsi_calc_syncparam(prelim_sync_period);
3385 freq = scsi_calc_syncsrate(spi->sync_period);
3388 if (sata && syncrate != -1) {
3389 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3390 warnx("HBA is not capable of changing "
3393 goto ratecontrol_bailout;
3395 sata->revision = ata_speed2revision(syncrate * 100);
3396 if (sata->revision < 0) {
3397 warnx("Invalid rate %f", syncrate);
3399 goto ratecontrol_bailout;
3401 sata->valid |= CTS_SATA_VALID_REVISION;
3404 if ((ata || sata) && mode != -1) {
3405 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3406 warnx("HBA is not capable of changing "
3409 goto ratecontrol_bailout;
3413 ata->valid |= CTS_ATA_VALID_MODE;
3416 sata->valid |= CTS_SATA_VALID_MODE;
3421 * The bus_width argument goes like this:
3425 * Therefore, if you shift the number of bits given on the
3426 * command line right by 4, you should get the correct
3429 if (spi && bus_width != -1) {
3431 * We might as well validate things here with a
3432 * decipherable error message, rather than what
3433 * will probably be an indecipherable error message
3434 * by the time it gets back to us.
3436 if ((bus_width == 16)
3437 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
3438 warnx("HBA does not support 16 bit bus width");
3440 goto ratecontrol_bailout;
3441 } else if ((bus_width == 32)
3442 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
3443 warnx("HBA does not support 32 bit bus width");
3445 goto ratecontrol_bailout;
3446 } else if ((bus_width != 8)
3447 && (bus_width != 16)
3448 && (bus_width != 32)) {
3449 warnx("Invalid bus width %d", bus_width);
3451 goto ratecontrol_bailout;
3453 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
3454 spi->bus_width = bus_width >> 4;
3457 if (didsettings == 0) {
3458 goto ratecontrol_bailout;
3460 if (!user_settings && (ata || sata)) {
3461 warnx("You can modify only user settings for ATA/SATA");
3463 goto ratecontrol_bailout;
3465 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
3466 if (cam_send_ccb(device, ccb) < 0) {
3467 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
3468 if (arglist & CAM_ARG_VERBOSE) {
3469 cam_error_print(device, ccb, CAM_ESF_ALL,
3470 CAM_EPF_ALL, stderr);
3473 goto ratecontrol_bailout;
3475 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3476 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
3477 if (arglist & CAM_ARG_VERBOSE) {
3478 cam_error_print(device, ccb, CAM_ESF_ALL,
3479 CAM_EPF_ALL, stderr);
3482 goto ratecontrol_bailout;
3486 retval = testunitready(device, retry_count, timeout,
3487 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
3489 * If the TUR didn't succeed, just bail.
3493 fprintf(stderr, "Test Unit Ready failed\n");
3494 goto ratecontrol_bailout;
3497 * If the user wants things quiet, there's no sense in
3498 * getting the transfer settings, if we're not going
3502 goto ratecontrol_bailout;
3503 fprintf(stdout, "New parameters:\n");
3504 retval = get_print_cts(device, user_settings, 0, NULL);
3507 ratecontrol_bailout:
3513 scsiformat(struct cam_device *device, int argc, char **argv,
3514 char *combinedopt, int retry_count, int timeout)
3518 int ycount = 0, quiet = 0;
3519 int error = 0, response = 0, retval = 0;
3520 int use_timeout = 10800 * 1000;
3522 struct format_defect_list_header fh;
3523 u_int8_t *data_ptr = NULL;
3524 u_int32_t dxfer_len = 0;
3526 int num_warnings = 0;
3529 ccb = cam_getccb(device);
3532 warnx("scsiformat: error allocating ccb");
3536 bzero(&(&ccb->ccb_h)[1],
3537 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3539 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3560 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
3561 "following device:\n");
3563 error = scsidoinquiry(device, argc, argv, combinedopt,
3564 retry_count, timeout);
3567 warnx("scsiformat: error sending inquiry");
3568 goto scsiformat_bailout;
3577 fprintf(stdout, "Are you SURE you want to do "
3580 if (fgets(str, sizeof(str), stdin) != NULL) {
3582 if (strncasecmp(str, "yes", 3) == 0)
3584 else if (strncasecmp(str, "no", 2) == 0)
3587 fprintf(stdout, "Please answer"
3588 " \"yes\" or \"no\"\n");
3591 } while (response == 0);
3593 if (response == -1) {
3595 goto scsiformat_bailout;
3600 use_timeout = timeout;
3603 fprintf(stdout, "Current format timeout is %d seconds\n",
3604 use_timeout / 1000);
3608 * If the user hasn't disabled questions and didn't specify a
3609 * timeout on the command line, ask them if they want the current
3613 && (timeout == 0)) {
3615 int new_timeout = 0;
3617 fprintf(stdout, "Enter new timeout in seconds or press\n"
3618 "return to keep the current timeout [%d] ",
3619 use_timeout / 1000);
3621 if (fgets(str, sizeof(str), stdin) != NULL) {
3623 new_timeout = atoi(str);
3626 if (new_timeout != 0) {
3627 use_timeout = new_timeout * 1000;
3628 fprintf(stdout, "Using new timeout value %d\n",
3629 use_timeout / 1000);
3634 * Keep this outside the if block below to silence any unused
3635 * variable warnings.
3637 bzero(&fh, sizeof(fh));
3640 * If we're in immediate mode, we've got to include the format
3643 if (immediate != 0) {
3644 fh.byte2 = FU_DLH_IMMED;
3645 data_ptr = (u_int8_t *)&fh;
3646 dxfer_len = sizeof(fh);
3647 byte2 = FU_FMT_DATA;
3648 } else if (quiet == 0) {
3649 fprintf(stdout, "Formatting...");
3653 scsi_format_unit(&ccb->csio,
3654 /* retries */ retry_count,
3656 /* tag_action */ MSG_SIMPLE_Q_TAG,
3659 /* data_ptr */ data_ptr,
3660 /* dxfer_len */ dxfer_len,
3661 /* sense_len */ SSD_FULL_SIZE,
3662 /* timeout */ use_timeout);
3664 /* Disable freezing the device queue */
3665 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3667 if (arglist & CAM_ARG_ERR_RECOVER)
3668 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3670 if (((retval = cam_send_ccb(device, ccb)) < 0)
3671 || ((immediate == 0)
3672 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
3673 const char errstr[] = "error sending format command";
3680 if (arglist & CAM_ARG_VERBOSE) {
3681 cam_error_print(device, ccb, CAM_ESF_ALL,
3682 CAM_EPF_ALL, stderr);
3685 goto scsiformat_bailout;
3689 * If we ran in non-immediate mode, we already checked for errors
3690 * above and printed out any necessary information. If we're in
3691 * immediate mode, we need to loop through and get status
3692 * information periodically.
3694 if (immediate == 0) {
3696 fprintf(stdout, "Format Complete\n");
3698 goto scsiformat_bailout;
3705 bzero(&(&ccb->ccb_h)[1],
3706 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3709 * There's really no need to do error recovery or
3710 * retries here, since we're just going to sit in a
3711 * loop and wait for the device to finish formatting.
3713 scsi_test_unit_ready(&ccb->csio,
3716 /* tag_action */ MSG_SIMPLE_Q_TAG,
3717 /* sense_len */ SSD_FULL_SIZE,
3718 /* timeout */ 5000);
3720 /* Disable freezing the device queue */
3721 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3723 retval = cam_send_ccb(device, ccb);
3726 * If we get an error from the ioctl, bail out. SCSI
3727 * errors are expected.
3730 warn("error sending CAMIOCOMMAND ioctl");
3731 if (arglist & CAM_ARG_VERBOSE) {
3732 cam_error_print(device, ccb, CAM_ESF_ALL,
3733 CAM_EPF_ALL, stderr);
3736 goto scsiformat_bailout;
3739 status = ccb->ccb_h.status & CAM_STATUS_MASK;
3741 if ((status != CAM_REQ_CMP)
3742 && (status == CAM_SCSI_STATUS_ERROR)
3743 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3744 struct scsi_sense_data *sense;
3745 int error_code, sense_key, asc, ascq;
3747 sense = &ccb->csio.sense_data;
3748 scsi_extract_sense(sense, &error_code, &sense_key,
3752 * According to the SCSI-2 and SCSI-3 specs, a
3753 * drive that is in the middle of a format should
3754 * return NOT READY with an ASC of "logical unit
3755 * not ready, format in progress". The sense key
3756 * specific bytes will then be a progress indicator.
3758 if ((sense_key == SSD_KEY_NOT_READY)
3759 && (asc == 0x04) && (ascq == 0x04)) {
3760 if ((sense->extra_len >= 10)
3761 && ((sense->sense_key_spec[0] &
3762 SSD_SCS_VALID) != 0)
3765 u_int64_t percentage;
3768 &sense->sense_key_spec[1]);
3769 percentage = 10000 * val;
3772 "\rFormatting: %ju.%02u %% "
3774 (uintmax_t)(percentage /
3776 (unsigned)((percentage /
3780 } else if ((quiet == 0)
3781 && (++num_warnings <= 1)) {
3782 warnx("Unexpected SCSI Sense Key "
3783 "Specific value returned "
3785 scsi_sense_print(device, &ccb->csio,
3787 warnx("Unable to print status "
3788 "information, but format will "
3790 warnx("will exit when format is "
3795 warnx("Unexpected SCSI error during format");
3796 cam_error_print(device, ccb, CAM_ESF_ALL,
3797 CAM_EPF_ALL, stderr);
3799 goto scsiformat_bailout;
3802 } else if (status != CAM_REQ_CMP) {
3803 warnx("Unexpected CAM status %#x", status);
3804 if (arglist & CAM_ARG_VERBOSE)
3805 cam_error_print(device, ccb, CAM_ESF_ALL,
3806 CAM_EPF_ALL, stderr);
3808 goto scsiformat_bailout;
3811 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
3814 fprintf(stdout, "\nFormat Complete\n");
3824 scsireportluns(struct cam_device *device, int argc, char **argv,
3825 char *combinedopt, int retry_count, int timeout)
3828 int c, countonly, lunsonly;
3829 struct scsi_report_luns_data *lundata;
3831 uint8_t report_type;
3832 uint32_t list_len, i, j;
3837 report_type = RPL_REPORT_DEFAULT;
3838 ccb = cam_getccb(device);
3841 warnx("%s: error allocating ccb", __func__);
3845 bzero(&(&ccb->ccb_h)[1],
3846 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3851 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3860 if (strcasecmp(optarg, "default") == 0)
3861 report_type = RPL_REPORT_DEFAULT;
3862 else if (strcasecmp(optarg, "wellknown") == 0)
3863 report_type = RPL_REPORT_WELLKNOWN;
3864 else if (strcasecmp(optarg, "all") == 0)
3865 report_type = RPL_REPORT_ALL;
3867 warnx("%s: invalid report type \"%s\"",
3878 if ((countonly != 0)
3879 && (lunsonly != 0)) {
3880 warnx("%s: you can only specify one of -c or -l", __func__);
3885 * According to SPC-4, the allocation length must be at least 16
3886 * bytes -- enough for the header and one LUN.
3888 alloc_len = sizeof(*lundata) + 8;
3892 lundata = malloc(alloc_len);
3894 if (lundata == NULL) {
3895 warn("%s: error mallocing %d bytes", __func__, alloc_len);
3900 scsi_report_luns(&ccb->csio,
3901 /*retries*/ retry_count,
3903 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3904 /*select_report*/ report_type,
3905 /*rpl_buf*/ lundata,
3906 /*alloc_len*/ alloc_len,
3907 /*sense_len*/ SSD_FULL_SIZE,
3908 /*timeout*/ timeout ? timeout : 5000);
3910 /* Disable freezing the device queue */
3911 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3913 if (arglist & CAM_ARG_ERR_RECOVER)
3914 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3916 if (cam_send_ccb(device, ccb) < 0) {
3917 warn("error sending REPORT LUNS command");
3919 if (arglist & CAM_ARG_VERBOSE)
3920 cam_error_print(device, ccb, CAM_ESF_ALL,
3921 CAM_EPF_ALL, stderr);
3927 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3928 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
3934 list_len = scsi_4btoul(lundata->length);
3937 * If we need to list the LUNs, and our allocation
3938 * length was too short, reallocate and retry.
3940 if ((countonly == 0)
3941 && (list_len > (alloc_len - sizeof(*lundata)))) {
3942 alloc_len = list_len + sizeof(*lundata);
3948 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
3949 ((list_len / 8) > 1) ? "s" : "");
3954 for (i = 0; i < (list_len / 8); i++) {
3958 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
3960 fprintf(stdout, ",");
3961 switch (lundata->luns[i].lundata[j] &
3962 RPL_LUNDATA_ATYP_MASK) {
3963 case RPL_LUNDATA_ATYP_PERIPH:
3964 if ((lundata->luns[i].lundata[j] &
3965 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
3966 fprintf(stdout, "%d:",
3967 lundata->luns[i].lundata[j] &
3968 RPL_LUNDATA_PERIPH_BUS_MASK);
3970 && ((lundata->luns[i].lundata[j+2] &
3971 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
3974 fprintf(stdout, "%d",
3975 lundata->luns[i].lundata[j+1]);
3977 case RPL_LUNDATA_ATYP_FLAT: {
3979 tmplun[0] = lundata->luns[i].lundata[j] &
3980 RPL_LUNDATA_FLAT_LUN_MASK;
3981 tmplun[1] = lundata->luns[i].lundata[j+1];
3983 fprintf(stdout, "%d", scsi_2btoul(tmplun));
3987 case RPL_LUNDATA_ATYP_LUN:
3988 fprintf(stdout, "%d:%d:%d",
3989 (lundata->luns[i].lundata[j+1] &
3990 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
3991 lundata->luns[i].lundata[j] &
3992 RPL_LUNDATA_LUN_TARG_MASK,
3993 lundata->luns[i].lundata[j+1] &
3994 RPL_LUNDATA_LUN_LUN_MASK);
3996 case RPL_LUNDATA_ATYP_EXTLUN: {
3997 int field_len, field_len_code, eam_code;
3999 eam_code = lundata->luns[i].lundata[j] &
4000 RPL_LUNDATA_EXT_EAM_MASK;
4001 field_len_code = (lundata->luns[i].lundata[j] &
4002 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
4003 field_len = field_len_code * 2;
4005 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
4006 && (field_len_code == 0x00)) {
4007 fprintf(stdout, "%d",
4008 lundata->luns[i].lundata[j+1]);
4009 } else if ((eam_code ==
4010 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
4011 && (field_len_code == 0x03)) {
4015 * This format takes up all 8 bytes.
4016 * If we aren't starting at offset 0,
4020 fprintf(stdout, "Invalid "
4023 "specified format", j);
4027 bzero(tmp_lun, sizeof(tmp_lun));
4028 bcopy(&lundata->luns[i].lundata[j+1],
4029 &tmp_lun[1], sizeof(tmp_lun) - 1);
4030 fprintf(stdout, "%#jx",
4031 (intmax_t)scsi_8btou64(tmp_lun));
4034 fprintf(stderr, "Unknown Extended LUN"
4035 "Address method %#x, length "
4036 "code %#x", eam_code,
4043 fprintf(stderr, "Unknown LUN address method "
4044 "%#x\n", lundata->luns[i].lundata[0] &
4045 RPL_LUNDATA_ATYP_MASK);
4049 * For the flat addressing method, there are no
4050 * other levels after it.
4055 fprintf(stdout, "\n");
4068 scsireadcapacity(struct cam_device *device, int argc, char **argv,
4069 char *combinedopt, int retry_count, int timeout)
4072 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
4073 struct scsi_read_capacity_data rcap;
4074 struct scsi_read_capacity_data_long rcaplong;
4088 ccb = cam_getccb(device);
4091 warnx("%s: error allocating ccb", __func__);
4095 bzero(&(&ccb->ccb_h)[1],
4096 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
4098 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4125 if ((blocksizeonly != 0)
4126 && (numblocks != 0)) {
4127 warnx("%s: you can only specify one of -b or -N", __func__);
4132 if ((blocksizeonly != 0)
4133 && (sizeonly != 0)) {
4134 warnx("%s: you can only specify one of -b or -s", __func__);
4141 warnx("%s: you can only specify one of -h/-H or -q", __func__);
4147 && (blocksizeonly != 0)) {
4148 warnx("%s: you can only specify one of -h/-H or -b", __func__);
4153 scsi_read_capacity(&ccb->csio,
4154 /*retries*/ retry_count,
4156 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4159 /*timeout*/ timeout ? timeout : 5000);
4161 /* Disable freezing the device queue */
4162 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4164 if (arglist & CAM_ARG_ERR_RECOVER)
4165 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4167 if (cam_send_ccb(device, ccb) < 0) {
4168 warn("error sending READ CAPACITY command");
4170 if (arglist & CAM_ARG_VERBOSE)
4171 cam_error_print(device, ccb, CAM_ESF_ALL,
4172 CAM_EPF_ALL, stderr);
4178 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4179 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4184 maxsector = scsi_4btoul(rcap.addr);
4185 block_len = scsi_4btoul(rcap.length);
4188 * A last block of 2^32-1 means that the true capacity is over 2TB,
4189 * and we need to issue the long READ CAPACITY to get the real
4190 * capacity. Otherwise, we're all set.
4192 if (maxsector != 0xffffffff)
4195 scsi_read_capacity_16(&ccb->csio,
4196 /*retries*/ retry_count,
4198 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4203 /*sense_len*/ SSD_FULL_SIZE,
4204 /*timeout*/ timeout ? timeout : 5000);
4206 /* Disable freezing the device queue */
4207 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4209 if (arglist & CAM_ARG_ERR_RECOVER)
4210 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4212 if (cam_send_ccb(device, ccb) < 0) {
4213 warn("error sending READ CAPACITY (16) command");
4215 if (arglist & CAM_ARG_VERBOSE)
4216 cam_error_print(device, ccb, CAM_ESF_ALL,
4217 CAM_EPF_ALL, stderr);
4223 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4224 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4229 maxsector = scsi_8btou64(rcaplong.addr);
4230 block_len = scsi_4btoul(rcaplong.length);
4233 if (blocksizeonly == 0) {
4235 * Humanize implies !quiet, and also implies numblocks.
4237 if (humanize != 0) {
4242 tmpbytes = (maxsector + 1) * block_len;
4243 ret = humanize_number(tmpstr, sizeof(tmpstr),
4244 tmpbytes, "", HN_AUTOSCALE,
4247 HN_DIVISOR_1000 : 0));
4249 warnx("%s: humanize_number failed!", __func__);
4253 fprintf(stdout, "Device Size: %s%s", tmpstr,
4254 (sizeonly == 0) ? ", " : "\n");
4255 } else if (numblocks != 0) {
4256 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
4257 "Blocks: " : "", (uintmax_t)maxsector + 1,
4258 (sizeonly == 0) ? ", " : "\n");
4260 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
4261 "Last Block: " : "", (uintmax_t)maxsector,
4262 (sizeonly == 0) ? ", " : "\n");
4266 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
4267 "Block Length: " : "", block_len, (quiet == 0) ?
4276 atapm(struct cam_device *device, int argc, char **argv,
4277 char *combinedopt, int retry_count, int timeout)
4285 ccb = cam_getccb(device);
4288 warnx("%s: error allocating ccb", __func__);
4292 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4301 if (strcmp(argv[1], "idle") == 0) {
4303 cmd = ATA_IDLE_IMMEDIATE;
4306 } else if (strcmp(argv[1], "standby") == 0) {
4308 cmd = ATA_STANDBY_IMMEDIATE;
4310 cmd = ATA_STANDBY_CMD;
4317 else if (t <= (240 * 5))
4319 else if (t <= (11 * 30 * 60))
4320 sc = t / (30 * 60) + 241;
4323 cam_fill_ataio(&ccb->ataio,
4326 /*flags*/CAM_DIR_NONE,
4330 timeout ? timeout : 30 * 1000);
4331 ata_28bit_cmd(&ccb->ataio, cmd, 0, 0, sc);
4333 /* Disable freezing the device queue */
4334 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4336 if (arglist & CAM_ARG_ERR_RECOVER)
4337 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4339 if (cam_send_ccb(device, ccb) < 0) {
4340 warn("error sending command");
4342 if (arglist & CAM_ARG_VERBOSE)
4343 cam_error_print(device, ccb, CAM_ESF_ALL,
4344 CAM_EPF_ALL, stderr);
4350 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4351 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4360 #endif /* MINIMALISTIC */
4365 fprintf(verbose ? stdout : stderr,
4366 "usage: camcontrol <command> [device id][generic args][command args]\n"
4367 " camcontrol devlist [-v]\n"
4368 #ifndef MINIMALISTIC
4369 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
4370 " camcontrol tur [dev_id][generic args]\n"
4371 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
4372 " camcontrol identify [dev_id][generic args] [-v]\n"
4373 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
4374 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
4376 " camcontrol start [dev_id][generic args]\n"
4377 " camcontrol stop [dev_id][generic args]\n"
4378 " camcontrol load [dev_id][generic args]\n"
4379 " camcontrol eject [dev_id][generic args]\n"
4380 #endif /* MINIMALISTIC */
4381 " camcontrol rescan <all | bus[:target:lun]>\n"
4382 " camcontrol reset <all | bus[:target:lun]>\n"
4383 #ifndef MINIMALISTIC
4384 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
4385 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
4386 " [-P pagectl][-e | -b][-d]\n"
4387 " camcontrol cmd [dev_id][generic args]\n"
4388 " <-a cmd [args] | -c cmd [args]>\n"
4389 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
4390 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
4391 " <all|bus[:target[:lun]]|off>\n"
4392 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
4393 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
4394 " [-D <enable|disable>][-M mode][-O offset]\n"
4395 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
4396 " [-U][-W bus_width]\n"
4397 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
4398 " camcontrol idle [dev_id][generic args][-t time]\n"
4399 " camcontrol standby [dev_id][generic args][-t time]\n"
4400 " camcontrol sleep [dev_id][generic args]\n"
4401 #endif /* MINIMALISTIC */
4402 " camcontrol help\n");
4405 #ifndef MINIMALISTIC
4407 "Specify one of the following options:\n"
4408 "devlist list all CAM devices\n"
4409 "periphlist list all CAM peripheral drivers attached to a device\n"
4410 "tur send a test unit ready to the named device\n"
4411 "inquiry send a SCSI inquiry command to the named device\n"
4412 "identify send a ATA identify command to the named device\n"
4413 "reportluns send a SCSI report luns command to the device\n"
4414 "readcap send a SCSI read capacity command to the device\n"
4415 "start send a Start Unit command to the device\n"
4416 "stop send a Stop Unit command to the device\n"
4417 "load send a Start Unit command to the device with the load bit set\n"
4418 "eject send a Stop Unit command to the device with the eject bit set\n"
4419 "rescan rescan all busses, the given bus, or bus:target:lun\n"
4420 "reset reset all busses, the given bus, or bus:target:lun\n"
4421 "defects read the defect list of the specified device\n"
4422 "modepage display or edit (-e) the given mode page\n"
4423 "cmd send the given scsi command, may need -i or -o as well\n"
4424 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
4425 "tags report or set the number of transaction slots for a device\n"
4426 "negotiate report or set device negotiation parameters\n"
4427 "format send the SCSI FORMAT UNIT command to the named device\n"
4428 "idle send the ATA IDLE command to the named device\n"
4429 "standby send the ATA STANDBY command to the named device\n"
4430 "sleep send the ATA SLEEP command to the named device\n"
4431 "help this message\n"
4432 "Device Identifiers:\n"
4433 "bus:target specify the bus and target, lun defaults to 0\n"
4434 "bus:target:lun specify the bus, target and lun\n"
4435 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
4436 "Generic arguments:\n"
4437 "-v be verbose, print out sense information\n"
4438 "-t timeout command timeout in seconds, overrides default timeout\n"
4439 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
4440 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
4441 "-E have the kernel attempt to perform SCSI error recovery\n"
4442 "-C count specify the SCSI command retry count (needs -E to work)\n"
4443 "modepage arguments:\n"
4444 "-l list all available mode pages\n"
4445 "-m page specify the mode page to view or edit\n"
4446 "-e edit the specified mode page\n"
4447 "-b force view to binary mode\n"
4448 "-d disable block descriptors for mode sense\n"
4449 "-P pgctl page control field 0-3\n"
4450 "defects arguments:\n"
4451 "-f format specify defect list format (block, bfi or phys)\n"
4452 "-G get the grown defect list\n"
4453 "-P get the permanant defect list\n"
4454 "inquiry arguments:\n"
4455 "-D get the standard inquiry data\n"
4456 "-S get the serial number\n"
4457 "-R get the transfer rate, etc.\n"
4458 "reportluns arguments:\n"
4459 "-c only report a count of available LUNs\n"
4460 "-l only print out luns, and not a count\n"
4461 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
4462 "readcap arguments\n"
4463 "-b only report the blocksize\n"
4464 "-h human readable device size, base 2\n"
4465 "-H human readable device size, base 10\n"
4466 "-N print the number of blocks instead of last block\n"
4467 "-q quiet, print numbers only\n"
4468 "-s only report the last block/device size\n"
4470 "-c cdb [args] specify the SCSI CDB\n"
4471 "-i len fmt specify input data and input data format\n"
4472 "-o len fmt [args] specify output data and output data fmt\n"
4473 "debug arguments:\n"
4474 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
4475 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
4476 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
4477 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
4479 "-N tags specify the number of tags to use for this device\n"
4480 "-q be quiet, don't report the number of tags\n"
4481 "-v report a number of tag-related parameters\n"
4482 "negotiate arguments:\n"
4483 "-a send a test unit ready after negotiation\n"
4484 "-c report/set current negotiation settings\n"
4485 "-D <arg> \"enable\" or \"disable\" disconnection\n"
4486 "-M mode set ATA mode\n"
4487 "-O offset set command delay offset\n"
4488 "-q be quiet, don't report anything\n"
4489 "-R syncrate synchronization rate in MHz\n"
4490 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
4491 "-U report/set user negotiation settings\n"
4492 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
4493 "-v also print a Path Inquiry CCB for the controller\n"
4494 "format arguments:\n"
4495 "-q be quiet, don't print status messages\n"
4496 "-r run in report only mode\n"
4497 "-w don't send immediate format command\n"
4498 "-y don't ask any questions\n"
4499 "idle/standby arguments:\n"
4500 "-t <arg> number of seconds before respective state.\n");
4501 #endif /* MINIMALISTIC */
4505 main(int argc, char **argv)
4508 char *device = NULL;
4510 struct cam_device *cam_dev = NULL;
4511 int timeout = 0, retry_count = 1;
4512 camcontrol_optret optreturn;
4514 const char *mainopt = "C:En:t:u:v";
4515 const char *subopt = NULL;
4516 char combinedopt[256];
4517 int error = 0, optstart = 2;
4519 #ifndef MINIMALISTIC
4520 int bus, target, lun;
4521 #endif /* MINIMALISTIC */
4523 cmdlist = CAM_CMD_NONE;
4524 arglist = CAM_ARG_NONE;
4532 * Get the base option.
4534 optreturn = getoption(argv[1], &cmdlist, &arglist, &subopt);
4536 if (optreturn == CC_OR_AMBIGUOUS) {
4537 warnx("ambiguous option %s", argv[1]);
4540 } else if (optreturn == CC_OR_NOT_FOUND) {
4541 warnx("option %s not found", argv[1]);
4547 * Ahh, getopt(3) is a pain.
4549 * This is a gross hack. There really aren't many other good
4550 * options (excuse the pun) for parsing options in a situation like
4551 * this. getopt is kinda braindead, so you end up having to run
4552 * through the options twice, and give each invocation of getopt
4553 * the option string for the other invocation.
4555 * You would think that you could just have two groups of options.
4556 * The first group would get parsed by the first invocation of
4557 * getopt, and the second group would get parsed by the second
4558 * invocation of getopt. It doesn't quite work out that way. When
4559 * the first invocation of getopt finishes, it leaves optind pointing
4560 * to the argument _after_ the first argument in the second group.
4561 * So when the second invocation of getopt comes around, it doesn't
4562 * recognize the first argument it gets and then bails out.
4564 * A nice alternative would be to have a flag for getopt that says
4565 * "just keep parsing arguments even when you encounter an unknown
4566 * argument", but there isn't one. So there's no real clean way to
4567 * easily parse two sets of arguments without having one invocation
4568 * of getopt know about the other.
4570 * Without this hack, the first invocation of getopt would work as
4571 * long as the generic arguments are first, but the second invocation
4572 * (in the subfunction) would fail in one of two ways. In the case
4573 * where you don't set optreset, it would fail because optind may be
4574 * pointing to the argument after the one it should be pointing at.
4575 * In the case where you do set optreset, and reset optind, it would
4576 * fail because getopt would run into the first set of options, which
4577 * it doesn't understand.
4579 * All of this would "sort of" work if you could somehow figure out
4580 * whether optind had been incremented one option too far. The
4581 * mechanics of that, however, are more daunting than just giving
4582 * both invocations all of the expect options for either invocation.
4584 * Needless to say, I wouldn't mind if someone invented a better
4585 * (non-GPL!) command line parsing interface than getopt. I
4586 * wouldn't mind if someone added more knobs to getopt to make it
4587 * work better. Who knows, I may talk myself into doing it someday,
4588 * if the standards weenies let me. As it is, it just leads to
4589 * hackery like this and causes people to avoid it in some cases.
4591 * KDM, September 8th, 1998
4594 sprintf(combinedopt, "%s%s", mainopt, subopt);
4596 sprintf(combinedopt, "%s", mainopt);
4599 * For these options we do not parse optional device arguments and
4600 * we do not open a passthrough device.
4602 if ((cmdlist == CAM_CMD_RESCAN)
4603 || (cmdlist == CAM_CMD_RESET)
4604 || (cmdlist == CAM_CMD_DEVTREE)
4605 || (cmdlist == CAM_CMD_USAGE)
4606 || (cmdlist == CAM_CMD_DEBUG))
4609 #ifndef MINIMALISTIC
4611 && (argc > 2 && argv[2][0] != '-')) {
4615 if (isdigit(argv[2][0])) {
4616 /* device specified as bus:target[:lun] */
4617 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
4619 errx(1, "numeric device specification must "
4620 "be either bus:target, or "
4622 /* default to 0 if lun was not specified */
4623 if ((arglist & CAM_ARG_LUN) == 0) {
4625 arglist |= CAM_ARG_LUN;
4629 if (cam_get_device(argv[2], name, sizeof name, &unit)
4631 errx(1, "%s", cam_errbuf);
4632 device = strdup(name);
4633 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
4637 #endif /* MINIMALISTIC */
4639 * Start getopt processing at argv[2/3], since we've already
4640 * accepted argv[1..2] as the command name, and as a possible
4646 * Now we run through the argument list looking for generic
4647 * options, and ignoring options that possibly belong to
4650 while ((c = getopt(argc, argv, combinedopt))!= -1){
4653 retry_count = strtol(optarg, NULL, 0);
4654 if (retry_count < 0)
4655 errx(1, "retry count %d is < 0",
4657 arglist |= CAM_ARG_RETRIES;
4660 arglist |= CAM_ARG_ERR_RECOVER;
4663 arglist |= CAM_ARG_DEVICE;
4665 while (isspace(*tstr) && (*tstr != '\0'))
4667 device = (char *)strdup(tstr);
4670 timeout = strtol(optarg, NULL, 0);
4672 errx(1, "invalid timeout %d", timeout);
4673 /* Convert the timeout from seconds to ms */
4675 arglist |= CAM_ARG_TIMEOUT;
4678 arglist |= CAM_ARG_UNIT;
4679 unit = strtol(optarg, NULL, 0);
4682 arglist |= CAM_ARG_VERBOSE;
4689 #ifndef MINIMALISTIC
4691 * For most commands we'll want to open the passthrough device
4692 * associated with the specified device. In the case of the rescan
4693 * commands, we don't use a passthrough device at all, just the
4694 * transport layer device.
4697 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
4698 && (((arglist & CAM_ARG_DEVICE) == 0)
4699 || ((arglist & CAM_ARG_UNIT) == 0))) {
4700 errx(1, "subcommand \"%s\" requires a valid device "
4701 "identifier", argv[1]);
4704 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
4705 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
4706 cam_open_spec_device(device,unit,O_RDWR,NULL)))
4708 errx(1,"%s", cam_errbuf);
4710 #endif /* MINIMALISTIC */
4713 * Reset optind to 2, and reset getopt, so these routines can parse
4714 * the arguments again.
4720 #ifndef MINIMALISTIC
4721 case CAM_CMD_DEVLIST:
4722 error = getdevlist(cam_dev);
4724 #endif /* MINIMALISTIC */
4725 case CAM_CMD_DEVTREE:
4726 error = getdevtree();
4728 #ifndef MINIMALISTIC
4730 error = testunitready(cam_dev, retry_count, timeout, 0);
4732 case CAM_CMD_INQUIRY:
4733 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
4734 retry_count, timeout);
4736 case CAM_CMD_IDENTIFY:
4737 error = ataidentify(cam_dev, retry_count, timeout);
4739 case CAM_CMD_STARTSTOP:
4740 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
4741 arglist & CAM_ARG_EJECT, retry_count,
4744 #endif /* MINIMALISTIC */
4745 case CAM_CMD_RESCAN:
4746 error = dorescan_or_reset(argc, argv, 1);
4749 error = dorescan_or_reset(argc, argv, 0);
4751 #ifndef MINIMALISTIC
4752 case CAM_CMD_READ_DEFECTS:
4753 error = readdefects(cam_dev, argc, argv, combinedopt,
4754 retry_count, timeout);
4756 case CAM_CMD_MODE_PAGE:
4757 modepage(cam_dev, argc, argv, combinedopt,
4758 retry_count, timeout);
4760 case CAM_CMD_SCSI_CMD:
4761 error = scsicmd(cam_dev, argc, argv, combinedopt,
4762 retry_count, timeout);
4765 error = camdebug(argc, argv, combinedopt);
4768 error = tagcontrol(cam_dev, argc, argv, combinedopt);
4771 error = ratecontrol(cam_dev, retry_count, timeout,
4772 argc, argv, combinedopt);
4774 case CAM_CMD_FORMAT:
4775 error = scsiformat(cam_dev, argc, argv,
4776 combinedopt, retry_count, timeout);
4778 case CAM_CMD_REPORTLUNS:
4779 error = scsireportluns(cam_dev, argc, argv,
4780 combinedopt, retry_count,
4783 case CAM_CMD_READCAP:
4784 error = scsireadcapacity(cam_dev, argc, argv,
4785 combinedopt, retry_count,
4789 case CAM_CMD_STANDBY:
4791 error = atapm(cam_dev, argc, argv,
4792 combinedopt, retry_count,
4795 #endif /* MINIMALISTIC */
4805 if (cam_dev != NULL)
4806 cam_close_device(cam_dev);