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:i: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);
1025 if (sata->valid & CTS_SATA_VALID_MODE)
1026 printf("%s, ", ata_mode2string(sata->mode));
1027 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1028 printf("ATAPI %dbytes, ", sata->atapi);
1029 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1030 printf("PIO %dbytes", sata->bytecount);
1034 if (ccb->cts.protocol == PROTO_SCSI) {
1035 struct ccb_trans_settings_scsi *scsi =
1036 &ccb->cts.proto_specific.scsi;
1037 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1038 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1039 fprintf(stdout, ", Command Queueing Enabled");
1044 fprintf(stdout, "\n");
1054 atacapprint(struct ata_params *parm)
1056 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1057 ((u_int32_t)parm->lba_size_2 << 16);
1059 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1060 ((u_int64_t)parm->lba_size48_2 << 16) |
1061 ((u_int64_t)parm->lba_size48_3 << 32) |
1062 ((u_int64_t)parm->lba_size48_4 << 48);
1065 printf("protocol ");
1066 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1067 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1068 if (parm->satacapabilities & ATA_SATA_GEN3)
1069 printf(" SATA 3.x\n");
1070 else if (parm->satacapabilities & ATA_SATA_GEN2)
1071 printf(" SATA 2.x\n");
1072 else if (parm->satacapabilities & ATA_SATA_GEN1)
1073 printf(" SATA 1.x\n");
1079 printf("device model %.40s\n", parm->model);
1080 printf("firmware revision %.8s\n", parm->revision);
1081 printf("serial number %.20s\n", parm->serial);
1082 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1083 printf("WWN %02x%02x%02x%02x\n",
1084 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1086 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1087 printf("media serial number %.30s\n",
1088 parm->media_serial);
1091 printf("cylinders %d\n", parm->cylinders);
1092 printf("heads %d\n", parm->heads);
1093 printf("sectors/track %d\n", parm->sectors);
1094 printf("sector size logical %u, physical %lu, offset %lu\n",
1095 ata_logical_sector_size(parm),
1096 (unsigned long)ata_physical_sector_size(parm),
1097 (unsigned long)ata_logical_sector_offset(parm));
1099 if (parm->config == ATA_PROTO_CFA ||
1100 (parm->support.command2 & ATA_SUPPORT_CFA))
1101 printf("CFA supported\n");
1103 printf("LBA%ssupported ",
1104 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1106 printf("%d sectors\n", lbasize);
1110 printf("LBA48%ssupported ",
1111 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1113 printf("%ju sectors\n", (uintmax_t)lbasize48);
1117 printf("PIO supported PIO");
1118 switch (ata_max_pmode(parm)) {
1134 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1135 printf(" w/o IORDY");
1138 printf("DMA%ssupported ",
1139 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1140 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1141 if (parm->mwdmamodes & 0xff) {
1143 if (parm->mwdmamodes & 0x04)
1145 else if (parm->mwdmamodes & 0x02)
1147 else if (parm->mwdmamodes & 0x01)
1151 if ((parm->atavalid & ATA_FLAG_88) &&
1152 (parm->udmamodes & 0xff)) {
1154 if (parm->udmamodes & 0x40)
1156 else if (parm->udmamodes & 0x20)
1158 else if (parm->udmamodes & 0x10)
1160 else if (parm->udmamodes & 0x08)
1162 else if (parm->udmamodes & 0x04)
1164 else if (parm->udmamodes & 0x02)
1166 else if (parm->udmamodes & 0x01)
1173 if (parm->media_rotation_rate == 1) {
1174 printf("media RPM non-rotating\n");
1175 } else if (parm->media_rotation_rate >= 0x0401 &&
1176 parm->media_rotation_rate <= 0xFFFE) {
1177 printf("media RPM %d\n",
1178 parm->media_rotation_rate);
1182 "Support Enable Value Vendor\n");
1183 printf("read ahead %s %s\n",
1184 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1185 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1186 printf("write cache %s %s\n",
1187 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1188 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1189 printf("flush cache %s %s\n",
1190 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1191 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1192 printf("overlap %s\n",
1193 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1194 printf("Tagged Command Queuing (TCQ) %s %s",
1195 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1196 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1197 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1198 printf(" %d tags\n",
1199 ATA_QUEUE_LEN(parm->queue) + 1);
1202 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1203 printf("Native Command Queuing (NCQ) %s ",
1204 parm->satacapabilities & ATA_SUPPORT_NCQ ?
1206 if (parm->satacapabilities & ATA_SUPPORT_NCQ) {
1207 printf(" %d tags\n",
1208 ATA_QUEUE_LEN(parm->queue) + 1);
1212 printf("SMART %s %s\n",
1213 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1214 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1215 printf("microcode download %s %s\n",
1216 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1217 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1218 printf("security %s %s\n",
1219 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1220 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1221 printf("power management %s %s\n",
1222 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1223 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1224 printf("advanced power management %s %s %d/0x%02X\n",
1225 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1226 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1227 parm->apm_value, parm->apm_value);
1228 printf("automatic acoustic management %s %s "
1229 "%d/0x%02X %d/0x%02X\n",
1230 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1231 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1232 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1233 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1234 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1235 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1236 printf("media status notification %s %s\n",
1237 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1238 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1239 printf("power-up in Standby %s %s\n",
1240 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1241 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1242 printf("write-read-verify %s %s %d/0x%x\n",
1243 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1244 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1245 parm->wrv_mode, parm->wrv_mode);
1246 printf("unload %s %s\n",
1247 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1248 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1249 printf("free-fall %s %s\n",
1250 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1251 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1252 printf("data set management (TRIM) %s\n",
1253 parm->support_dsm & ATA_SUPPORT_DSM_TRIM ? "yes" : "no");
1258 ataidentify(struct cam_device *device, int retry_count, int timeout)
1261 struct ata_params *ident_buf;
1262 struct ccb_getdev cgd;
1266 if (get_cgd(device, &cgd) != 0) {
1267 warnx("couldn't get CGD");
1270 ccb = cam_getccb(device);
1273 warnx("couldn't allocate CCB");
1277 /* cam_getccb cleans up the header, caller has to zero the payload */
1278 bzero(&(&ccb->ccb_h)[1],
1279 sizeof(struct ccb_ataio) - sizeof(struct ccb_hdr));
1281 ptr = (uint16_t *)malloc(sizeof(struct ata_params));
1285 warnx("can't malloc memory for identify\n");
1288 bzero(ptr, sizeof(struct ata_params));
1290 cam_fill_ataio(&ccb->ataio,
1293 /*flags*/CAM_DIR_IN,
1295 /*data_ptr*/(u_int8_t *)ptr,
1296 /*dxfer_len*/sizeof(struct ata_params),
1297 timeout ? timeout : 30 * 1000);
1298 if (cgd.protocol == PROTO_ATA)
1299 ata_28bit_cmd(&ccb->ataio, ATA_ATA_IDENTIFY, 0, 0, 0);
1301 ata_28bit_cmd(&ccb->ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0);
1303 /* Disable freezing the device queue */
1304 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1306 if (arglist & CAM_ARG_ERR_RECOVER)
1307 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1309 if (cam_send_ccb(device, ccb) < 0) {
1310 perror("error sending ATA identify");
1312 if (arglist & CAM_ARG_VERBOSE) {
1313 cam_error_print(device, ccb, CAM_ESF_ALL,
1314 CAM_EPF_ALL, stderr);
1322 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1325 if (arglist & CAM_ARG_VERBOSE) {
1326 cam_error_print(device, ccb, CAM_ESF_ALL,
1327 CAM_EPF_ALL, stderr);
1338 for (i = 0; i < sizeof(struct ata_params) / 2; i++)
1339 ptr[i] = le16toh(ptr[i]);
1340 if (arglist & CAM_ARG_VERBOSE) {
1341 fprintf(stdout, "%s%d: Raw identify data:\n",
1342 device->device_name, device->dev_unit_num);
1343 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
1345 fprintf(stdout, " %3d: ", i);
1346 fprintf(stdout, "%04x ", (uint16_t)ptr[i]);
1348 fprintf(stdout, "\n");
1351 ident_buf = (struct ata_params *)ptr;
1352 if (strncmp(ident_buf->model, "FX", 2) &&
1353 strncmp(ident_buf->model, "NEC", 3) &&
1354 strncmp(ident_buf->model, "Pioneer", 7) &&
1355 strncmp(ident_buf->model, "SHARP", 5)) {
1356 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
1357 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
1358 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
1359 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
1361 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
1362 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
1363 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
1364 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
1365 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
1366 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
1367 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
1368 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
1369 sizeof(ident_buf->media_serial));
1371 fprintf(stdout, "%s%d: ", device->device_name,
1372 device->dev_unit_num);
1373 ata_print_ident(ident_buf);
1374 camxferrate(device);
1375 atacapprint(ident_buf);
1381 #endif /* MINIMALISTIC */
1384 * Parse out a bus, or a bus, target and lun in the following
1390 * Returns the number of parsed components, or 0.
1393 parse_btl(char *tstr, int *bus, int *target, int *lun, cam_argmask *arglst)
1398 while (isspace(*tstr) && (*tstr != '\0'))
1401 tmpstr = (char *)strtok(tstr, ":");
1402 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
1403 *bus = strtol(tmpstr, NULL, 0);
1404 *arglst |= CAM_ARG_BUS;
1406 tmpstr = (char *)strtok(NULL, ":");
1407 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
1408 *target = strtol(tmpstr, NULL, 0);
1409 *arglst |= CAM_ARG_TARGET;
1411 tmpstr = (char *)strtok(NULL, ":");
1412 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
1413 *lun = strtol(tmpstr, NULL, 0);
1414 *arglst |= CAM_ARG_LUN;
1424 dorescan_or_reset(int argc, char **argv, int rescan)
1426 static const char must[] =
1427 "you must specify \"all\", a bus, or a bus:target:lun to %s";
1429 int bus = -1, target = -1, lun = -1;
1433 warnx(must, rescan? "rescan" : "reset");
1437 tstr = argv[optind];
1438 while (isspace(*tstr) && (*tstr != '\0'))
1440 if (strncasecmp(tstr, "all", strlen("all")) == 0)
1441 arglist |= CAM_ARG_BUS;
1443 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
1444 if (rv != 1 && rv != 3) {
1445 warnx(must, rescan? "rescan" : "reset");
1450 if ((arglist & CAM_ARG_BUS)
1451 && (arglist & CAM_ARG_TARGET)
1452 && (arglist & CAM_ARG_LUN))
1453 error = scanlun_or_reset_dev(bus, target, lun, rescan);
1455 error = rescan_or_reset_bus(bus, rescan);
1461 rescan_or_reset_bus(int bus, int rescan)
1463 union ccb ccb, matchccb;
1469 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
1470 warnx("error opening transport layer device %s", XPT_DEVICE);
1471 warn("%s", XPT_DEVICE);
1476 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
1477 ccb.ccb_h.path_id = bus;
1478 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
1479 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
1480 ccb.crcn.flags = CAM_FLAG_NONE;
1482 /* run this at a low priority */
1483 ccb.ccb_h.pinfo.priority = 5;
1485 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
1486 warn("CAMIOCOMMAND ioctl failed");
1491 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
1492 fprintf(stdout, "%s of bus %d was successful\n",
1493 rescan ? "Re-scan" : "Reset", bus);
1495 fprintf(stdout, "%s of bus %d returned error %#x\n",
1496 rescan ? "Re-scan" : "Reset", bus,
1497 ccb.ccb_h.status & CAM_STATUS_MASK);
1508 * The right way to handle this is to modify the xpt so that it can
1509 * handle a wildcarded bus in a rescan or reset CCB. At the moment
1510 * that isn't implemented, so instead we enumerate the busses and
1511 * send the rescan or reset to those busses in the case where the
1512 * given bus is -1 (wildcard). We don't send a rescan or reset
1513 * to the xpt bus; sending a rescan to the xpt bus is effectively a
1514 * no-op, sending a rescan to the xpt bus would result in a status of
1517 bzero(&(&matchccb.ccb_h)[1],
1518 sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr));
1519 matchccb.ccb_h.func_code = XPT_DEV_MATCH;
1520 bufsize = sizeof(struct dev_match_result) * 20;
1521 matchccb.cdm.match_buf_len = bufsize;
1522 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
1523 if (matchccb.cdm.matches == NULL) {
1524 warnx("can't malloc memory for matches");
1528 matchccb.cdm.num_matches = 0;
1530 matchccb.cdm.num_patterns = 1;
1531 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
1533 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
1534 matchccb.cdm.pattern_buf_len);
1535 if (matchccb.cdm.patterns == NULL) {
1536 warnx("can't malloc memory for patterns");
1540 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
1541 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
1546 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
1547 warn("CAMIOCOMMAND ioctl failed");
1552 if ((matchccb.ccb_h.status != CAM_REQ_CMP)
1553 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
1554 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
1555 warnx("got CAM error %#x, CDM error %d\n",
1556 matchccb.ccb_h.status, matchccb.cdm.status);
1561 for (i = 0; i < matchccb.cdm.num_matches; i++) {
1562 struct bus_match_result *bus_result;
1564 /* This shouldn't happen. */
1565 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
1568 bus_result = &matchccb.cdm.matches[i].result.bus_result;
1571 * We don't want to rescan or reset the xpt bus.
1574 if ((int)bus_result->path_id == -1)
1577 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
1579 ccb.ccb_h.path_id = bus_result->path_id;
1580 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
1581 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
1582 ccb.crcn.flags = CAM_FLAG_NONE;
1584 /* run this at a low priority */
1585 ccb.ccb_h.pinfo.priority = 5;
1587 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
1588 warn("CAMIOCOMMAND ioctl failed");
1593 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
1594 fprintf(stdout, "%s of bus %d was successful\n",
1595 rescan? "Re-scan" : "Reset",
1596 bus_result->path_id);
1599 * Don't bail out just yet, maybe the other
1600 * rescan or reset commands will complete
1603 fprintf(stderr, "%s of bus %d returned error "
1604 "%#x\n", rescan? "Re-scan" : "Reset",
1605 bus_result->path_id,
1606 ccb.ccb_h.status & CAM_STATUS_MASK);
1610 } while ((matchccb.ccb_h.status == CAM_REQ_CMP)
1611 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
1618 if (matchccb.cdm.patterns != NULL)
1619 free(matchccb.cdm.patterns);
1620 if (matchccb.cdm.matches != NULL)
1621 free(matchccb.cdm.matches);
1627 scanlun_or_reset_dev(int bus, int target, int lun, int scan)
1630 struct cam_device *device;
1636 warnx("invalid bus number %d", bus);
1641 warnx("invalid target number %d", target);
1646 warnx("invalid lun number %d", lun);
1652 bzero(&ccb, sizeof(union ccb));
1655 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
1656 warnx("error opening transport layer device %s\n",
1658 warn("%s", XPT_DEVICE);
1662 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
1663 if (device == NULL) {
1664 warnx("%s", cam_errbuf);
1669 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
1670 ccb.ccb_h.path_id = bus;
1671 ccb.ccb_h.target_id = target;
1672 ccb.ccb_h.target_lun = lun;
1673 ccb.ccb_h.timeout = 5000;
1674 ccb.crcn.flags = CAM_FLAG_NONE;
1676 /* run this at a low priority */
1677 ccb.ccb_h.pinfo.priority = 5;
1680 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
1681 warn("CAMIOCOMMAND ioctl failed");
1686 if (cam_send_ccb(device, &ccb) < 0) {
1687 warn("error sending XPT_RESET_DEV CCB");
1688 cam_close_device(device);
1696 cam_close_device(device);
1699 * An error code of CAM_BDR_SENT is normal for a BDR request.
1701 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
1703 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
1704 fprintf(stdout, "%s of %d:%d:%d was successful\n",
1705 scan? "Re-scan" : "Reset", bus, target, lun);
1708 fprintf(stdout, "%s of %d:%d:%d returned error %#x\n",
1709 scan? "Re-scan" : "Reset", bus, target, lun,
1710 ccb.ccb_h.status & CAM_STATUS_MASK);
1715 #ifndef MINIMALISTIC
1717 readdefects(struct cam_device *device, int argc, char **argv,
1718 char *combinedopt, int retry_count, int timeout)
1720 union ccb *ccb = NULL;
1721 struct scsi_read_defect_data_10 *rdd_cdb;
1722 u_int8_t *defect_list = NULL;
1723 u_int32_t dlist_length = 65000;
1724 u_int32_t returned_length = 0;
1725 u_int32_t num_returned = 0;
1726 u_int8_t returned_format;
1729 int lists_specified = 0;
1731 while ((c = getopt(argc, argv, combinedopt)) != -1) {
1737 while (isspace(*tstr) && (*tstr != '\0'))
1739 if (strcmp(tstr, "block") == 0)
1740 arglist |= CAM_ARG_FORMAT_BLOCK;
1741 else if (strcmp(tstr, "bfi") == 0)
1742 arglist |= CAM_ARG_FORMAT_BFI;
1743 else if (strcmp(tstr, "phys") == 0)
1744 arglist |= CAM_ARG_FORMAT_PHYS;
1747 warnx("invalid defect format %s", tstr);
1748 goto defect_bailout;
1753 arglist |= CAM_ARG_GLIST;
1756 arglist |= CAM_ARG_PLIST;
1763 ccb = cam_getccb(device);
1766 * Hopefully 65000 bytes is enough to hold the defect list. If it
1767 * isn't, the disk is probably dead already. We'd have to go with
1768 * 12 byte command (i.e. alloc_length is 32 bits instead of 16)
1771 defect_list = malloc(dlist_length);
1772 if (defect_list == NULL) {
1773 warnx("can't malloc memory for defect list");
1775 goto defect_bailout;
1778 rdd_cdb =(struct scsi_read_defect_data_10 *)&ccb->csio.cdb_io.cdb_bytes;
1781 * cam_getccb() zeros the CCB header only. So we need to zero the
1782 * payload portion of the ccb.
1784 bzero(&(&ccb->ccb_h)[1],
1785 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1787 cam_fill_csio(&ccb->csio,
1788 /*retries*/ retry_count,
1790 /*flags*/ CAM_DIR_IN | ((arglist & CAM_ARG_ERR_RECOVER) ?
1791 CAM_PASS_ERR_RECOVER : 0),
1792 /*tag_action*/ MSG_SIMPLE_Q_TAG,
1793 /*data_ptr*/ defect_list,
1794 /*dxfer_len*/ dlist_length,
1795 /*sense_len*/ SSD_FULL_SIZE,
1796 /*cdb_len*/ sizeof(struct scsi_read_defect_data_10),
1797 /*timeout*/ timeout ? timeout : 5000);
1799 rdd_cdb->opcode = READ_DEFECT_DATA_10;
1800 if (arglist & CAM_ARG_FORMAT_BLOCK)
1801 rdd_cdb->format = SRDD10_BLOCK_FORMAT;
1802 else if (arglist & CAM_ARG_FORMAT_BFI)
1803 rdd_cdb->format = SRDD10_BYTES_FROM_INDEX_FORMAT;
1804 else if (arglist & CAM_ARG_FORMAT_PHYS)
1805 rdd_cdb->format = SRDD10_PHYSICAL_SECTOR_FORMAT;
1808 warnx("no defect list format specified");
1809 goto defect_bailout;
1811 if (arglist & CAM_ARG_PLIST) {
1812 rdd_cdb->format |= SRDD10_PLIST;
1816 if (arglist & CAM_ARG_GLIST) {
1817 rdd_cdb->format |= SRDD10_GLIST;
1821 scsi_ulto2b(dlist_length, rdd_cdb->alloc_length);
1823 /* Disable freezing the device queue */
1824 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1826 if (cam_send_ccb(device, ccb) < 0) {
1827 perror("error reading defect list");
1829 if (arglist & CAM_ARG_VERBOSE) {
1830 cam_error_print(device, ccb, CAM_ESF_ALL,
1831 CAM_EPF_ALL, stderr);
1835 goto defect_bailout;
1838 returned_length = scsi_2btoul(((struct
1839 scsi_read_defect_data_hdr_10 *)defect_list)->length);
1841 returned_format = ((struct scsi_read_defect_data_hdr_10 *)
1842 defect_list)->format;
1844 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
1845 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
1846 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
1847 struct scsi_sense_data *sense;
1848 int error_code, sense_key, asc, ascq;
1850 sense = &ccb->csio.sense_data;
1851 scsi_extract_sense(sense, &error_code, &sense_key, &asc, &ascq);
1854 * According to the SCSI spec, if the disk doesn't support
1855 * the requested format, it will generally return a sense
1856 * key of RECOVERED ERROR, and an additional sense code
1857 * of "DEFECT LIST NOT FOUND". So, we check for that, and
1858 * also check to make sure that the returned length is
1859 * greater than 0, and then print out whatever format the
1862 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
1863 && (asc == 0x1c) && (ascq == 0x00)
1864 && (returned_length > 0)) {
1865 warnx("requested defect format not available");
1866 switch(returned_format & SRDDH10_DLIST_FORMAT_MASK) {
1867 case SRDD10_BLOCK_FORMAT:
1868 warnx("Device returned block format");
1870 case SRDD10_BYTES_FROM_INDEX_FORMAT:
1871 warnx("Device returned bytes from index"
1874 case SRDD10_PHYSICAL_SECTOR_FORMAT:
1875 warnx("Device returned physical sector format");
1879 warnx("Device returned unknown defect"
1880 " data format %#x", returned_format);
1881 goto defect_bailout;
1882 break; /* NOTREACHED */
1886 warnx("Error returned from read defect data command");
1887 if (arglist & CAM_ARG_VERBOSE)
1888 cam_error_print(device, ccb, CAM_ESF_ALL,
1889 CAM_EPF_ALL, stderr);
1890 goto defect_bailout;
1892 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1894 warnx("Error returned from read defect data command");
1895 if (arglist & CAM_ARG_VERBOSE)
1896 cam_error_print(device, ccb, CAM_ESF_ALL,
1897 CAM_EPF_ALL, stderr);
1898 goto defect_bailout;
1902 * XXX KDM I should probably clean up the printout format for the
1905 switch (returned_format & SRDDH10_DLIST_FORMAT_MASK){
1906 case SRDDH10_PHYSICAL_SECTOR_FORMAT:
1908 struct scsi_defect_desc_phys_sector *dlist;
1910 dlist = (struct scsi_defect_desc_phys_sector *)
1912 sizeof(struct scsi_read_defect_data_hdr_10));
1914 num_returned = returned_length /
1915 sizeof(struct scsi_defect_desc_phys_sector);
1917 fprintf(stderr, "Got %d defect", num_returned);
1919 if ((lists_specified == 0) || (num_returned == 0)) {
1920 fprintf(stderr, "s.\n");
1922 } else if (num_returned == 1)
1923 fprintf(stderr, ":\n");
1925 fprintf(stderr, "s:\n");
1927 for (i = 0; i < num_returned; i++) {
1928 fprintf(stdout, "%d:%d:%d\n",
1929 scsi_3btoul(dlist[i].cylinder),
1931 scsi_4btoul(dlist[i].sector));
1935 case SRDDH10_BYTES_FROM_INDEX_FORMAT:
1937 struct scsi_defect_desc_bytes_from_index *dlist;
1939 dlist = (struct scsi_defect_desc_bytes_from_index *)
1941 sizeof(struct scsi_read_defect_data_hdr_10));
1943 num_returned = returned_length /
1944 sizeof(struct scsi_defect_desc_bytes_from_index);
1946 fprintf(stderr, "Got %d defect", num_returned);
1948 if ((lists_specified == 0) || (num_returned == 0)) {
1949 fprintf(stderr, "s.\n");
1951 } else if (num_returned == 1)
1952 fprintf(stderr, ":\n");
1954 fprintf(stderr, "s:\n");
1956 for (i = 0; i < num_returned; i++) {
1957 fprintf(stdout, "%d:%d:%d\n",
1958 scsi_3btoul(dlist[i].cylinder),
1960 scsi_4btoul(dlist[i].bytes_from_index));
1964 case SRDDH10_BLOCK_FORMAT:
1966 struct scsi_defect_desc_block *dlist;
1968 dlist = (struct scsi_defect_desc_block *)(defect_list +
1969 sizeof(struct scsi_read_defect_data_hdr_10));
1971 num_returned = returned_length /
1972 sizeof(struct scsi_defect_desc_block);
1974 fprintf(stderr, "Got %d defect", num_returned);
1976 if ((lists_specified == 0) || (num_returned == 0)) {
1977 fprintf(stderr, "s.\n");
1979 } else if (num_returned == 1)
1980 fprintf(stderr, ":\n");
1982 fprintf(stderr, "s:\n");
1984 for (i = 0; i < num_returned; i++)
1985 fprintf(stdout, "%u\n",
1986 scsi_4btoul(dlist[i].address));
1990 fprintf(stderr, "Unknown defect format %d\n",
1991 returned_format & SRDDH10_DLIST_FORMAT_MASK);
1997 if (defect_list != NULL)
2005 #endif /* MINIMALISTIC */
2009 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
2013 ccb = cam_getccb(device);
2019 #ifndef MINIMALISTIC
2021 mode_sense(struct cam_device *device, int mode_page, int page_control,
2022 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
2027 ccb = cam_getccb(device);
2030 errx(1, "mode_sense: couldn't allocate CCB");
2032 bzero(&(&ccb->ccb_h)[1],
2033 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
2035 scsi_mode_sense(&ccb->csio,
2036 /* retries */ retry_count,
2038 /* tag_action */ MSG_SIMPLE_Q_TAG,
2040 /* page_code */ page_control << 6,
2041 /* page */ mode_page,
2042 /* param_buf */ data,
2043 /* param_len */ datalen,
2044 /* sense_len */ SSD_FULL_SIZE,
2045 /* timeout */ timeout ? timeout : 5000);
2047 if (arglist & CAM_ARG_ERR_RECOVER)
2048 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
2050 /* Disable freezing the device queue */
2051 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
2053 if (((retval = cam_send_ccb(device, ccb)) < 0)
2054 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
2055 if (arglist & CAM_ARG_VERBOSE) {
2056 cam_error_print(device, ccb, CAM_ESF_ALL,
2057 CAM_EPF_ALL, stderr);
2060 cam_close_device(device);
2062 err(1, "error sending mode sense command");
2064 errx(1, "error sending mode sense command");
2071 mode_select(struct cam_device *device, int save_pages, int retry_count,
2072 int timeout, u_int8_t *data, int datalen)
2077 ccb = cam_getccb(device);
2080 errx(1, "mode_select: couldn't allocate CCB");
2082 bzero(&(&ccb->ccb_h)[1],
2083 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
2085 scsi_mode_select(&ccb->csio,
2086 /* retries */ retry_count,
2088 /* tag_action */ MSG_SIMPLE_Q_TAG,
2089 /* scsi_page_fmt */ 1,
2090 /* save_pages */ save_pages,
2091 /* param_buf */ data,
2092 /* param_len */ datalen,
2093 /* sense_len */ SSD_FULL_SIZE,
2094 /* timeout */ timeout ? timeout : 5000);
2096 if (arglist & CAM_ARG_ERR_RECOVER)
2097 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
2099 /* Disable freezing the device queue */
2100 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
2102 if (((retval = cam_send_ccb(device, ccb)) < 0)
2103 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
2104 if (arglist & CAM_ARG_VERBOSE) {
2105 cam_error_print(device, ccb, CAM_ESF_ALL,
2106 CAM_EPF_ALL, stderr);
2109 cam_close_device(device);
2112 err(1, "error sending mode select command");
2114 errx(1, "error sending mode select command");
2122 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
2123 int retry_count, int timeout)
2125 int c, mode_page = -1, page_control = 0;
2126 int binary = 0, list = 0;
2128 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2134 arglist |= CAM_ARG_DBD;
2137 arglist |= CAM_ARG_MODE_EDIT;
2143 mode_page = strtol(optarg, NULL, 0);
2145 errx(1, "invalid mode page %d", mode_page);
2148 page_control = strtol(optarg, NULL, 0);
2149 if ((page_control < 0) || (page_control > 3))
2150 errx(1, "invalid page control field %d",
2152 arglist |= CAM_ARG_PAGE_CNTL;
2159 if (mode_page == -1 && list == 0)
2160 errx(1, "you must specify a mode page!");
2163 mode_list(device, page_control, arglist & CAM_ARG_DBD,
2164 retry_count, timeout);
2166 mode_edit(device, mode_page, page_control,
2167 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
2168 retry_count, timeout);
2173 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
2174 int retry_count, int timeout)
2177 u_int32_t flags = CAM_DIR_NONE;
2178 u_int8_t *data_ptr = NULL;
2180 u_int8_t atacmd[12];
2181 struct get_hook hook;
2182 int c, data_bytes = 0;
2186 char *datastr = NULL, *tstr, *resstr = NULL;
2188 int fd_data = 0, fd_res = 0;
2191 ccb = cam_getccb(device);
2194 warnx("scsicmd: error allocating ccb");
2198 bzero(&(&ccb->ccb_h)[1],
2199 sizeof(union ccb) - sizeof(struct ccb_hdr));
2201 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2205 while (isspace(*tstr) && (*tstr != '\0'))
2207 hook.argc = argc - optind;
2208 hook.argv = argv + optind;
2210 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
2213 * Increment optind by the number of arguments the
2214 * encoding routine processed. After each call to
2215 * getopt(3), optind points to the argument that
2216 * getopt should process _next_. In this case,
2217 * that means it points to the first command string
2218 * argument, if there is one. Once we increment
2219 * this, it should point to either the next command
2220 * line argument, or it should be past the end of
2227 while (isspace(*tstr) && (*tstr != '\0'))
2229 hook.argc = argc - optind;
2230 hook.argv = argv + optind;
2232 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
2235 * Increment optind by the number of arguments the
2236 * encoding routine processed. After each call to
2237 * getopt(3), optind points to the argument that
2238 * getopt should process _next_. In this case,
2239 * that means it points to the first command string
2240 * argument, if there is one. Once we increment
2241 * this, it should point to either the next command
2242 * line argument, or it should be past the end of
2248 if (arglist & CAM_ARG_CMD_OUT) {
2249 warnx("command must either be "
2250 "read or write, not both");
2252 goto scsicmd_bailout;
2254 arglist |= CAM_ARG_CMD_IN;
2256 data_bytes = strtol(optarg, NULL, 0);
2257 if (data_bytes <= 0) {
2258 warnx("invalid number of input bytes %d",
2261 goto scsicmd_bailout;
2263 hook.argc = argc - optind;
2264 hook.argv = argv + optind;
2267 datastr = cget(&hook, NULL);
2269 * If the user supplied "-" instead of a format, he
2270 * wants the data to be written to stdout.
2272 if ((datastr != NULL)
2273 && (datastr[0] == '-'))
2276 data_ptr = (u_int8_t *)malloc(data_bytes);
2277 if (data_ptr == NULL) {
2278 warnx("can't malloc memory for data_ptr");
2280 goto scsicmd_bailout;
2284 if (arglist & CAM_ARG_CMD_IN) {
2285 warnx("command must either be "
2286 "read or write, not both");
2288 goto scsicmd_bailout;
2290 arglist |= CAM_ARG_CMD_OUT;
2291 flags = CAM_DIR_OUT;
2292 data_bytes = strtol(optarg, NULL, 0);
2293 if (data_bytes <= 0) {
2294 warnx("invalid number of output bytes %d",
2297 goto scsicmd_bailout;
2299 hook.argc = argc - optind;
2300 hook.argv = argv + optind;
2302 datastr = cget(&hook, NULL);
2303 data_ptr = (u_int8_t *)malloc(data_bytes);
2304 if (data_ptr == NULL) {
2305 warnx("can't malloc memory for data_ptr");
2307 goto scsicmd_bailout;
2309 bzero(data_ptr, data_bytes);
2311 * If the user supplied "-" instead of a format, he
2312 * wants the data to be read from stdin.
2314 if ((datastr != NULL)
2315 && (datastr[0] == '-'))
2318 buff_encode_visit(data_ptr, data_bytes, datastr,
2324 hook.argc = argc - optind;
2325 hook.argv = argv + optind;
2327 resstr = cget(&hook, NULL);
2328 if ((resstr != NULL) && (resstr[0] == '-'))
2338 * If fd_data is set, and we're writing to the device, we need to
2339 * read the data the user wants written from stdin.
2341 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
2343 int amt_to_read = data_bytes;
2344 u_int8_t *buf_ptr = data_ptr;
2346 for (amt_read = 0; amt_to_read > 0;
2347 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
2348 if (amt_read == -1) {
2349 warn("error reading data from stdin");
2351 goto scsicmd_bailout;
2353 amt_to_read -= amt_read;
2354 buf_ptr += amt_read;
2358 if (arglist & CAM_ARG_ERR_RECOVER)
2359 flags |= CAM_PASS_ERR_RECOVER;
2361 /* Disable freezing the device queue */
2362 flags |= CAM_DEV_QFRZDIS;
2366 * This is taken from the SCSI-3 draft spec.
2367 * (T10/1157D revision 0.3)
2368 * The top 3 bits of an opcode are the group code.
2369 * The next 5 bits are the command code.
2370 * Group 0: six byte commands
2371 * Group 1: ten byte commands
2372 * Group 2: ten byte commands
2374 * Group 4: sixteen byte commands
2375 * Group 5: twelve byte commands
2376 * Group 6: vendor specific
2377 * Group 7: vendor specific
2379 switch((cdb[0] >> 5) & 0x7) {
2390 /* computed by buff_encode_visit */
2401 * We should probably use csio_build_visit or something like that
2402 * here, but it's easier to encode arguments as you go. The
2403 * alternative would be skipping the CDB argument and then encoding
2404 * it here, since we've got the data buffer argument by now.
2406 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
2408 cam_fill_csio(&ccb->csio,
2409 /*retries*/ retry_count,
2412 /*tag_action*/ MSG_SIMPLE_Q_TAG,
2413 /*data_ptr*/ data_ptr,
2414 /*dxfer_len*/ data_bytes,
2415 /*sense_len*/ SSD_FULL_SIZE,
2416 /*cdb_len*/ cdb_len,
2417 /*timeout*/ timeout ? timeout : 5000);
2420 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
2422 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
2424 cam_fill_ataio(&ccb->ataio,
2425 /*retries*/ retry_count,
2429 /*data_ptr*/ data_ptr,
2430 /*dxfer_len*/ data_bytes,
2431 /*timeout*/ timeout ? timeout : 5000);
2434 if (((retval = cam_send_ccb(device, ccb)) < 0)
2435 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
2437 warn("error sending command");
2439 warnx("error sending command");
2441 if (arglist & CAM_ARG_VERBOSE) {
2442 cam_error_print(device, ccb, CAM_ESF_ALL,
2443 CAM_EPF_ALL, stderr);
2447 goto scsicmd_bailout;
2450 if (atacmd_len && need_res) {
2452 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
2454 fprintf(stdout, "\n");
2457 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
2458 ccb->ataio.res.status,
2459 ccb->ataio.res.error,
2460 ccb->ataio.res.lba_low,
2461 ccb->ataio.res.lba_mid,
2462 ccb->ataio.res.lba_high,
2463 ccb->ataio.res.device,
2464 ccb->ataio.res.lba_low_exp,
2465 ccb->ataio.res.lba_mid_exp,
2466 ccb->ataio.res.lba_high_exp,
2467 ccb->ataio.res.sector_count,
2468 ccb->ataio.res.sector_count_exp);
2473 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
2474 && (arglist & CAM_ARG_CMD_IN)
2475 && (data_bytes > 0)) {
2477 buff_decode_visit(data_ptr, data_bytes, datastr,
2479 fprintf(stdout, "\n");
2481 ssize_t amt_written;
2482 int amt_to_write = data_bytes;
2483 u_int8_t *buf_ptr = data_ptr;
2485 for (amt_written = 0; (amt_to_write > 0) &&
2486 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
2487 amt_to_write -= amt_written;
2488 buf_ptr += amt_written;
2490 if (amt_written == -1) {
2491 warn("error writing data to stdout");
2493 goto scsicmd_bailout;
2494 } else if ((amt_written == 0)
2495 && (amt_to_write > 0)) {
2496 warnx("only wrote %u bytes out of %u",
2497 data_bytes - amt_to_write, data_bytes);
2504 if ((data_bytes > 0) && (data_ptr != NULL))
2513 camdebug(int argc, char **argv, char *combinedopt)
2516 int bus = -1, target = -1, lun = -1;
2517 char *tstr, *tmpstr = NULL;
2521 bzero(&ccb, sizeof(union ccb));
2523 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2526 arglist |= CAM_ARG_DEBUG_INFO;
2527 ccb.cdbg.flags |= CAM_DEBUG_INFO;
2530 arglist |= CAM_ARG_DEBUG_PERIPH;
2531 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
2534 arglist |= CAM_ARG_DEBUG_SUBTRACE;
2535 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
2538 arglist |= CAM_ARG_DEBUG_TRACE;
2539 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
2542 arglist |= CAM_ARG_DEBUG_XPT;
2543 ccb.cdbg.flags |= CAM_DEBUG_XPT;
2546 arglist |= CAM_ARG_DEBUG_CDB;
2547 ccb.cdbg.flags |= CAM_DEBUG_CDB;
2554 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
2555 warnx("error opening transport layer device %s", XPT_DEVICE);
2556 warn("%s", XPT_DEVICE);
2563 warnx("you must specify \"off\", \"all\" or a bus,");
2564 warnx("bus:target, or bus:target:lun");
2571 while (isspace(*tstr) && (*tstr != '\0'))
2574 if (strncmp(tstr, "off", 3) == 0) {
2575 ccb.cdbg.flags = CAM_DEBUG_NONE;
2576 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
2577 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
2579 } else if (strncmp(tstr, "all", 3) != 0) {
2580 tmpstr = (char *)strtok(tstr, ":");
2581 if ((tmpstr != NULL) && (*tmpstr != '\0')){
2582 bus = strtol(tmpstr, NULL, 0);
2583 arglist |= CAM_ARG_BUS;
2584 tmpstr = (char *)strtok(NULL, ":");
2585 if ((tmpstr != NULL) && (*tmpstr != '\0')){
2586 target = strtol(tmpstr, NULL, 0);
2587 arglist |= CAM_ARG_TARGET;
2588 tmpstr = (char *)strtok(NULL, ":");
2589 if ((tmpstr != NULL) && (*tmpstr != '\0')){
2590 lun = strtol(tmpstr, NULL, 0);
2591 arglist |= CAM_ARG_LUN;
2596 warnx("you must specify \"all\", \"off\", or a bus,");
2597 warnx("bus:target, or bus:target:lun to debug");
2603 ccb.ccb_h.func_code = XPT_DEBUG;
2604 ccb.ccb_h.path_id = bus;
2605 ccb.ccb_h.target_id = target;
2606 ccb.ccb_h.target_lun = lun;
2608 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
2609 warn("CAMIOCOMMAND ioctl failed");
2614 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
2615 CAM_FUNC_NOTAVAIL) {
2616 warnx("CAM debugging not available");
2617 warnx("you need to put options CAMDEBUG in"
2618 " your kernel config file!");
2620 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
2622 warnx("XPT_DEBUG CCB failed with status %#x",
2626 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
2628 "Debugging turned off\n");
2631 "Debugging enabled for "
2644 tagcontrol(struct cam_device *device, int argc, char **argv,
2654 ccb = cam_getccb(device);
2657 warnx("tagcontrol: error allocating ccb");
2661 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2664 numtags = strtol(optarg, NULL, 0);
2666 warnx("tag count %d is < 0", numtags);
2668 goto tagcontrol_bailout;
2679 cam_path_string(device, pathstr, sizeof(pathstr));
2682 bzero(&(&ccb->ccb_h)[1],
2683 sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
2684 ccb->ccb_h.func_code = XPT_REL_SIMQ;
2685 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
2686 ccb->crs.openings = numtags;
2689 if (cam_send_ccb(device, ccb) < 0) {
2690 perror("error sending XPT_REL_SIMQ CCB");
2692 goto tagcontrol_bailout;
2695 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2696 warnx("XPT_REL_SIMQ CCB failed");
2697 cam_error_print(device, ccb, CAM_ESF_ALL,
2698 CAM_EPF_ALL, stderr);
2700 goto tagcontrol_bailout;
2705 fprintf(stdout, "%stagged openings now %d\n",
2706 pathstr, ccb->crs.openings);
2709 bzero(&(&ccb->ccb_h)[1],
2710 sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr));
2712 ccb->ccb_h.func_code = XPT_GDEV_STATS;
2714 if (cam_send_ccb(device, ccb) < 0) {
2715 perror("error sending XPT_GDEV_STATS CCB");
2717 goto tagcontrol_bailout;
2720 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2721 warnx("XPT_GDEV_STATS CCB failed");
2722 cam_error_print(device, ccb, CAM_ESF_ALL,
2723 CAM_EPF_ALL, stderr);
2725 goto tagcontrol_bailout;
2728 if (arglist & CAM_ARG_VERBOSE) {
2729 fprintf(stdout, "%s", pathstr);
2730 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
2731 fprintf(stdout, "%s", pathstr);
2732 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
2733 fprintf(stdout, "%s", pathstr);
2734 fprintf(stdout, "devq_openings %d\n", ccb->cgds.devq_openings);
2735 fprintf(stdout, "%s", pathstr);
2736 fprintf(stdout, "devq_queued %d\n", ccb->cgds.devq_queued);
2737 fprintf(stdout, "%s", pathstr);
2738 fprintf(stdout, "held %d\n", ccb->cgds.held);
2739 fprintf(stdout, "%s", pathstr);
2740 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
2741 fprintf(stdout, "%s", pathstr);
2742 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
2745 fprintf(stdout, "%s", pathstr);
2746 fprintf(stdout, "device openings: ");
2748 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
2749 ccb->cgds.dev_active);
2759 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
2763 cam_path_string(device, pathstr, sizeof(pathstr));
2765 if (cts->transport == XPORT_SPI) {
2766 struct ccb_trans_settings_spi *spi =
2767 &cts->xport_specific.spi;
2769 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
2771 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
2774 if (spi->sync_offset != 0) {
2777 freq = scsi_calc_syncsrate(spi->sync_period);
2778 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
2779 pathstr, freq / 1000, freq % 1000);
2783 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
2784 fprintf(stdout, "%soffset: %d\n", pathstr,
2788 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
2789 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
2790 (0x01 << spi->bus_width) * 8);
2793 if (spi->valid & CTS_SPI_VALID_DISC) {
2794 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
2795 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
2796 "enabled" : "disabled");
2799 if (cts->transport == XPORT_ATA) {
2800 struct ccb_trans_settings_ata *ata =
2801 &cts->xport_specific.ata;
2803 if ((ata->valid & CTS_ATA_VALID_MODE) != 0) {
2804 fprintf(stdout, "%sATA mode: %s\n", pathstr,
2805 ata_mode2string(ata->mode));
2807 if ((ata->valid & CTS_ATA_VALID_ATAPI) != 0) {
2808 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
2811 if ((ata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
2812 fprintf(stdout, "%sPIO transaction length: %d\n",
2813 pathstr, ata->bytecount);
2816 if (cts->transport == XPORT_SATA) {
2817 struct ccb_trans_settings_sata *sata =
2818 &cts->xport_specific.sata;
2820 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
2821 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
2824 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
2825 fprintf(stdout, "%sATA mode: %s\n", pathstr,
2826 ata_mode2string(sata->mode));
2828 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
2829 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
2832 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
2833 fprintf(stdout, "%sPIO transaction length: %d\n",
2834 pathstr, sata->bytecount);
2836 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
2837 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
2840 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
2841 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
2845 if (cts->protocol == PROTO_SCSI) {
2846 struct ccb_trans_settings_scsi *scsi=
2847 &cts->proto_specific.scsi;
2849 if (scsi->valid & CTS_SCSI_VALID_TQ) {
2850 fprintf(stdout, "%stagged queueing is %s\n", pathstr,
2851 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
2852 "enabled" : "disabled");
2859 * Get a path inquiry CCB for the specified device.
2862 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
2867 ccb = cam_getccb(device);
2869 warnx("get_cpi: couldn't allocate CCB");
2872 bzero(&(&ccb->ccb_h)[1],
2873 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
2874 ccb->ccb_h.func_code = XPT_PATH_INQ;
2875 if (cam_send_ccb(device, ccb) < 0) {
2876 warn("get_cpi: error sending Path Inquiry CCB");
2877 if (arglist & CAM_ARG_VERBOSE)
2878 cam_error_print(device, ccb, CAM_ESF_ALL,
2879 CAM_EPF_ALL, stderr);
2881 goto get_cpi_bailout;
2883 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2884 if (arglist & CAM_ARG_VERBOSE)
2885 cam_error_print(device, ccb, CAM_ESF_ALL,
2886 CAM_EPF_ALL, stderr);
2888 goto get_cpi_bailout;
2890 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
2898 * Get a get device CCB for the specified device.
2901 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
2906 ccb = cam_getccb(device);
2908 warnx("get_cgd: couldn't allocate CCB");
2911 bzero(&(&ccb->ccb_h)[1],
2912 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
2913 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
2914 if (cam_send_ccb(device, ccb) < 0) {
2915 warn("get_cgd: error sending Path Inquiry CCB");
2916 if (arglist & CAM_ARG_VERBOSE)
2917 cam_error_print(device, ccb, CAM_ESF_ALL,
2918 CAM_EPF_ALL, stderr);
2920 goto get_cgd_bailout;
2922 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2923 if (arglist & CAM_ARG_VERBOSE)
2924 cam_error_print(device, ccb, CAM_ESF_ALL,
2925 CAM_EPF_ALL, stderr);
2927 goto get_cgd_bailout;
2929 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
2937 cpi_print(struct ccb_pathinq *cpi)
2939 char adapter_str[1024];
2942 snprintf(adapter_str, sizeof(adapter_str),
2943 "%s%d:", cpi->dev_name, cpi->unit_number);
2945 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
2948 for (i = 1; i < 0xff; i = i << 1) {
2951 if ((i & cpi->hba_inquiry) == 0)
2954 fprintf(stdout, "%s supports ", adapter_str);
2958 str = "MDP message";
2961 str = "32 bit wide SCSI";
2964 str = "16 bit wide SCSI";
2967 str = "SDTR message";
2970 str = "linked CDBs";
2973 str = "tag queue messages";
2976 str = "soft reset alternative";
2979 str = "SATA Port Multiplier";
2982 str = "unknown PI bit set";
2985 fprintf(stdout, "%s\n", str);
2988 for (i = 1; i < 0xff; i = i << 1) {
2991 if ((i & cpi->hba_misc) == 0)
2994 fprintf(stdout, "%s ", adapter_str);
2998 str = "bus scans from high ID to low ID";
3001 str = "removable devices not included in scan";
3003 case PIM_NOINITIATOR:
3004 str = "initiator role not supported";
3006 case PIM_NOBUSRESET:
3007 str = "user has disabled initial BUS RESET or"
3008 " controller is in target/mixed mode";
3011 str = "do not send 6-byte commands";
3014 str = "scan bus sequentially";
3017 str = "unknown PIM bit set";
3020 fprintf(stdout, "%s\n", str);
3023 for (i = 1; i < 0xff; i = i << 1) {
3026 if ((i & cpi->target_sprt) == 0)
3029 fprintf(stdout, "%s supports ", adapter_str);
3032 str = "target mode processor mode";
3035 str = "target mode phase cog. mode";
3037 case PIT_DISCONNECT:
3038 str = "disconnects in target mode";
3041 str = "terminate I/O message in target mode";
3044 str = "group 6 commands in target mode";
3047 str = "group 7 commands in target mode";
3050 str = "unknown PIT bit set";
3054 fprintf(stdout, "%s\n", str);
3056 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
3058 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
3060 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
3062 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
3063 adapter_str, cpi->hpath_id);
3064 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
3066 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
3067 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
3068 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
3069 fprintf(stdout, "%s base transfer speed: ", adapter_str);
3070 if (cpi->base_transfer_speed > 1000)
3071 fprintf(stdout, "%d.%03dMB/sec\n",
3072 cpi->base_transfer_speed / 1000,
3073 cpi->base_transfer_speed % 1000);
3075 fprintf(stdout, "%dKB/sec\n",
3076 (cpi->base_transfer_speed % 1000) * 1000);
3080 get_print_cts(struct cam_device *device, int user_settings, int quiet,
3081 struct ccb_trans_settings *cts)
3087 ccb = cam_getccb(device);
3090 warnx("get_print_cts: error allocating ccb");
3094 bzero(&(&ccb->ccb_h)[1],
3095 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
3097 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
3099 if (user_settings == 0)
3100 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
3102 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
3104 if (cam_send_ccb(device, ccb) < 0) {
3105 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
3106 if (arglist & CAM_ARG_VERBOSE)
3107 cam_error_print(device, ccb, CAM_ESF_ALL,
3108 CAM_EPF_ALL, stderr);
3110 goto get_print_cts_bailout;
3113 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3114 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
3115 if (arglist & CAM_ARG_VERBOSE)
3116 cam_error_print(device, ccb, CAM_ESF_ALL,
3117 CAM_EPF_ALL, stderr);
3119 goto get_print_cts_bailout;
3123 cts_print(device, &ccb->cts);
3126 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
3128 get_print_cts_bailout:
3136 ratecontrol(struct cam_device *device, int retry_count, int timeout,
3137 int argc, char **argv, char *combinedopt)
3141 int user_settings = 0;
3143 int disc_enable = -1, tag_enable = -1;
3146 double syncrate = -1;
3149 int change_settings = 0, send_tur = 0;
3150 struct ccb_pathinq cpi;
3152 ccb = cam_getccb(device);
3154 warnx("ratecontrol: error allocating ccb");
3157 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3166 if (strncasecmp(optarg, "enable", 6) == 0)
3168 else if (strncasecmp(optarg, "disable", 7) == 0)
3171 warnx("-D argument \"%s\" is unknown", optarg);
3173 goto ratecontrol_bailout;
3175 change_settings = 1;
3178 mode = ata_string2mode(optarg);
3180 warnx("unknown mode '%s'", optarg);
3182 goto ratecontrol_bailout;
3184 change_settings = 1;
3187 offset = strtol(optarg, NULL, 0);
3189 warnx("offset value %d is < 0", offset);
3191 goto ratecontrol_bailout;
3193 change_settings = 1;
3199 syncrate = atof(optarg);
3201 warnx("sync rate %f is < 0", syncrate);
3203 goto ratecontrol_bailout;
3205 change_settings = 1;
3208 if (strncasecmp(optarg, "enable", 6) == 0)
3210 else if (strncasecmp(optarg, "disable", 7) == 0)
3213 warnx("-T argument \"%s\" is unknown", optarg);
3215 goto ratecontrol_bailout;
3217 change_settings = 1;
3223 bus_width = strtol(optarg, NULL, 0);
3224 if (bus_width < 0) {
3225 warnx("bus width %d is < 0", bus_width);
3227 goto ratecontrol_bailout;
3229 change_settings = 1;
3235 bzero(&(&ccb->ccb_h)[1],
3236 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
3238 * Grab path inquiry information, so we can determine whether
3239 * or not the initiator is capable of the things that the user
3242 ccb->ccb_h.func_code = XPT_PATH_INQ;
3243 if (cam_send_ccb(device, ccb) < 0) {
3244 perror("error sending XPT_PATH_INQ CCB");
3245 if (arglist & CAM_ARG_VERBOSE) {
3246 cam_error_print(device, ccb, CAM_ESF_ALL,
3247 CAM_EPF_ALL, stderr);
3250 goto ratecontrol_bailout;
3252 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3253 warnx("XPT_PATH_INQ CCB failed");
3254 if (arglist & CAM_ARG_VERBOSE) {
3255 cam_error_print(device, ccb, CAM_ESF_ALL,
3256 CAM_EPF_ALL, stderr);
3259 goto ratecontrol_bailout;
3261 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
3262 bzero(&(&ccb->ccb_h)[1],
3263 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
3265 fprintf(stdout, "%s parameters:\n",
3266 user_settings ? "User" : "Current");
3268 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
3270 goto ratecontrol_bailout;
3272 if (arglist & CAM_ARG_VERBOSE)
3275 if (change_settings) {
3276 int didsettings = 0;
3277 struct ccb_trans_settings_spi *spi = NULL;
3278 struct ccb_trans_settings_ata *ata = NULL;
3279 struct ccb_trans_settings_sata *sata = NULL;
3280 struct ccb_trans_settings_scsi *scsi = NULL;
3282 if (ccb->cts.transport == XPORT_SPI)
3283 spi = &ccb->cts.xport_specific.spi;
3284 if (ccb->cts.transport == XPORT_ATA)
3285 ata = &ccb->cts.xport_specific.ata;
3286 if (ccb->cts.transport == XPORT_SATA)
3287 sata = &ccb->cts.xport_specific.sata;
3288 if (ccb->cts.protocol == PROTO_SCSI)
3289 scsi = &ccb->cts.proto_specific.scsi;
3290 ccb->cts.xport_specific.valid = 0;
3291 ccb->cts.proto_specific.valid = 0;
3292 if (spi && disc_enable != -1) {
3293 spi->valid |= CTS_SPI_VALID_DISC;
3294 if (disc_enable == 0)
3295 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
3297 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
3299 if (scsi && tag_enable != -1) {
3300 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
3301 warnx("HBA does not support tagged queueing, "
3302 "so you cannot modify tag settings");
3304 goto ratecontrol_bailout;
3306 scsi->valid |= CTS_SCSI_VALID_TQ;
3307 if (tag_enable == 0)
3308 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
3310 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
3313 if (spi && offset != -1) {
3314 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3315 warnx("HBA is not capable of changing offset");
3317 goto ratecontrol_bailout;
3319 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
3320 spi->sync_offset = offset;
3323 if (spi && syncrate != -1) {
3324 int prelim_sync_period;
3327 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3328 warnx("HBA is not capable of changing "
3331 goto ratecontrol_bailout;
3333 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
3335 * The sync rate the user gives us is in MHz.
3336 * We need to translate it into KHz for this
3341 * Next, we calculate a "preliminary" sync period
3342 * in tenths of a nanosecond.
3345 prelim_sync_period = 0;
3347 prelim_sync_period = 10000000 / syncrate;
3349 scsi_calc_syncparam(prelim_sync_period);
3350 freq = scsi_calc_syncsrate(spi->sync_period);
3353 if (sata && syncrate != -1) {
3354 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3355 warnx("HBA is not capable of changing "
3358 goto ratecontrol_bailout;
3360 sata->revision = ata_speed2revision(syncrate * 100);
3361 if (sata->revision < 0) {
3362 warnx("Invalid rate %f", syncrate);
3364 goto ratecontrol_bailout;
3366 sata->valid |= CTS_SATA_VALID_REVISION;
3369 if ((ata || sata) && mode != -1) {
3370 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3371 warnx("HBA is not capable of changing "
3374 goto ratecontrol_bailout;
3378 ata->valid |= CTS_ATA_VALID_MODE;
3381 sata->valid |= CTS_SATA_VALID_MODE;
3386 * The bus_width argument goes like this:
3390 * Therefore, if you shift the number of bits given on the
3391 * command line right by 4, you should get the correct
3394 if (spi && bus_width != -1) {
3396 * We might as well validate things here with a
3397 * decipherable error message, rather than what
3398 * will probably be an indecipherable error message
3399 * by the time it gets back to us.
3401 if ((bus_width == 16)
3402 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
3403 warnx("HBA does not support 16 bit bus width");
3405 goto ratecontrol_bailout;
3406 } else if ((bus_width == 32)
3407 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
3408 warnx("HBA does not support 32 bit bus width");
3410 goto ratecontrol_bailout;
3411 } else if ((bus_width != 8)
3412 && (bus_width != 16)
3413 && (bus_width != 32)) {
3414 warnx("Invalid bus width %d", bus_width);
3416 goto ratecontrol_bailout;
3418 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
3419 spi->bus_width = bus_width >> 4;
3422 if (didsettings == 0) {
3423 goto ratecontrol_bailout;
3425 if (!user_settings && (ata || sata)) {
3426 warnx("You can modify only user settings for ATA/SATA");
3428 goto ratecontrol_bailout;
3430 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
3431 if (cam_send_ccb(device, ccb) < 0) {
3432 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
3433 if (arglist & CAM_ARG_VERBOSE) {
3434 cam_error_print(device, ccb, CAM_ESF_ALL,
3435 CAM_EPF_ALL, stderr);
3438 goto ratecontrol_bailout;
3440 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3441 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
3442 if (arglist & CAM_ARG_VERBOSE) {
3443 cam_error_print(device, ccb, CAM_ESF_ALL,
3444 CAM_EPF_ALL, stderr);
3447 goto ratecontrol_bailout;
3451 retval = testunitready(device, retry_count, timeout,
3452 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
3454 * If the TUR didn't succeed, just bail.
3458 fprintf(stderr, "Test Unit Ready failed\n");
3459 goto ratecontrol_bailout;
3462 * If the user wants things quiet, there's no sense in
3463 * getting the transfer settings, if we're not going
3467 goto ratecontrol_bailout;
3468 fprintf(stdout, "New parameters:\n");
3469 retval = get_print_cts(device, user_settings, 0, NULL);
3472 ratecontrol_bailout:
3478 scsiformat(struct cam_device *device, int argc, char **argv,
3479 char *combinedopt, int retry_count, int timeout)
3483 int ycount = 0, quiet = 0;
3484 int error = 0, response = 0, retval = 0;
3485 int use_timeout = 10800 * 1000;
3487 struct format_defect_list_header fh;
3488 u_int8_t *data_ptr = NULL;
3489 u_int32_t dxfer_len = 0;
3491 int num_warnings = 0;
3494 ccb = cam_getccb(device);
3497 warnx("scsiformat: error allocating ccb");
3501 bzero(&(&ccb->ccb_h)[1],
3502 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3504 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3525 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
3526 "following device:\n");
3528 error = scsidoinquiry(device, argc, argv, combinedopt,
3529 retry_count, timeout);
3532 warnx("scsiformat: error sending inquiry");
3533 goto scsiformat_bailout;
3542 fprintf(stdout, "Are you SURE you want to do "
3545 if (fgets(str, sizeof(str), stdin) != NULL) {
3547 if (strncasecmp(str, "yes", 3) == 0)
3549 else if (strncasecmp(str, "no", 2) == 0)
3552 fprintf(stdout, "Please answer"
3553 " \"yes\" or \"no\"\n");
3556 } while (response == 0);
3558 if (response == -1) {
3560 goto scsiformat_bailout;
3565 use_timeout = timeout;
3568 fprintf(stdout, "Current format timeout is %d seconds\n",
3569 use_timeout / 1000);
3573 * If the user hasn't disabled questions and didn't specify a
3574 * timeout on the command line, ask them if they want the current
3578 && (timeout == 0)) {
3580 int new_timeout = 0;
3582 fprintf(stdout, "Enter new timeout in seconds or press\n"
3583 "return to keep the current timeout [%d] ",
3584 use_timeout / 1000);
3586 if (fgets(str, sizeof(str), stdin) != NULL) {
3588 new_timeout = atoi(str);
3591 if (new_timeout != 0) {
3592 use_timeout = new_timeout * 1000;
3593 fprintf(stdout, "Using new timeout value %d\n",
3594 use_timeout / 1000);
3599 * Keep this outside the if block below to silence any unused
3600 * variable warnings.
3602 bzero(&fh, sizeof(fh));
3605 * If we're in immediate mode, we've got to include the format
3608 if (immediate != 0) {
3609 fh.byte2 = FU_DLH_IMMED;
3610 data_ptr = (u_int8_t *)&fh;
3611 dxfer_len = sizeof(fh);
3612 byte2 = FU_FMT_DATA;
3613 } else if (quiet == 0) {
3614 fprintf(stdout, "Formatting...");
3618 scsi_format_unit(&ccb->csio,
3619 /* retries */ retry_count,
3621 /* tag_action */ MSG_SIMPLE_Q_TAG,
3624 /* data_ptr */ data_ptr,
3625 /* dxfer_len */ dxfer_len,
3626 /* sense_len */ SSD_FULL_SIZE,
3627 /* timeout */ use_timeout);
3629 /* Disable freezing the device queue */
3630 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3632 if (arglist & CAM_ARG_ERR_RECOVER)
3633 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3635 if (((retval = cam_send_ccb(device, ccb)) < 0)
3636 || ((immediate == 0)
3637 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
3638 const char errstr[] = "error sending format command";
3645 if (arglist & CAM_ARG_VERBOSE) {
3646 cam_error_print(device, ccb, CAM_ESF_ALL,
3647 CAM_EPF_ALL, stderr);
3650 goto scsiformat_bailout;
3654 * If we ran in non-immediate mode, we already checked for errors
3655 * above and printed out any necessary information. If we're in
3656 * immediate mode, we need to loop through and get status
3657 * information periodically.
3659 if (immediate == 0) {
3661 fprintf(stdout, "Format Complete\n");
3663 goto scsiformat_bailout;
3670 bzero(&(&ccb->ccb_h)[1],
3671 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3674 * There's really no need to do error recovery or
3675 * retries here, since we're just going to sit in a
3676 * loop and wait for the device to finish formatting.
3678 scsi_test_unit_ready(&ccb->csio,
3681 /* tag_action */ MSG_SIMPLE_Q_TAG,
3682 /* sense_len */ SSD_FULL_SIZE,
3683 /* timeout */ 5000);
3685 /* Disable freezing the device queue */
3686 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3688 retval = cam_send_ccb(device, ccb);
3691 * If we get an error from the ioctl, bail out. SCSI
3692 * errors are expected.
3695 warn("error sending CAMIOCOMMAND ioctl");
3696 if (arglist & CAM_ARG_VERBOSE) {
3697 cam_error_print(device, ccb, CAM_ESF_ALL,
3698 CAM_EPF_ALL, stderr);
3701 goto scsiformat_bailout;
3704 status = ccb->ccb_h.status & CAM_STATUS_MASK;
3706 if ((status != CAM_REQ_CMP)
3707 && (status == CAM_SCSI_STATUS_ERROR)
3708 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3709 struct scsi_sense_data *sense;
3710 int error_code, sense_key, asc, ascq;
3712 sense = &ccb->csio.sense_data;
3713 scsi_extract_sense(sense, &error_code, &sense_key,
3717 * According to the SCSI-2 and SCSI-3 specs, a
3718 * drive that is in the middle of a format should
3719 * return NOT READY with an ASC of "logical unit
3720 * not ready, format in progress". The sense key
3721 * specific bytes will then be a progress indicator.
3723 if ((sense_key == SSD_KEY_NOT_READY)
3724 && (asc == 0x04) && (ascq == 0x04)) {
3725 if ((sense->extra_len >= 10)
3726 && ((sense->sense_key_spec[0] &
3727 SSD_SCS_VALID) != 0)
3730 u_int64_t percentage;
3733 &sense->sense_key_spec[1]);
3734 percentage = 10000 * val;
3737 "\rFormatting: %ju.%02u %% "
3739 (uintmax_t)(percentage /
3741 (unsigned)((percentage /
3745 } else if ((quiet == 0)
3746 && (++num_warnings <= 1)) {
3747 warnx("Unexpected SCSI Sense Key "
3748 "Specific value returned "
3750 scsi_sense_print(device, &ccb->csio,
3752 warnx("Unable to print status "
3753 "information, but format will "
3755 warnx("will exit when format is "
3760 warnx("Unexpected SCSI error during format");
3761 cam_error_print(device, ccb, CAM_ESF_ALL,
3762 CAM_EPF_ALL, stderr);
3764 goto scsiformat_bailout;
3767 } else if (status != CAM_REQ_CMP) {
3768 warnx("Unexpected CAM status %#x", status);
3769 if (arglist & CAM_ARG_VERBOSE)
3770 cam_error_print(device, ccb, CAM_ESF_ALL,
3771 CAM_EPF_ALL, stderr);
3773 goto scsiformat_bailout;
3776 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
3779 fprintf(stdout, "\nFormat Complete\n");
3789 scsireportluns(struct cam_device *device, int argc, char **argv,
3790 char *combinedopt, int retry_count, int timeout)
3793 int c, countonly, lunsonly;
3794 struct scsi_report_luns_data *lundata;
3796 uint8_t report_type;
3797 uint32_t list_len, i, j;
3802 report_type = RPL_REPORT_DEFAULT;
3803 ccb = cam_getccb(device);
3806 warnx("%s: error allocating ccb", __func__);
3810 bzero(&(&ccb->ccb_h)[1],
3811 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3816 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3825 if (strcasecmp(optarg, "default") == 0)
3826 report_type = RPL_REPORT_DEFAULT;
3827 else if (strcasecmp(optarg, "wellknown") == 0)
3828 report_type = RPL_REPORT_WELLKNOWN;
3829 else if (strcasecmp(optarg, "all") == 0)
3830 report_type = RPL_REPORT_ALL;
3832 warnx("%s: invalid report type \"%s\"",
3843 if ((countonly != 0)
3844 && (lunsonly != 0)) {
3845 warnx("%s: you can only specify one of -c or -l", __func__);
3850 * According to SPC-4, the allocation length must be at least 16
3851 * bytes -- enough for the header and one LUN.
3853 alloc_len = sizeof(*lundata) + 8;
3857 lundata = malloc(alloc_len);
3859 if (lundata == NULL) {
3860 warn("%s: error mallocing %d bytes", __func__, alloc_len);
3865 scsi_report_luns(&ccb->csio,
3866 /*retries*/ retry_count,
3868 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3869 /*select_report*/ report_type,
3870 /*rpl_buf*/ lundata,
3871 /*alloc_len*/ alloc_len,
3872 /*sense_len*/ SSD_FULL_SIZE,
3873 /*timeout*/ timeout ? timeout : 5000);
3875 /* Disable freezing the device queue */
3876 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3878 if (arglist & CAM_ARG_ERR_RECOVER)
3879 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3881 if (cam_send_ccb(device, ccb) < 0) {
3882 warn("error sending REPORT LUNS command");
3884 if (arglist & CAM_ARG_VERBOSE)
3885 cam_error_print(device, ccb, CAM_ESF_ALL,
3886 CAM_EPF_ALL, stderr);
3892 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3893 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
3899 list_len = scsi_4btoul(lundata->length);
3902 * If we need to list the LUNs, and our allocation
3903 * length was too short, reallocate and retry.
3905 if ((countonly == 0)
3906 && (list_len > (alloc_len - sizeof(*lundata)))) {
3907 alloc_len = list_len + sizeof(*lundata);
3913 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
3914 ((list_len / 8) > 1) ? "s" : "");
3919 for (i = 0; i < (list_len / 8); i++) {
3923 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
3925 fprintf(stdout, ",");
3926 switch (lundata->luns[i].lundata[j] &
3927 RPL_LUNDATA_ATYP_MASK) {
3928 case RPL_LUNDATA_ATYP_PERIPH:
3929 if ((lundata->luns[i].lundata[j] &
3930 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
3931 fprintf(stdout, "%d:",
3932 lundata->luns[i].lundata[j] &
3933 RPL_LUNDATA_PERIPH_BUS_MASK);
3935 && ((lundata->luns[i].lundata[j+2] &
3936 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
3939 fprintf(stdout, "%d",
3940 lundata->luns[i].lundata[j+1]);
3942 case RPL_LUNDATA_ATYP_FLAT: {
3944 tmplun[0] = lundata->luns[i].lundata[j] &
3945 RPL_LUNDATA_FLAT_LUN_MASK;
3946 tmplun[1] = lundata->luns[i].lundata[j+1];
3948 fprintf(stdout, "%d", scsi_2btoul(tmplun));
3952 case RPL_LUNDATA_ATYP_LUN:
3953 fprintf(stdout, "%d:%d:%d",
3954 (lundata->luns[i].lundata[j+1] &
3955 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
3956 lundata->luns[i].lundata[j] &
3957 RPL_LUNDATA_LUN_TARG_MASK,
3958 lundata->luns[i].lundata[j+1] &
3959 RPL_LUNDATA_LUN_LUN_MASK);
3961 case RPL_LUNDATA_ATYP_EXTLUN: {
3962 int field_len, field_len_code, eam_code;
3964 eam_code = lundata->luns[i].lundata[j] &
3965 RPL_LUNDATA_EXT_EAM_MASK;
3966 field_len_code = (lundata->luns[i].lundata[j] &
3967 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
3968 field_len = field_len_code * 2;
3970 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
3971 && (field_len_code == 0x00)) {
3972 fprintf(stdout, "%d",
3973 lundata->luns[i].lundata[j+1]);
3974 } else if ((eam_code ==
3975 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
3976 && (field_len_code == 0x03)) {
3980 * This format takes up all 8 bytes.
3981 * If we aren't starting at offset 0,
3985 fprintf(stdout, "Invalid "
3988 "specified format", j);
3992 bzero(tmp_lun, sizeof(tmp_lun));
3993 bcopy(&lundata->luns[i].lundata[j+1],
3994 &tmp_lun[1], sizeof(tmp_lun) - 1);
3995 fprintf(stdout, "%#jx",
3996 (intmax_t)scsi_8btou64(tmp_lun));
3999 fprintf(stderr, "Unknown Extended LUN"
4000 "Address method %#x, length "
4001 "code %#x", eam_code,
4008 fprintf(stderr, "Unknown LUN address method "
4009 "%#x\n", lundata->luns[i].lundata[0] &
4010 RPL_LUNDATA_ATYP_MASK);
4014 * For the flat addressing method, there are no
4015 * other levels after it.
4020 fprintf(stdout, "\n");
4033 scsireadcapacity(struct cam_device *device, int argc, char **argv,
4034 char *combinedopt, int retry_count, int timeout)
4037 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
4038 struct scsi_read_capacity_data rcap;
4039 struct scsi_read_capacity_data_long rcaplong;
4053 ccb = cam_getccb(device);
4056 warnx("%s: error allocating ccb", __func__);
4060 bzero(&(&ccb->ccb_h)[1],
4061 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
4063 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4090 if ((blocksizeonly != 0)
4091 && (numblocks != 0)) {
4092 warnx("%s: you can only specify one of -b or -N", __func__);
4097 if ((blocksizeonly != 0)
4098 && (sizeonly != 0)) {
4099 warnx("%s: you can only specify one of -b or -s", __func__);
4106 warnx("%s: you can only specify one of -h/-H or -q", __func__);
4112 && (blocksizeonly != 0)) {
4113 warnx("%s: you can only specify one of -h/-H or -b", __func__);
4118 scsi_read_capacity(&ccb->csio,
4119 /*retries*/ retry_count,
4121 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4124 /*timeout*/ timeout ? timeout : 5000);
4126 /* Disable freezing the device queue */
4127 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4129 if (arglist & CAM_ARG_ERR_RECOVER)
4130 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4132 if (cam_send_ccb(device, ccb) < 0) {
4133 warn("error sending READ CAPACITY command");
4135 if (arglist & CAM_ARG_VERBOSE)
4136 cam_error_print(device, ccb, CAM_ESF_ALL,
4137 CAM_EPF_ALL, stderr);
4143 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4144 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4149 maxsector = scsi_4btoul(rcap.addr);
4150 block_len = scsi_4btoul(rcap.length);
4153 * A last block of 2^32-1 means that the true capacity is over 2TB,
4154 * and we need to issue the long READ CAPACITY to get the real
4155 * capacity. Otherwise, we're all set.
4157 if (maxsector != 0xffffffff)
4160 scsi_read_capacity_16(&ccb->csio,
4161 /*retries*/ retry_count,
4163 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4168 /*sense_len*/ SSD_FULL_SIZE,
4169 /*timeout*/ timeout ? timeout : 5000);
4171 /* Disable freezing the device queue */
4172 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4174 if (arglist & CAM_ARG_ERR_RECOVER)
4175 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4177 if (cam_send_ccb(device, ccb) < 0) {
4178 warn("error sending READ CAPACITY (16) command");
4180 if (arglist & CAM_ARG_VERBOSE)
4181 cam_error_print(device, ccb, CAM_ESF_ALL,
4182 CAM_EPF_ALL, stderr);
4188 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4189 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4194 maxsector = scsi_8btou64(rcaplong.addr);
4195 block_len = scsi_4btoul(rcaplong.length);
4198 if (blocksizeonly == 0) {
4200 * Humanize implies !quiet, and also implies numblocks.
4202 if (humanize != 0) {
4207 tmpbytes = (maxsector + 1) * block_len;
4208 ret = humanize_number(tmpstr, sizeof(tmpstr),
4209 tmpbytes, "", HN_AUTOSCALE,
4212 HN_DIVISOR_1000 : 0));
4214 warnx("%s: humanize_number failed!", __func__);
4218 fprintf(stdout, "Device Size: %s%s", tmpstr,
4219 (sizeonly == 0) ? ", " : "\n");
4220 } else if (numblocks != 0) {
4221 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
4222 "Blocks: " : "", (uintmax_t)maxsector + 1,
4223 (sizeonly == 0) ? ", " : "\n");
4225 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
4226 "Last Block: " : "", (uintmax_t)maxsector,
4227 (sizeonly == 0) ? ", " : "\n");
4231 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
4232 "Block Length: " : "", block_len, (quiet == 0) ?
4241 atapm(struct cam_device *device, int argc, char **argv,
4242 char *combinedopt, int retry_count, int timeout)
4250 ccb = cam_getccb(device);
4253 warnx("%s: error allocating ccb", __func__);
4257 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4266 if (strcmp(argv[1], "idle") == 0) {
4268 cmd = ATA_IDLE_IMMEDIATE;
4271 } else if (strcmp(argv[1], "standby") == 0) {
4273 cmd = ATA_STANDBY_IMMEDIATE;
4275 cmd = ATA_STANDBY_CMD;
4282 else if (t <= (240 * 5))
4284 else if (t <= (11 * 30 * 60))
4285 sc = t / (30 * 60) + 241;
4288 cam_fill_ataio(&ccb->ataio,
4291 /*flags*/CAM_DIR_NONE,
4295 timeout ? timeout : 30 * 1000);
4296 ata_28bit_cmd(&ccb->ataio, cmd, 0, 0, sc);
4298 /* Disable freezing the device queue */
4299 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4301 if (arglist & CAM_ARG_ERR_RECOVER)
4302 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4304 if (cam_send_ccb(device, ccb) < 0) {
4305 warn("error sending command");
4307 if (arglist & CAM_ARG_VERBOSE)
4308 cam_error_print(device, ccb, CAM_ESF_ALL,
4309 CAM_EPF_ALL, stderr);
4315 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4316 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4325 #endif /* MINIMALISTIC */
4330 fprintf(verbose ? stdout : stderr,
4331 "usage: camcontrol <command> [device id][generic args][command args]\n"
4332 " camcontrol devlist [-v]\n"
4333 #ifndef MINIMALISTIC
4334 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
4335 " camcontrol tur [dev_id][generic args]\n"
4336 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
4337 " camcontrol identify [dev_id][generic args] [-v]\n"
4338 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
4339 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
4341 " camcontrol start [dev_id][generic args]\n"
4342 " camcontrol stop [dev_id][generic args]\n"
4343 " camcontrol load [dev_id][generic args]\n"
4344 " camcontrol eject [dev_id][generic args]\n"
4345 #endif /* MINIMALISTIC */
4346 " camcontrol rescan <all | bus[:target:lun]>\n"
4347 " camcontrol reset <all | bus[:target:lun]>\n"
4348 #ifndef MINIMALISTIC
4349 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
4350 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
4351 " [-P pagectl][-e | -b][-d]\n"
4352 " camcontrol cmd [dev_id][generic args]\n"
4353 " <-a cmd [args] | -c cmd [args]>\n"
4354 " [-i len fmt|-o len fmt [args]] [-r fmt]\n"
4355 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
4356 " <all|bus[:target[:lun]]|off>\n"
4357 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
4358 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
4359 " [-D <enable|disable>][-M mode][-O offset]\n"
4360 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
4361 " [-U][-W bus_width]\n"
4362 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
4363 " camcontrol idle [dev_id][generic args][-t time]\n"
4364 " camcontrol standby [dev_id][generic args][-t time]\n"
4365 " camcontrol sleep [dev_id][generic args]\n"
4366 #endif /* MINIMALISTIC */
4367 " camcontrol help\n");
4370 #ifndef MINIMALISTIC
4372 "Specify one of the following options:\n"
4373 "devlist list all CAM devices\n"
4374 "periphlist list all CAM peripheral drivers attached to a device\n"
4375 "tur send a test unit ready to the named device\n"
4376 "inquiry send a SCSI inquiry command to the named device\n"
4377 "identify send a ATA identify command to the named device\n"
4378 "reportluns send a SCSI report luns command to the device\n"
4379 "readcap send a SCSI read capacity command to the device\n"
4380 "start send a Start Unit command to the device\n"
4381 "stop send a Stop Unit command to the device\n"
4382 "load send a Start Unit command to the device with the load bit set\n"
4383 "eject send a Stop Unit command to the device with the eject bit set\n"
4384 "rescan rescan all busses, the given bus, or bus:target:lun\n"
4385 "reset reset all busses, the given bus, or bus:target:lun\n"
4386 "defects read the defect list of the specified device\n"
4387 "modepage display or edit (-e) the given mode page\n"
4388 "cmd send the given scsi command, may need -i or -o as well\n"
4389 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
4390 "tags report or set the number of transaction slots for a device\n"
4391 "negotiate report or set device negotiation parameters\n"
4392 "format send the SCSI FORMAT UNIT command to the named device\n"
4393 "idle send the ATA IDLE command to the named device\n"
4394 "standby send the ATA STANDBY command to the named device\n"
4395 "sleep send the ATA SLEEP command to the named device\n"
4396 "help this message\n"
4397 "Device Identifiers:\n"
4398 "bus:target specify the bus and target, lun defaults to 0\n"
4399 "bus:target:lun specify the bus, target and lun\n"
4400 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
4401 "Generic arguments:\n"
4402 "-v be verbose, print out sense information\n"
4403 "-t timeout command timeout in seconds, overrides default timeout\n"
4404 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
4405 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
4406 "-E have the kernel attempt to perform SCSI error recovery\n"
4407 "-C count specify the SCSI command retry count (needs -E to work)\n"
4408 "modepage arguments:\n"
4409 "-l list all available mode pages\n"
4410 "-m page specify the mode page to view or edit\n"
4411 "-e edit the specified mode page\n"
4412 "-b force view to binary mode\n"
4413 "-d disable block descriptors for mode sense\n"
4414 "-P pgctl page control field 0-3\n"
4415 "defects arguments:\n"
4416 "-f format specify defect list format (block, bfi or phys)\n"
4417 "-G get the grown defect list\n"
4418 "-P get the permanant defect list\n"
4419 "inquiry arguments:\n"
4420 "-D get the standard inquiry data\n"
4421 "-S get the serial number\n"
4422 "-R get the transfer rate, etc.\n"
4423 "reportluns arguments:\n"
4424 "-c only report a count of available LUNs\n"
4425 "-l only print out luns, and not a count\n"
4426 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
4427 "readcap arguments\n"
4428 "-b only report the blocksize\n"
4429 "-h human readable device size, base 2\n"
4430 "-H human readable device size, base 10\n"
4431 "-N print the number of blocks instead of last block\n"
4432 "-q quiet, print numbers only\n"
4433 "-s only report the last block/device size\n"
4435 "-c cdb [args] specify the SCSI CDB\n"
4436 "-i len fmt specify input data and input data format\n"
4437 "-o len fmt [args] specify output data and output data fmt\n"
4438 "debug arguments:\n"
4439 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
4440 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
4441 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
4442 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
4444 "-N tags specify the number of tags to use for this device\n"
4445 "-q be quiet, don't report the number of tags\n"
4446 "-v report a number of tag-related parameters\n"
4447 "negotiate arguments:\n"
4448 "-a send a test unit ready after negotiation\n"
4449 "-c report/set current negotiation settings\n"
4450 "-D <arg> \"enable\" or \"disable\" disconnection\n"
4451 "-M mode set ATA mode\n"
4452 "-O offset set command delay offset\n"
4453 "-q be quiet, don't report anything\n"
4454 "-R syncrate synchronization rate in MHz\n"
4455 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
4456 "-U report/set user negotiation settings\n"
4457 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
4458 "-v also print a Path Inquiry CCB for the controller\n"
4459 "format arguments:\n"
4460 "-q be quiet, don't print status messages\n"
4461 "-r run in report only mode\n"
4462 "-w don't send immediate format command\n"
4463 "-y don't ask any questions\n"
4464 "idle/standby arguments:\n"
4465 "-t <arg> number of seconds before respective state.\n");
4466 #endif /* MINIMALISTIC */
4470 main(int argc, char **argv)
4473 char *device = NULL;
4475 struct cam_device *cam_dev = NULL;
4476 int timeout = 0, retry_count = 1;
4477 camcontrol_optret optreturn;
4479 const char *mainopt = "C:En:t:u:v";
4480 const char *subopt = NULL;
4481 char combinedopt[256];
4482 int error = 0, optstart = 2;
4484 #ifndef MINIMALISTIC
4485 int bus, target, lun;
4486 #endif /* MINIMALISTIC */
4488 cmdlist = CAM_CMD_NONE;
4489 arglist = CAM_ARG_NONE;
4497 * Get the base option.
4499 optreturn = getoption(argv[1], &cmdlist, &arglist, &subopt);
4501 if (optreturn == CC_OR_AMBIGUOUS) {
4502 warnx("ambiguous option %s", argv[1]);
4505 } else if (optreturn == CC_OR_NOT_FOUND) {
4506 warnx("option %s not found", argv[1]);
4512 * Ahh, getopt(3) is a pain.
4514 * This is a gross hack. There really aren't many other good
4515 * options (excuse the pun) for parsing options in a situation like
4516 * this. getopt is kinda braindead, so you end up having to run
4517 * through the options twice, and give each invocation of getopt
4518 * the option string for the other invocation.
4520 * You would think that you could just have two groups of options.
4521 * The first group would get parsed by the first invocation of
4522 * getopt, and the second group would get parsed by the second
4523 * invocation of getopt. It doesn't quite work out that way. When
4524 * the first invocation of getopt finishes, it leaves optind pointing
4525 * to the argument _after_ the first argument in the second group.
4526 * So when the second invocation of getopt comes around, it doesn't
4527 * recognize the first argument it gets and then bails out.
4529 * A nice alternative would be to have a flag for getopt that says
4530 * "just keep parsing arguments even when you encounter an unknown
4531 * argument", but there isn't one. So there's no real clean way to
4532 * easily parse two sets of arguments without having one invocation
4533 * of getopt know about the other.
4535 * Without this hack, the first invocation of getopt would work as
4536 * long as the generic arguments are first, but the second invocation
4537 * (in the subfunction) would fail in one of two ways. In the case
4538 * where you don't set optreset, it would fail because optind may be
4539 * pointing to the argument after the one it should be pointing at.
4540 * In the case where you do set optreset, and reset optind, it would
4541 * fail because getopt would run into the first set of options, which
4542 * it doesn't understand.
4544 * All of this would "sort of" work if you could somehow figure out
4545 * whether optind had been incremented one option too far. The
4546 * mechanics of that, however, are more daunting than just giving
4547 * both invocations all of the expect options for either invocation.
4549 * Needless to say, I wouldn't mind if someone invented a better
4550 * (non-GPL!) command line parsing interface than getopt. I
4551 * wouldn't mind if someone added more knobs to getopt to make it
4552 * work better. Who knows, I may talk myself into doing it someday,
4553 * if the standards weenies let me. As it is, it just leads to
4554 * hackery like this and causes people to avoid it in some cases.
4556 * KDM, September 8th, 1998
4559 sprintf(combinedopt, "%s%s", mainopt, subopt);
4561 sprintf(combinedopt, "%s", mainopt);
4564 * For these options we do not parse optional device arguments and
4565 * we do not open a passthrough device.
4567 if ((cmdlist == CAM_CMD_RESCAN)
4568 || (cmdlist == CAM_CMD_RESET)
4569 || (cmdlist == CAM_CMD_DEVTREE)
4570 || (cmdlist == CAM_CMD_USAGE)
4571 || (cmdlist == CAM_CMD_DEBUG))
4574 #ifndef MINIMALISTIC
4576 && (argc > 2 && argv[2][0] != '-')) {
4581 * First catch people who try to do things like:
4582 * camcontrol tur /dev/da0
4583 * camcontrol doesn't take device nodes as arguments.
4585 if (argv[2][0] == '/') {
4586 warnx("%s is not a valid device identifier", argv[2]);
4587 errx(1, "please read the camcontrol(8) man page");
4588 } else if (isdigit(argv[2][0])) {
4589 /* device specified as bus:target[:lun] */
4590 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
4592 errx(1, "numeric device specification must "
4593 "be either bus:target, or "
4595 /* default to 0 if lun was not specified */
4596 if ((arglist & CAM_ARG_LUN) == 0) {
4598 arglist |= CAM_ARG_LUN;
4602 if (cam_get_device(argv[2], name, sizeof name, &unit)
4604 errx(1, "%s", cam_errbuf);
4605 device = strdup(name);
4606 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
4610 #endif /* MINIMALISTIC */
4612 * Start getopt processing at argv[2/3], since we've already
4613 * accepted argv[1..2] as the command name, and as a possible
4619 * Now we run through the argument list looking for generic
4620 * options, and ignoring options that possibly belong to
4623 while ((c = getopt(argc, argv, combinedopt))!= -1){
4626 retry_count = strtol(optarg, NULL, 0);
4627 if (retry_count < 0)
4628 errx(1, "retry count %d is < 0",
4630 arglist |= CAM_ARG_RETRIES;
4633 arglist |= CAM_ARG_ERR_RECOVER;
4636 arglist |= CAM_ARG_DEVICE;
4638 while (isspace(*tstr) && (*tstr != '\0'))
4640 device = (char *)strdup(tstr);
4643 timeout = strtol(optarg, NULL, 0);
4645 errx(1, "invalid timeout %d", timeout);
4646 /* Convert the timeout from seconds to ms */
4648 arglist |= CAM_ARG_TIMEOUT;
4651 arglist |= CAM_ARG_UNIT;
4652 unit = strtol(optarg, NULL, 0);
4655 arglist |= CAM_ARG_VERBOSE;
4662 #ifndef MINIMALISTIC
4664 * For most commands we'll want to open the passthrough device
4665 * associated with the specified device. In the case of the rescan
4666 * commands, we don't use a passthrough device at all, just the
4667 * transport layer device.
4670 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
4671 && (((arglist & CAM_ARG_DEVICE) == 0)
4672 || ((arglist & CAM_ARG_UNIT) == 0))) {
4673 errx(1, "subcommand \"%s\" requires a valid device "
4674 "identifier", argv[1]);
4677 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
4678 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
4679 cam_open_spec_device(device,unit,O_RDWR,NULL)))
4681 errx(1,"%s", cam_errbuf);
4683 #endif /* MINIMALISTIC */
4686 * Reset optind to 2, and reset getopt, so these routines can parse
4687 * the arguments again.
4693 #ifndef MINIMALISTIC
4694 case CAM_CMD_DEVLIST:
4695 error = getdevlist(cam_dev);
4697 #endif /* MINIMALISTIC */
4698 case CAM_CMD_DEVTREE:
4699 error = getdevtree();
4701 #ifndef MINIMALISTIC
4703 error = testunitready(cam_dev, retry_count, timeout, 0);
4705 case CAM_CMD_INQUIRY:
4706 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
4707 retry_count, timeout);
4709 case CAM_CMD_IDENTIFY:
4710 error = ataidentify(cam_dev, retry_count, timeout);
4712 case CAM_CMD_STARTSTOP:
4713 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
4714 arglist & CAM_ARG_EJECT, retry_count,
4717 #endif /* MINIMALISTIC */
4718 case CAM_CMD_RESCAN:
4719 error = dorescan_or_reset(argc, argv, 1);
4722 error = dorescan_or_reset(argc, argv, 0);
4724 #ifndef MINIMALISTIC
4725 case CAM_CMD_READ_DEFECTS:
4726 error = readdefects(cam_dev, argc, argv, combinedopt,
4727 retry_count, timeout);
4729 case CAM_CMD_MODE_PAGE:
4730 modepage(cam_dev, argc, argv, combinedopt,
4731 retry_count, timeout);
4733 case CAM_CMD_SCSI_CMD:
4734 error = scsicmd(cam_dev, argc, argv, combinedopt,
4735 retry_count, timeout);
4738 error = camdebug(argc, argv, combinedopt);
4741 error = tagcontrol(cam_dev, argc, argv, combinedopt);
4744 error = ratecontrol(cam_dev, retry_count, timeout,
4745 argc, argv, combinedopt);
4747 case CAM_CMD_FORMAT:
4748 error = scsiformat(cam_dev, argc, argv,
4749 combinedopt, retry_count, timeout);
4751 case CAM_CMD_REPORTLUNS:
4752 error = scsireportluns(cam_dev, argc, argv,
4753 combinedopt, retry_count,
4756 case CAM_CMD_READCAP:
4757 error = scsireadcapacity(cam_dev, argc, argv,
4758 combinedopt, retry_count,
4762 case CAM_CMD_STANDBY:
4764 error = atapm(cam_dev, argc, argv,
4765 combinedopt, retry_count,
4768 #endif /* MINIMALISTIC */
4778 if (cam_dev != NULL)
4779 cam_close_device(cam_dev);