2 * Copyright (c) 1997-2007 Kenneth D. Merry
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/ioctl.h>
33 #include <sys/stdint.h>
34 #include <sys/types.h>
35 #include <sys/endian.h>
47 #include <cam/cam_debug.h>
48 #include <cam/cam_ccb.h>
49 #include <cam/scsi/scsi_all.h>
50 #include <cam/scsi/scsi_da.h>
51 #include <cam/scsi/scsi_pass.h>
52 #include <cam/scsi/scsi_message.h>
53 #include <cam/ata/ata_all.h>
55 #include "camcontrol.h"
58 CAM_CMD_NONE = 0x00000000,
59 CAM_CMD_DEVLIST = 0x00000001,
60 CAM_CMD_TUR = 0x00000002,
61 CAM_CMD_INQUIRY = 0x00000003,
62 CAM_CMD_STARTSTOP = 0x00000004,
63 CAM_CMD_RESCAN = 0x00000005,
64 CAM_CMD_READ_DEFECTS = 0x00000006,
65 CAM_CMD_MODE_PAGE = 0x00000007,
66 CAM_CMD_SCSI_CMD = 0x00000008,
67 CAM_CMD_DEVTREE = 0x00000009,
68 CAM_CMD_USAGE = 0x0000000a,
69 CAM_CMD_DEBUG = 0x0000000b,
70 CAM_CMD_RESET = 0x0000000c,
71 CAM_CMD_FORMAT = 0x0000000d,
72 CAM_CMD_TAG = 0x0000000e,
73 CAM_CMD_RATE = 0x0000000f,
74 CAM_CMD_DETACH = 0x00000010,
75 CAM_CMD_REPORTLUNS = 0x00000011,
76 CAM_CMD_READCAP = 0x00000012,
77 CAM_CMD_IDENTIFY = 0x00000013,
78 CAM_CMD_IDLE = 0x00000014,
79 CAM_CMD_STANDBY = 0x00000015,
80 CAM_CMD_SLEEP = 0x00000016
84 CAM_ARG_NONE = 0x00000000,
85 CAM_ARG_VERBOSE = 0x00000001,
86 CAM_ARG_DEVICE = 0x00000002,
87 CAM_ARG_BUS = 0x00000004,
88 CAM_ARG_TARGET = 0x00000008,
89 CAM_ARG_LUN = 0x00000010,
90 CAM_ARG_EJECT = 0x00000020,
91 CAM_ARG_UNIT = 0x00000040,
92 CAM_ARG_FORMAT_BLOCK = 0x00000080,
93 CAM_ARG_FORMAT_BFI = 0x00000100,
94 CAM_ARG_FORMAT_PHYS = 0x00000200,
95 CAM_ARG_PLIST = 0x00000400,
96 CAM_ARG_GLIST = 0x00000800,
97 CAM_ARG_GET_SERIAL = 0x00001000,
98 CAM_ARG_GET_STDINQ = 0x00002000,
99 CAM_ARG_GET_XFERRATE = 0x00004000,
100 CAM_ARG_INQ_MASK = 0x00007000,
101 CAM_ARG_MODE_EDIT = 0x00008000,
102 CAM_ARG_PAGE_CNTL = 0x00010000,
103 CAM_ARG_TIMEOUT = 0x00020000,
104 CAM_ARG_CMD_IN = 0x00040000,
105 CAM_ARG_CMD_OUT = 0x00080000,
106 CAM_ARG_DBD = 0x00100000,
107 CAM_ARG_ERR_RECOVER = 0x00200000,
108 CAM_ARG_RETRIES = 0x00400000,
109 CAM_ARG_START_UNIT = 0x00800000,
110 CAM_ARG_DEBUG_INFO = 0x01000000,
111 CAM_ARG_DEBUG_TRACE = 0x02000000,
112 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
113 CAM_ARG_DEBUG_CDB = 0x08000000,
114 CAM_ARG_DEBUG_XPT = 0x10000000,
115 CAM_ARG_DEBUG_PERIPH = 0x20000000,
118 struct camcontrol_opts {
126 static const char scsicmd_opts[] = "a:c:dfi:o:r";
127 static const char readdefect_opts[] = "f:GP";
128 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
131 struct camcontrol_opts option_table[] = {
133 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
134 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
135 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
136 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
137 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
138 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
139 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
140 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
141 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
142 #endif /* MINIMALISTIC */
143 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
144 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
146 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
147 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
148 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
149 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
150 #endif /* MINIMALISTIC */
151 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, NULL},
153 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
154 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
155 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
156 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
157 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
158 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXc"},
159 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
160 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
161 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
162 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
163 #endif /* MINIMALISTIC */
164 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
165 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
166 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
180 camcontrol_optret getoption(char *arg, cam_cmdmask *cmdnum, cam_argmask *argnum,
181 const char **subopt);
183 static int getdevlist(struct cam_device *device);
184 #endif /* MINIMALISTIC */
185 static int getdevtree(void);
187 static int testunitready(struct cam_device *device, int retry_count,
188 int timeout, int quiet);
189 static int scsistart(struct cam_device *device, int startstop, int loadeject,
190 int retry_count, int timeout);
191 static int scsidoinquiry(struct cam_device *device, int argc, char **argv,
192 char *combinedopt, int retry_count, int timeout);
193 static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
194 static int scsiserial(struct cam_device *device, int retry_count, int timeout);
195 static int camxferrate(struct cam_device *device);
196 #endif /* MINIMALISTIC */
197 static int parse_btl(char *tstr, int *bus, int *target, int *lun,
198 cam_argmask *arglst);
199 static int dorescan_or_reset(int argc, char **argv, int rescan);
200 static int rescan_or_reset_bus(int bus, int rescan);
201 static int scanlun_or_reset_dev(int bus, int target, int lun, int scan);
203 static int readdefects(struct cam_device *device, int argc, char **argv,
204 char *combinedopt, int retry_count, int timeout);
205 static void modepage(struct cam_device *device, int argc, char **argv,
206 char *combinedopt, int retry_count, int timeout);
207 static int scsicmd(struct cam_device *device, int argc, char **argv,
208 char *combinedopt, int retry_count, int timeout);
209 static int tagcontrol(struct cam_device *device, int argc, char **argv,
211 static void cts_print(struct cam_device *device,
212 struct ccb_trans_settings *cts);
213 static void cpi_print(struct ccb_pathinq *cpi);
214 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
215 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
216 static int get_print_cts(struct cam_device *device, int user_settings,
217 int quiet, struct ccb_trans_settings *cts);
218 static int ratecontrol(struct cam_device *device, int retry_count,
219 int timeout, int argc, char **argv, char *combinedopt);
220 static int scsiformat(struct cam_device *device, int argc, char **argv,
221 char *combinedopt, int retry_count, int timeout);
222 static int scsireportluns(struct cam_device *device, int argc, char **argv,
223 char *combinedopt, int retry_count, int timeout);
224 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
225 char *combinedopt, int retry_count, int timeout);
226 static int atapm(struct cam_device *device, int argc, char **argv,
227 char *combinedopt, int retry_count, int timeout);
228 #endif /* MINIMALISTIC */
230 #define min(a,b) (((a)<(b))?(a):(b))
233 #define max(a,b) (((a)>(b))?(a):(b))
237 getoption(char *arg, cam_cmdmask *cmdnum, cam_argmask *argnum,
240 struct camcontrol_opts *opts;
243 for (opts = option_table; (opts != NULL) && (opts->optname != NULL);
245 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
246 *cmdnum = opts->cmdnum;
247 *argnum = opts->argnum;
248 *subopt = opts->subopt;
249 if (++num_matches > 1)
250 return(CC_OR_AMBIGUOUS);
257 return(CC_OR_NOT_FOUND);
262 getdevlist(struct cam_device *device)
268 ccb = cam_getccb(device);
270 ccb->ccb_h.func_code = XPT_GDEVLIST;
271 ccb->ccb_h.flags = CAM_DIR_NONE;
272 ccb->ccb_h.retry_count = 1;
274 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
275 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
276 if (cam_send_ccb(device, ccb) < 0) {
277 perror("error getting device list");
284 switch (ccb->cgdl.status) {
285 case CAM_GDEVLIST_MORE_DEVS:
286 strcpy(status, "MORE");
288 case CAM_GDEVLIST_LAST_DEVICE:
289 strcpy(status, "LAST");
291 case CAM_GDEVLIST_LIST_CHANGED:
292 strcpy(status, "CHANGED");
294 case CAM_GDEVLIST_ERROR:
295 strcpy(status, "ERROR");
300 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
301 ccb->cgdl.periph_name,
302 ccb->cgdl.unit_number,
303 ccb->cgdl.generation,
308 * If the list has changed, we need to start over from the
311 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
319 #endif /* MINIMALISTIC */
331 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
332 warn("couldn't open %s", XPT_DEVICE);
336 bzero(&ccb, sizeof(union ccb));
338 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
339 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
340 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
342 ccb.ccb_h.func_code = XPT_DEV_MATCH;
343 bufsize = sizeof(struct dev_match_result) * 100;
344 ccb.cdm.match_buf_len = bufsize;
345 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
346 if (ccb.cdm.matches == NULL) {
347 warnx("can't malloc memory for matches");
351 ccb.cdm.num_matches = 0;
354 * We fetch all nodes, since we display most of them in the default
355 * case, and all in the verbose case.
357 ccb.cdm.num_patterns = 0;
358 ccb.cdm.pattern_buf_len = 0;
361 * We do the ioctl multiple times if necessary, in case there are
362 * more than 100 nodes in the EDT.
365 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
366 warn("error sending CAMIOCOMMAND ioctl");
371 if ((ccb.ccb_h.status != CAM_REQ_CMP)
372 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
373 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
374 warnx("got CAM error %#x, CDM error %d\n",
375 ccb.ccb_h.status, ccb.cdm.status);
380 for (i = 0; i < ccb.cdm.num_matches; i++) {
381 switch (ccb.cdm.matches[i].type) {
382 case DEV_MATCH_BUS: {
383 struct bus_match_result *bus_result;
386 * Only print the bus information if the
387 * user turns on the verbose flag.
389 if ((arglist & CAM_ARG_VERBOSE) == 0)
393 &ccb.cdm.matches[i].result.bus_result;
396 fprintf(stdout, ")\n");
400 fprintf(stdout, "scbus%d on %s%d bus %d:\n",
402 bus_result->dev_name,
403 bus_result->unit_number,
407 case DEV_MATCH_DEVICE: {
408 struct device_match_result *dev_result;
409 char vendor[16], product[48], revision[16];
413 &ccb.cdm.matches[i].result.device_result;
415 if ((dev_result->flags
416 & DEV_RESULT_UNCONFIGURED)
417 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
423 if (dev_result->protocol == PROTO_SCSI) {
424 cam_strvis(vendor, dev_result->inq_data.vendor,
425 sizeof(dev_result->inq_data.vendor),
428 dev_result->inq_data.product,
429 sizeof(dev_result->inq_data.product),
432 dev_result->inq_data.revision,
433 sizeof(dev_result->inq_data.revision),
435 sprintf(tmpstr, "<%s %s %s>", vendor, product,
437 } else if (dev_result->protocol == PROTO_ATA ||
438 dev_result->protocol == PROTO_SATAPM) {
440 dev_result->ident_data.model,
441 sizeof(dev_result->ident_data.model),
444 dev_result->ident_data.revision,
445 sizeof(dev_result->ident_data.revision),
447 sprintf(tmpstr, "<%s %s>", product,
450 sprintf(tmpstr, "<>");
453 fprintf(stdout, ")\n");
457 fprintf(stdout, "%-33s at scbus%d "
458 "target %d lun %d (",
461 dev_result->target_id,
462 dev_result->target_lun);
468 case DEV_MATCH_PERIPH: {
469 struct periph_match_result *periph_result;
472 &ccb.cdm.matches[i].result.periph_result;
474 if (skip_device != 0)
478 fprintf(stdout, ",");
480 fprintf(stdout, "%s%d",
481 periph_result->periph_name,
482 periph_result->unit_number);
488 fprintf(stdout, "unknown match type\n");
493 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
494 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
497 fprintf(stdout, ")\n");
506 testunitready(struct cam_device *device, int retry_count, int timeout,
512 ccb = cam_getccb(device);
514 scsi_test_unit_ready(&ccb->csio,
515 /* retries */ retry_count,
517 /* tag_action */ MSG_SIMPLE_Q_TAG,
518 /* sense_len */ SSD_FULL_SIZE,
519 /* timeout */ timeout ? timeout : 5000);
521 /* Disable freezing the device queue */
522 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
524 if (arglist & CAM_ARG_ERR_RECOVER)
525 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
527 if (cam_send_ccb(device, ccb) < 0) {
529 perror("error sending test unit ready");
531 if (arglist & CAM_ARG_VERBOSE) {
532 cam_error_print(device, ccb, CAM_ESF_ALL,
533 CAM_EPF_ALL, stderr);
540 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
542 fprintf(stdout, "Unit is ready\n");
545 fprintf(stdout, "Unit is not ready\n");
548 if (arglist & CAM_ARG_VERBOSE) {
549 cam_error_print(device, ccb, CAM_ESF_ALL,
550 CAM_EPF_ALL, stderr);
560 scsistart(struct cam_device *device, int startstop, int loadeject,
561 int retry_count, int timeout)
566 ccb = cam_getccb(device);
569 * If we're stopping, send an ordered tag so the drive in question
570 * will finish any previously queued writes before stopping. If
571 * the device isn't capable of tagged queueing, or if tagged
572 * queueing is turned off, the tag action is a no-op.
574 scsi_start_stop(&ccb->csio,
575 /* retries */ retry_count,
577 /* tag_action */ startstop ? MSG_SIMPLE_Q_TAG :
579 /* start/stop */ startstop,
580 /* load_eject */ loadeject,
582 /* sense_len */ SSD_FULL_SIZE,
583 /* timeout */ timeout ? timeout : 120000);
585 /* Disable freezing the device queue */
586 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
588 if (arglist & CAM_ARG_ERR_RECOVER)
589 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
591 if (cam_send_ccb(device, ccb) < 0) {
592 perror("error sending start unit");
594 if (arglist & CAM_ARG_VERBOSE) {
595 cam_error_print(device, ccb, CAM_ESF_ALL,
596 CAM_EPF_ALL, stderr);
603 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
605 fprintf(stdout, "Unit started successfully");
607 fprintf(stdout,", Media loaded\n");
609 fprintf(stdout,"\n");
611 fprintf(stdout, "Unit stopped successfully");
613 fprintf(stdout, ", Media ejected\n");
615 fprintf(stdout, "\n");
621 "Error received from start unit command\n");
624 "Error received from stop unit command\n");
626 if (arglist & CAM_ARG_VERBOSE) {
627 cam_error_print(device, ccb, CAM_ESF_ALL,
628 CAM_EPF_ALL, stderr);
638 scsidoinquiry(struct cam_device *device, int argc, char **argv,
639 char *combinedopt, int retry_count, int timeout)
644 while ((c = getopt(argc, argv, combinedopt)) != -1) {
647 arglist |= CAM_ARG_GET_STDINQ;
650 arglist |= CAM_ARG_GET_XFERRATE;
653 arglist |= CAM_ARG_GET_SERIAL;
661 * If the user didn't specify any inquiry options, he wants all of
664 if ((arglist & CAM_ARG_INQ_MASK) == 0)
665 arglist |= CAM_ARG_INQ_MASK;
667 if (arglist & CAM_ARG_GET_STDINQ)
668 error = scsiinquiry(device, retry_count, timeout);
673 if (arglist & CAM_ARG_GET_SERIAL)
674 scsiserial(device, retry_count, timeout);
679 if (arglist & CAM_ARG_GET_XFERRATE)
680 error = camxferrate(device);
686 scsiinquiry(struct cam_device *device, int retry_count, int timeout)
689 struct scsi_inquiry_data *inq_buf;
692 ccb = cam_getccb(device);
695 warnx("couldn't allocate CCB");
699 /* cam_getccb cleans up the header, caller has to zero the payload */
700 bzero(&(&ccb->ccb_h)[1],
701 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
703 inq_buf = (struct scsi_inquiry_data *)malloc(
704 sizeof(struct scsi_inquiry_data));
706 if (inq_buf == NULL) {
708 warnx("can't malloc memory for inquiry\n");
711 bzero(inq_buf, sizeof(*inq_buf));
714 * Note that although the size of the inquiry buffer is the full
715 * 256 bytes specified in the SCSI spec, we only tell the device
716 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
717 * two reasons for this:
719 * - The SCSI spec says that when a length field is only 1 byte,
720 * a value of 0 will be interpreted as 256. Therefore
721 * scsi_inquiry() will convert an inq_len (which is passed in as
722 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
723 * to 0. Evidently, very few devices meet the spec in that
724 * regard. Some devices, like many Seagate disks, take the 0 as
725 * 0, and don't return any data. One Pioneer DVD-R drive
726 * returns more data than the command asked for.
728 * So, since there are numerous devices that just don't work
729 * right with the full inquiry size, we don't send the full size.
731 * - The second reason not to use the full inquiry data length is
732 * that we don't need it here. The only reason we issue a
733 * standard inquiry is to get the vendor name, device name,
734 * and revision so scsi_print_inquiry() can print them.
736 * If, at some point in the future, more inquiry data is needed for
737 * some reason, this code should use a procedure similar to the
738 * probe code. i.e., issue a short inquiry, and determine from
739 * the additional length passed back from the device how much
740 * inquiry data the device supports. Once the amount the device
741 * supports is determined, issue an inquiry for that amount and no
746 scsi_inquiry(&ccb->csio,
747 /* retries */ retry_count,
749 /* tag_action */ MSG_SIMPLE_Q_TAG,
750 /* inq_buf */ (u_int8_t *)inq_buf,
751 /* inq_len */ SHORT_INQUIRY_LENGTH,
754 /* sense_len */ SSD_FULL_SIZE,
755 /* timeout */ timeout ? timeout : 5000);
757 /* Disable freezing the device queue */
758 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
760 if (arglist & CAM_ARG_ERR_RECOVER)
761 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
763 if (cam_send_ccb(device, ccb) < 0) {
764 perror("error sending SCSI inquiry");
766 if (arglist & CAM_ARG_VERBOSE) {
767 cam_error_print(device, ccb, CAM_ESF_ALL,
768 CAM_EPF_ALL, stderr);
775 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
778 if (arglist & CAM_ARG_VERBOSE) {
779 cam_error_print(device, ccb, CAM_ESF_ALL,
780 CAM_EPF_ALL, stderr);
791 fprintf(stdout, "%s%d: ", device->device_name,
792 device->dev_unit_num);
793 scsi_print_inquiry(inq_buf);
801 scsiserial(struct cam_device *device, int retry_count, int timeout)
804 struct scsi_vpd_unit_serial_number *serial_buf;
805 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
808 ccb = cam_getccb(device);
811 warnx("couldn't allocate CCB");
815 /* cam_getccb cleans up the header, caller has to zero the payload */
816 bzero(&(&ccb->ccb_h)[1],
817 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
819 serial_buf = (struct scsi_vpd_unit_serial_number *)
820 malloc(sizeof(*serial_buf));
822 if (serial_buf == NULL) {
824 warnx("can't malloc memory for serial number");
828 scsi_inquiry(&ccb->csio,
829 /*retries*/ retry_count,
831 /* tag_action */ MSG_SIMPLE_Q_TAG,
832 /* inq_buf */ (u_int8_t *)serial_buf,
833 /* inq_len */ sizeof(*serial_buf),
835 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
836 /* sense_len */ SSD_FULL_SIZE,
837 /* timeout */ timeout ? timeout : 5000);
839 /* Disable freezing the device queue */
840 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
842 if (arglist & CAM_ARG_ERR_RECOVER)
843 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
845 if (cam_send_ccb(device, ccb) < 0) {
846 warn("error getting serial number");
848 if (arglist & CAM_ARG_VERBOSE) {
849 cam_error_print(device, ccb, CAM_ESF_ALL,
850 CAM_EPF_ALL, stderr);
858 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
861 if (arglist & CAM_ARG_VERBOSE) {
862 cam_error_print(device, ccb, CAM_ESF_ALL,
863 CAM_EPF_ALL, stderr);
874 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
875 serial_num[serial_buf->length] = '\0';
877 if ((arglist & CAM_ARG_GET_STDINQ)
878 || (arglist & CAM_ARG_GET_XFERRATE))
879 fprintf(stdout, "%s%d: Serial Number ",
880 device->device_name, device->dev_unit_num);
882 fprintf(stdout, "%.60s\n", serial_num);
890 camxferrate(struct cam_device *device)
892 struct ccb_pathinq cpi;
899 if ((retval = get_cpi(device, &cpi)) != 0)
902 ccb = cam_getccb(device);
905 warnx("couldn't allocate CCB");
909 bzero(&(&ccb->ccb_h)[1],
910 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
912 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
913 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
915 if (((retval = cam_send_ccb(device, ccb)) < 0)
916 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
917 const char error_string[] = "error getting transfer settings";
924 if (arglist & CAM_ARG_VERBOSE)
925 cam_error_print(device, ccb, CAM_ESF_ALL,
926 CAM_EPF_ALL, stderr);
930 goto xferrate_bailout;
934 speed = cpi.base_transfer_speed;
936 if (ccb->cts.transport == XPORT_SPI) {
937 struct ccb_trans_settings_spi *spi =
938 &ccb->cts.xport_specific.spi;
940 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
941 freq = scsi_calc_syncsrate(spi->sync_period);
944 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
945 speed *= (0x01 << spi->bus_width);
947 } else if (ccb->cts.transport == XPORT_FC) {
948 struct ccb_trans_settings_fc *fc =
949 &ccb->cts.xport_specific.fc;
951 if (fc->valid & CTS_FC_VALID_SPEED)
953 } else if (ccb->cts.transport == XPORT_SAS) {
954 struct ccb_trans_settings_sas *sas =
955 &ccb->cts.xport_specific.sas;
957 if (sas->valid & CTS_SAS_VALID_SPEED)
958 speed = sas->bitrate;
959 } else if (ccb->cts.transport == XPORT_ATA) {
960 struct ccb_trans_settings_pata *pata =
961 &ccb->cts.xport_specific.ata;
963 if (pata->valid & CTS_ATA_VALID_MODE)
964 speed = ata_mode2speed(pata->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_pata *pata =
1008 &ccb->cts.xport_specific.ata;
1011 if (pata->valid & CTS_ATA_VALID_MODE)
1012 printf("%s, ", ata_mode2string(pata->mode));
1013 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1014 printf("ATAPI %dbytes, ", pata->atapi);
1015 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1016 printf("PIO %dbytes", pata->bytecount);
1018 } else if (ccb->cts.transport == XPORT_SATA) {
1019 struct ccb_trans_settings_sata *sata =
1020 &ccb->cts.xport_specific.sata;
1023 if (sata->valid & CTS_SATA_VALID_REVISION)
1024 printf("SATA %d.x, ", sata->revision);
1027 if (sata->valid & CTS_SATA_VALID_MODE)
1028 printf("%s, ", ata_mode2string(sata->mode));
1029 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1030 printf("ATAPI %dbytes, ", sata->atapi);
1031 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1032 printf("PIO %dbytes", sata->bytecount);
1036 if (ccb->cts.protocol == PROTO_SCSI) {
1037 struct ccb_trans_settings_scsi *scsi =
1038 &ccb->cts.proto_specific.scsi;
1039 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1040 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1041 fprintf(stdout, ", Command Queueing Enabled");
1046 fprintf(stdout, "\n");
1056 atacapprint(struct ata_params *parm)
1058 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1059 ((u_int32_t)parm->lba_size_2 << 16);
1061 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1062 ((u_int64_t)parm->lba_size48_2 << 16) |
1063 ((u_int64_t)parm->lba_size48_3 << 32) |
1064 ((u_int64_t)parm->lba_size48_4 << 48);
1067 printf("protocol ");
1068 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1069 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1070 if (parm->satacapabilities & ATA_SATA_GEN3)
1071 printf(" SATA 3.x\n");
1072 else if (parm->satacapabilities & ATA_SATA_GEN2)
1073 printf(" SATA 2.x\n");
1074 else if (parm->satacapabilities & ATA_SATA_GEN1)
1075 printf(" SATA 1.x\n");
1081 printf("device model %.40s\n", parm->model);
1082 printf("firmware revision %.8s\n", parm->revision);
1083 printf("serial number %.20s\n", parm->serial);
1084 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1085 printf("WWN %04x%04x%04x%04x\n",
1086 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1088 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1089 printf("media serial number %.30s\n",
1090 parm->media_serial);
1093 printf("cylinders %d\n", parm->cylinders);
1094 printf("heads %d\n", parm->heads);
1095 printf("sectors/track %d\n", parm->sectors);
1096 printf("sector size logical %u, physical %lu, offset %lu\n",
1097 ata_logical_sector_size(parm),
1098 (unsigned long)ata_physical_sector_size(parm),
1099 (unsigned long)ata_logical_sector_offset(parm));
1101 if (parm->config == ATA_PROTO_CFA ||
1102 (parm->support.command2 & ATA_SUPPORT_CFA))
1103 printf("CFA supported\n");
1105 printf("LBA%ssupported ",
1106 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1108 printf("%d sectors\n", lbasize);
1112 printf("LBA48%ssupported ",
1113 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1115 printf("%ju sectors\n", (uintmax_t)lbasize48);
1119 printf("PIO supported PIO");
1120 switch (ata_max_pmode(parm)) {
1136 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1137 printf(" w/o IORDY");
1140 printf("DMA%ssupported ",
1141 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1142 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1143 if (parm->mwdmamodes & 0xff) {
1145 if (parm->mwdmamodes & 0x04)
1147 else if (parm->mwdmamodes & 0x02)
1149 else if (parm->mwdmamodes & 0x01)
1153 if ((parm->atavalid & ATA_FLAG_88) &&
1154 (parm->udmamodes & 0xff)) {
1156 if (parm->udmamodes & 0x40)
1158 else if (parm->udmamodes & 0x20)
1160 else if (parm->udmamodes & 0x10)
1162 else if (parm->udmamodes & 0x08)
1164 else if (parm->udmamodes & 0x04)
1166 else if (parm->udmamodes & 0x02)
1168 else if (parm->udmamodes & 0x01)
1175 if (parm->media_rotation_rate == 1) {
1176 printf("media RPM non-rotating\n");
1177 } else if (parm->media_rotation_rate >= 0x0401 &&
1178 parm->media_rotation_rate <= 0xFFFE) {
1179 printf("media RPM %d\n",
1180 parm->media_rotation_rate);
1184 "Support Enabled Value Vendor\n");
1185 printf("read ahead %s %s\n",
1186 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1187 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1188 printf("write cache %s %s\n",
1189 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1190 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1191 printf("flush cache %s %s\n",
1192 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1193 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1194 printf("overlap %s\n",
1195 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1196 printf("Tagged Command Queuing (TCQ) %s %s",
1197 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1198 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1199 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1200 printf(" %d tags\n",
1201 ATA_QUEUE_LEN(parm->queue) + 1);
1204 printf("Native Command Queuing (NCQ) ");
1205 if (parm->satacapabilities != 0xffff &&
1206 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1207 printf("yes %d tags\n",
1208 ATA_QUEUE_LEN(parm->queue) + 1);
1211 printf("SMART %s %s\n",
1212 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1213 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1214 printf("microcode download %s %s\n",
1215 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1216 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1217 printf("security %s %s\n",
1218 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1219 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1220 printf("power management %s %s\n",
1221 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1222 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1223 printf("advanced power management %s %s",
1224 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1225 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1226 if (parm->support.command2 & ATA_SUPPORT_APM) {
1227 printf(" %d/0x%02X\n",
1228 parm->apm_value, parm->apm_value);
1231 printf("automatic acoustic management %s %s",
1232 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1233 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1234 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1235 printf(" %d/0x%02X %d/0x%02X\n",
1236 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1237 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1238 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1239 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1242 printf("media status notification %s %s\n",
1243 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1244 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1245 printf("power-up in Standby %s %s\n",
1246 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1247 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1248 printf("write-read-verify %s %s",
1249 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1250 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1251 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1252 printf(" %d/0x%x\n",
1253 parm->wrv_mode, parm->wrv_mode);
1256 printf("unload %s %s\n",
1257 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1258 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1259 printf("free-fall %s %s\n",
1260 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1261 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1262 printf("data set management (TRIM) %s\n",
1263 parm->support_dsm & ATA_SUPPORT_DSM_TRIM ? "yes" : "no");
1267 ataidentify(struct cam_device *device, int retry_count, int timeout)
1270 struct ata_params *ident_buf;
1271 struct ccb_getdev cgd;
1275 if (get_cgd(device, &cgd) != 0) {
1276 warnx("couldn't get CGD");
1279 ccb = cam_getccb(device);
1282 warnx("couldn't allocate CCB");
1286 /* cam_getccb cleans up the header, caller has to zero the payload */
1287 bzero(&(&ccb->ccb_h)[1],
1288 sizeof(struct ccb_ataio) - sizeof(struct ccb_hdr));
1290 ptr = (uint16_t *)malloc(sizeof(struct ata_params));
1294 warnx("can't malloc memory for identify\n");
1297 bzero(ptr, sizeof(struct ata_params));
1299 cam_fill_ataio(&ccb->ataio,
1302 /*flags*/CAM_DIR_IN,
1304 /*data_ptr*/(u_int8_t *)ptr,
1305 /*dxfer_len*/sizeof(struct ata_params),
1306 timeout ? timeout : 30 * 1000);
1307 if (cgd.protocol == PROTO_ATA)
1308 ata_28bit_cmd(&ccb->ataio, ATA_ATA_IDENTIFY, 0, 0, 0);
1310 ata_28bit_cmd(&ccb->ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0);
1312 /* Disable freezing the device queue */
1313 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1315 if (arglist & CAM_ARG_ERR_RECOVER)
1316 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1318 if (cam_send_ccb(device, ccb) < 0) {
1319 perror("error sending ATA identify");
1321 if (arglist & CAM_ARG_VERBOSE) {
1322 cam_error_print(device, ccb, CAM_ESF_ALL,
1323 CAM_EPF_ALL, stderr);
1331 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1334 if (arglist & CAM_ARG_VERBOSE) {
1335 cam_error_print(device, ccb, CAM_ESF_ALL,
1336 CAM_EPF_ALL, stderr);
1347 for (i = 0; i < sizeof(struct ata_params) / 2; i++)
1348 ptr[i] = le16toh(ptr[i]);
1349 if (arglist & CAM_ARG_VERBOSE) {
1350 fprintf(stdout, "%s%d: Raw identify data:\n",
1351 device->device_name, device->dev_unit_num);
1352 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
1354 fprintf(stdout, " %3d: ", i);
1355 fprintf(stdout, "%04x ", (uint16_t)ptr[i]);
1357 fprintf(stdout, "\n");
1360 ident_buf = (struct ata_params *)ptr;
1361 if (strncmp(ident_buf->model, "FX", 2) &&
1362 strncmp(ident_buf->model, "NEC", 3) &&
1363 strncmp(ident_buf->model, "Pioneer", 7) &&
1364 strncmp(ident_buf->model, "SHARP", 5)) {
1365 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
1366 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
1367 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
1368 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
1370 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
1371 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
1372 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
1373 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
1374 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
1375 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
1376 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
1377 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
1378 sizeof(ident_buf->media_serial));
1380 fprintf(stdout, "%s%d: ", device->device_name,
1381 device->dev_unit_num);
1382 ata_print_ident(ident_buf);
1383 camxferrate(device);
1384 atacapprint(ident_buf);
1390 #endif /* MINIMALISTIC */
1393 * Parse out a bus, or a bus, target and lun in the following
1399 * Returns the number of parsed components, or 0.
1402 parse_btl(char *tstr, int *bus, int *target, int *lun, cam_argmask *arglst)
1407 while (isspace(*tstr) && (*tstr != '\0'))
1410 tmpstr = (char *)strtok(tstr, ":");
1411 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
1412 *bus = strtol(tmpstr, NULL, 0);
1413 *arglst |= CAM_ARG_BUS;
1415 tmpstr = (char *)strtok(NULL, ":");
1416 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
1417 *target = strtol(tmpstr, NULL, 0);
1418 *arglst |= CAM_ARG_TARGET;
1420 tmpstr = (char *)strtok(NULL, ":");
1421 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
1422 *lun = strtol(tmpstr, NULL, 0);
1423 *arglst |= CAM_ARG_LUN;
1433 dorescan_or_reset(int argc, char **argv, int rescan)
1435 static const char must[] =
1436 "you must specify \"all\", a bus, or a bus:target:lun to %s";
1438 int bus = -1, target = -1, lun = -1;
1442 warnx(must, rescan? "rescan" : "reset");
1446 tstr = argv[optind];
1447 while (isspace(*tstr) && (*tstr != '\0'))
1449 if (strncasecmp(tstr, "all", strlen("all")) == 0)
1450 arglist |= CAM_ARG_BUS;
1452 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
1453 if (rv != 1 && rv != 3) {
1454 warnx(must, rescan? "rescan" : "reset");
1459 if ((arglist & CAM_ARG_BUS)
1460 && (arglist & CAM_ARG_TARGET)
1461 && (arglist & CAM_ARG_LUN))
1462 error = scanlun_or_reset_dev(bus, target, lun, rescan);
1464 error = rescan_or_reset_bus(bus, rescan);
1470 rescan_or_reset_bus(int bus, int rescan)
1472 union ccb ccb, matchccb;
1478 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
1479 warnx("error opening transport layer device %s", XPT_DEVICE);
1480 warn("%s", XPT_DEVICE);
1485 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
1486 ccb.ccb_h.path_id = bus;
1487 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
1488 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
1489 ccb.crcn.flags = CAM_FLAG_NONE;
1491 /* run this at a low priority */
1492 ccb.ccb_h.pinfo.priority = 5;
1494 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
1495 warn("CAMIOCOMMAND ioctl failed");
1500 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
1501 fprintf(stdout, "%s of bus %d was successful\n",
1502 rescan ? "Re-scan" : "Reset", bus);
1504 fprintf(stdout, "%s of bus %d returned error %#x\n",
1505 rescan ? "Re-scan" : "Reset", bus,
1506 ccb.ccb_h.status & CAM_STATUS_MASK);
1517 * The right way to handle this is to modify the xpt so that it can
1518 * handle a wildcarded bus in a rescan or reset CCB. At the moment
1519 * that isn't implemented, so instead we enumerate the busses and
1520 * send the rescan or reset to those busses in the case where the
1521 * given bus is -1 (wildcard). We don't send a rescan or reset
1522 * to the xpt bus; sending a rescan to the xpt bus is effectively a
1523 * no-op, sending a rescan to the xpt bus would result in a status of
1526 bzero(&(&matchccb.ccb_h)[1],
1527 sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr));
1528 matchccb.ccb_h.func_code = XPT_DEV_MATCH;
1529 matchccb.ccb_h.path_id = CAM_BUS_WILDCARD;
1530 bufsize = sizeof(struct dev_match_result) * 20;
1531 matchccb.cdm.match_buf_len = bufsize;
1532 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
1533 if (matchccb.cdm.matches == NULL) {
1534 warnx("can't malloc memory for matches");
1538 matchccb.cdm.num_matches = 0;
1540 matchccb.cdm.num_patterns = 1;
1541 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
1543 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
1544 matchccb.cdm.pattern_buf_len);
1545 if (matchccb.cdm.patterns == NULL) {
1546 warnx("can't malloc memory for patterns");
1550 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
1551 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
1556 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
1557 warn("CAMIOCOMMAND ioctl failed");
1562 if ((matchccb.ccb_h.status != CAM_REQ_CMP)
1563 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
1564 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
1565 warnx("got CAM error %#x, CDM error %d\n",
1566 matchccb.ccb_h.status, matchccb.cdm.status);
1571 for (i = 0; i < matchccb.cdm.num_matches; i++) {
1572 struct bus_match_result *bus_result;
1574 /* This shouldn't happen. */
1575 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
1578 bus_result = &matchccb.cdm.matches[i].result.bus_result;
1581 * We don't want to rescan or reset the xpt bus.
1584 if ((int)bus_result->path_id == -1)
1587 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
1589 ccb.ccb_h.path_id = bus_result->path_id;
1590 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
1591 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
1592 ccb.crcn.flags = CAM_FLAG_NONE;
1594 /* run this at a low priority */
1595 ccb.ccb_h.pinfo.priority = 5;
1597 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
1598 warn("CAMIOCOMMAND ioctl failed");
1603 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
1604 fprintf(stdout, "%s of bus %d was successful\n",
1605 rescan? "Re-scan" : "Reset",
1606 bus_result->path_id);
1609 * Don't bail out just yet, maybe the other
1610 * rescan or reset commands will complete
1613 fprintf(stderr, "%s of bus %d returned error "
1614 "%#x\n", rescan? "Re-scan" : "Reset",
1615 bus_result->path_id,
1616 ccb.ccb_h.status & CAM_STATUS_MASK);
1620 } while ((matchccb.ccb_h.status == CAM_REQ_CMP)
1621 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
1628 if (matchccb.cdm.patterns != NULL)
1629 free(matchccb.cdm.patterns);
1630 if (matchccb.cdm.matches != NULL)
1631 free(matchccb.cdm.matches);
1637 scanlun_or_reset_dev(int bus, int target, int lun, int scan)
1640 struct cam_device *device;
1646 warnx("invalid bus number %d", bus);
1651 warnx("invalid target number %d", target);
1656 warnx("invalid lun number %d", lun);
1662 bzero(&ccb, sizeof(union ccb));
1665 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
1666 warnx("error opening transport layer device %s\n",
1668 warn("%s", XPT_DEVICE);
1672 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
1673 if (device == NULL) {
1674 warnx("%s", cam_errbuf);
1679 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
1680 ccb.ccb_h.path_id = bus;
1681 ccb.ccb_h.target_id = target;
1682 ccb.ccb_h.target_lun = lun;
1683 ccb.ccb_h.timeout = 5000;
1684 ccb.crcn.flags = CAM_FLAG_NONE;
1686 /* run this at a low priority */
1687 ccb.ccb_h.pinfo.priority = 5;
1690 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
1691 warn("CAMIOCOMMAND ioctl failed");
1696 if (cam_send_ccb(device, &ccb) < 0) {
1697 warn("error sending XPT_RESET_DEV CCB");
1698 cam_close_device(device);
1706 cam_close_device(device);
1709 * An error code of CAM_BDR_SENT is normal for a BDR request.
1711 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
1713 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
1714 fprintf(stdout, "%s of %d:%d:%d was successful\n",
1715 scan? "Re-scan" : "Reset", bus, target, lun);
1718 fprintf(stdout, "%s of %d:%d:%d returned error %#x\n",
1719 scan? "Re-scan" : "Reset", bus, target, lun,
1720 ccb.ccb_h.status & CAM_STATUS_MASK);
1725 #ifndef MINIMALISTIC
1727 readdefects(struct cam_device *device, int argc, char **argv,
1728 char *combinedopt, int retry_count, int timeout)
1730 union ccb *ccb = NULL;
1731 struct scsi_read_defect_data_10 *rdd_cdb;
1732 u_int8_t *defect_list = NULL;
1733 u_int32_t dlist_length = 65000;
1734 u_int32_t returned_length = 0;
1735 u_int32_t num_returned = 0;
1736 u_int8_t returned_format;
1739 int lists_specified = 0;
1741 while ((c = getopt(argc, argv, combinedopt)) != -1) {
1747 while (isspace(*tstr) && (*tstr != '\0'))
1749 if (strcmp(tstr, "block") == 0)
1750 arglist |= CAM_ARG_FORMAT_BLOCK;
1751 else if (strcmp(tstr, "bfi") == 0)
1752 arglist |= CAM_ARG_FORMAT_BFI;
1753 else if (strcmp(tstr, "phys") == 0)
1754 arglist |= CAM_ARG_FORMAT_PHYS;
1757 warnx("invalid defect format %s", tstr);
1758 goto defect_bailout;
1763 arglist |= CAM_ARG_GLIST;
1766 arglist |= CAM_ARG_PLIST;
1773 ccb = cam_getccb(device);
1776 * Hopefully 65000 bytes is enough to hold the defect list. If it
1777 * isn't, the disk is probably dead already. We'd have to go with
1778 * 12 byte command (i.e. alloc_length is 32 bits instead of 16)
1781 defect_list = malloc(dlist_length);
1782 if (defect_list == NULL) {
1783 warnx("can't malloc memory for defect list");
1785 goto defect_bailout;
1788 rdd_cdb =(struct scsi_read_defect_data_10 *)&ccb->csio.cdb_io.cdb_bytes;
1791 * cam_getccb() zeros the CCB header only. So we need to zero the
1792 * payload portion of the ccb.
1794 bzero(&(&ccb->ccb_h)[1],
1795 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1797 cam_fill_csio(&ccb->csio,
1798 /*retries*/ retry_count,
1800 /*flags*/ CAM_DIR_IN | ((arglist & CAM_ARG_ERR_RECOVER) ?
1801 CAM_PASS_ERR_RECOVER : 0),
1802 /*tag_action*/ MSG_SIMPLE_Q_TAG,
1803 /*data_ptr*/ defect_list,
1804 /*dxfer_len*/ dlist_length,
1805 /*sense_len*/ SSD_FULL_SIZE,
1806 /*cdb_len*/ sizeof(struct scsi_read_defect_data_10),
1807 /*timeout*/ timeout ? timeout : 5000);
1809 rdd_cdb->opcode = READ_DEFECT_DATA_10;
1810 if (arglist & CAM_ARG_FORMAT_BLOCK)
1811 rdd_cdb->format = SRDD10_BLOCK_FORMAT;
1812 else if (arglist & CAM_ARG_FORMAT_BFI)
1813 rdd_cdb->format = SRDD10_BYTES_FROM_INDEX_FORMAT;
1814 else if (arglist & CAM_ARG_FORMAT_PHYS)
1815 rdd_cdb->format = SRDD10_PHYSICAL_SECTOR_FORMAT;
1818 warnx("no defect list format specified");
1819 goto defect_bailout;
1821 if (arglist & CAM_ARG_PLIST) {
1822 rdd_cdb->format |= SRDD10_PLIST;
1826 if (arglist & CAM_ARG_GLIST) {
1827 rdd_cdb->format |= SRDD10_GLIST;
1831 scsi_ulto2b(dlist_length, rdd_cdb->alloc_length);
1833 /* Disable freezing the device queue */
1834 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1836 if (cam_send_ccb(device, ccb) < 0) {
1837 perror("error reading defect list");
1839 if (arglist & CAM_ARG_VERBOSE) {
1840 cam_error_print(device, ccb, CAM_ESF_ALL,
1841 CAM_EPF_ALL, stderr);
1845 goto defect_bailout;
1848 returned_length = scsi_2btoul(((struct
1849 scsi_read_defect_data_hdr_10 *)defect_list)->length);
1851 returned_format = ((struct scsi_read_defect_data_hdr_10 *)
1852 defect_list)->format;
1854 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
1855 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
1856 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
1857 struct scsi_sense_data *sense;
1858 int error_code, sense_key, asc, ascq;
1860 sense = &ccb->csio.sense_data;
1861 scsi_extract_sense(sense, &error_code, &sense_key, &asc, &ascq);
1864 * According to the SCSI spec, if the disk doesn't support
1865 * the requested format, it will generally return a sense
1866 * key of RECOVERED ERROR, and an additional sense code
1867 * of "DEFECT LIST NOT FOUND". So, we check for that, and
1868 * also check to make sure that the returned length is
1869 * greater than 0, and then print out whatever format the
1872 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
1873 && (asc == 0x1c) && (ascq == 0x00)
1874 && (returned_length > 0)) {
1875 warnx("requested defect format not available");
1876 switch(returned_format & SRDDH10_DLIST_FORMAT_MASK) {
1877 case SRDD10_BLOCK_FORMAT:
1878 warnx("Device returned block format");
1880 case SRDD10_BYTES_FROM_INDEX_FORMAT:
1881 warnx("Device returned bytes from index"
1884 case SRDD10_PHYSICAL_SECTOR_FORMAT:
1885 warnx("Device returned physical sector format");
1889 warnx("Device returned unknown defect"
1890 " data format %#x", returned_format);
1891 goto defect_bailout;
1892 break; /* NOTREACHED */
1896 warnx("Error returned from read defect data command");
1897 if (arglist & CAM_ARG_VERBOSE)
1898 cam_error_print(device, ccb, CAM_ESF_ALL,
1899 CAM_EPF_ALL, stderr);
1900 goto defect_bailout;
1902 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1904 warnx("Error returned from read defect data command");
1905 if (arglist & CAM_ARG_VERBOSE)
1906 cam_error_print(device, ccb, CAM_ESF_ALL,
1907 CAM_EPF_ALL, stderr);
1908 goto defect_bailout;
1912 * XXX KDM I should probably clean up the printout format for the
1915 switch (returned_format & SRDDH10_DLIST_FORMAT_MASK){
1916 case SRDDH10_PHYSICAL_SECTOR_FORMAT:
1918 struct scsi_defect_desc_phys_sector *dlist;
1920 dlist = (struct scsi_defect_desc_phys_sector *)
1922 sizeof(struct scsi_read_defect_data_hdr_10));
1924 num_returned = returned_length /
1925 sizeof(struct scsi_defect_desc_phys_sector);
1927 fprintf(stderr, "Got %d defect", num_returned);
1929 if ((lists_specified == 0) || (num_returned == 0)) {
1930 fprintf(stderr, "s.\n");
1932 } else if (num_returned == 1)
1933 fprintf(stderr, ":\n");
1935 fprintf(stderr, "s:\n");
1937 for (i = 0; i < num_returned; i++) {
1938 fprintf(stdout, "%d:%d:%d\n",
1939 scsi_3btoul(dlist[i].cylinder),
1941 scsi_4btoul(dlist[i].sector));
1945 case SRDDH10_BYTES_FROM_INDEX_FORMAT:
1947 struct scsi_defect_desc_bytes_from_index *dlist;
1949 dlist = (struct scsi_defect_desc_bytes_from_index *)
1951 sizeof(struct scsi_read_defect_data_hdr_10));
1953 num_returned = returned_length /
1954 sizeof(struct scsi_defect_desc_bytes_from_index);
1956 fprintf(stderr, "Got %d defect", num_returned);
1958 if ((lists_specified == 0) || (num_returned == 0)) {
1959 fprintf(stderr, "s.\n");
1961 } else if (num_returned == 1)
1962 fprintf(stderr, ":\n");
1964 fprintf(stderr, "s:\n");
1966 for (i = 0; i < num_returned; i++) {
1967 fprintf(stdout, "%d:%d:%d\n",
1968 scsi_3btoul(dlist[i].cylinder),
1970 scsi_4btoul(dlist[i].bytes_from_index));
1974 case SRDDH10_BLOCK_FORMAT:
1976 struct scsi_defect_desc_block *dlist;
1978 dlist = (struct scsi_defect_desc_block *)(defect_list +
1979 sizeof(struct scsi_read_defect_data_hdr_10));
1981 num_returned = returned_length /
1982 sizeof(struct scsi_defect_desc_block);
1984 fprintf(stderr, "Got %d defect", num_returned);
1986 if ((lists_specified == 0) || (num_returned == 0)) {
1987 fprintf(stderr, "s.\n");
1989 } else if (num_returned == 1)
1990 fprintf(stderr, ":\n");
1992 fprintf(stderr, "s:\n");
1994 for (i = 0; i < num_returned; i++)
1995 fprintf(stdout, "%u\n",
1996 scsi_4btoul(dlist[i].address));
2000 fprintf(stderr, "Unknown defect format %d\n",
2001 returned_format & SRDDH10_DLIST_FORMAT_MASK);
2007 if (defect_list != NULL)
2015 #endif /* MINIMALISTIC */
2019 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
2023 ccb = cam_getccb(device);
2029 #ifndef MINIMALISTIC
2031 mode_sense(struct cam_device *device, int mode_page, int page_control,
2032 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
2037 ccb = cam_getccb(device);
2040 errx(1, "mode_sense: couldn't allocate CCB");
2042 bzero(&(&ccb->ccb_h)[1],
2043 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
2045 scsi_mode_sense(&ccb->csio,
2046 /* retries */ retry_count,
2048 /* tag_action */ MSG_SIMPLE_Q_TAG,
2050 /* page_code */ page_control << 6,
2051 /* page */ mode_page,
2052 /* param_buf */ data,
2053 /* param_len */ datalen,
2054 /* sense_len */ SSD_FULL_SIZE,
2055 /* timeout */ timeout ? timeout : 5000);
2057 if (arglist & CAM_ARG_ERR_RECOVER)
2058 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
2060 /* Disable freezing the device queue */
2061 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
2063 if (((retval = cam_send_ccb(device, ccb)) < 0)
2064 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
2065 if (arglist & CAM_ARG_VERBOSE) {
2066 cam_error_print(device, ccb, CAM_ESF_ALL,
2067 CAM_EPF_ALL, stderr);
2070 cam_close_device(device);
2072 err(1, "error sending mode sense command");
2074 errx(1, "error sending mode sense command");
2081 mode_select(struct cam_device *device, int save_pages, int retry_count,
2082 int timeout, u_int8_t *data, int datalen)
2087 ccb = cam_getccb(device);
2090 errx(1, "mode_select: couldn't allocate CCB");
2092 bzero(&(&ccb->ccb_h)[1],
2093 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
2095 scsi_mode_select(&ccb->csio,
2096 /* retries */ retry_count,
2098 /* tag_action */ MSG_SIMPLE_Q_TAG,
2099 /* scsi_page_fmt */ 1,
2100 /* save_pages */ save_pages,
2101 /* param_buf */ data,
2102 /* param_len */ datalen,
2103 /* sense_len */ SSD_FULL_SIZE,
2104 /* timeout */ timeout ? timeout : 5000);
2106 if (arglist & CAM_ARG_ERR_RECOVER)
2107 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
2109 /* Disable freezing the device queue */
2110 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
2112 if (((retval = cam_send_ccb(device, ccb)) < 0)
2113 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
2114 if (arglist & CAM_ARG_VERBOSE) {
2115 cam_error_print(device, ccb, CAM_ESF_ALL,
2116 CAM_EPF_ALL, stderr);
2119 cam_close_device(device);
2122 err(1, "error sending mode select command");
2124 errx(1, "error sending mode select command");
2132 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
2133 int retry_count, int timeout)
2135 int c, mode_page = -1, page_control = 0;
2136 int binary = 0, list = 0;
2138 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2144 arglist |= CAM_ARG_DBD;
2147 arglist |= CAM_ARG_MODE_EDIT;
2153 mode_page = strtol(optarg, NULL, 0);
2155 errx(1, "invalid mode page %d", mode_page);
2158 page_control = strtol(optarg, NULL, 0);
2159 if ((page_control < 0) || (page_control > 3))
2160 errx(1, "invalid page control field %d",
2162 arglist |= CAM_ARG_PAGE_CNTL;
2169 if (mode_page == -1 && list == 0)
2170 errx(1, "you must specify a mode page!");
2173 mode_list(device, page_control, arglist & CAM_ARG_DBD,
2174 retry_count, timeout);
2176 mode_edit(device, mode_page, page_control,
2177 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
2178 retry_count, timeout);
2183 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
2184 int retry_count, int timeout)
2187 u_int32_t flags = CAM_DIR_NONE;
2188 u_int8_t *data_ptr = NULL;
2190 u_int8_t atacmd[12];
2191 struct get_hook hook;
2192 int c, data_bytes = 0;
2198 char *datastr = NULL, *tstr, *resstr = NULL;
2200 int fd_data = 0, fd_res = 0;
2203 ccb = cam_getccb(device);
2206 warnx("scsicmd: error allocating ccb");
2210 bzero(&(&ccb->ccb_h)[1],
2211 sizeof(union ccb) - sizeof(struct ccb_hdr));
2213 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2217 while (isspace(*tstr) && (*tstr != '\0'))
2219 hook.argc = argc - optind;
2220 hook.argv = argv + optind;
2222 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
2225 * Increment optind by the number of arguments the
2226 * encoding routine processed. After each call to
2227 * getopt(3), optind points to the argument that
2228 * getopt should process _next_. In this case,
2229 * that means it points to the first command string
2230 * argument, if there is one. Once we increment
2231 * this, it should point to either the next command
2232 * line argument, or it should be past the end of
2239 while (isspace(*tstr) && (*tstr != '\0'))
2241 hook.argc = argc - optind;
2242 hook.argv = argv + optind;
2244 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
2247 * Increment optind by the number of arguments the
2248 * encoding routine processed. After each call to
2249 * getopt(3), optind points to the argument that
2250 * getopt should process _next_. In this case,
2251 * that means it points to the first command string
2252 * argument, if there is one. Once we increment
2253 * this, it should point to either the next command
2254 * line argument, or it should be past the end of
2266 if (arglist & CAM_ARG_CMD_OUT) {
2267 warnx("command must either be "
2268 "read or write, not both");
2270 goto scsicmd_bailout;
2272 arglist |= CAM_ARG_CMD_IN;
2274 data_bytes = strtol(optarg, NULL, 0);
2275 if (data_bytes <= 0) {
2276 warnx("invalid number of input bytes %d",
2279 goto scsicmd_bailout;
2281 hook.argc = argc - optind;
2282 hook.argv = argv + optind;
2285 datastr = cget(&hook, NULL);
2287 * If the user supplied "-" instead of a format, he
2288 * wants the data to be written to stdout.
2290 if ((datastr != NULL)
2291 && (datastr[0] == '-'))
2294 data_ptr = (u_int8_t *)malloc(data_bytes);
2295 if (data_ptr == NULL) {
2296 warnx("can't malloc memory for data_ptr");
2298 goto scsicmd_bailout;
2302 if (arglist & CAM_ARG_CMD_IN) {
2303 warnx("command must either be "
2304 "read or write, not both");
2306 goto scsicmd_bailout;
2308 arglist |= CAM_ARG_CMD_OUT;
2309 flags = CAM_DIR_OUT;
2310 data_bytes = strtol(optarg, NULL, 0);
2311 if (data_bytes <= 0) {
2312 warnx("invalid number of output bytes %d",
2315 goto scsicmd_bailout;
2317 hook.argc = argc - optind;
2318 hook.argv = argv + optind;
2320 datastr = cget(&hook, NULL);
2321 data_ptr = (u_int8_t *)malloc(data_bytes);
2322 if (data_ptr == NULL) {
2323 warnx("can't malloc memory for data_ptr");
2325 goto scsicmd_bailout;
2327 bzero(data_ptr, data_bytes);
2329 * If the user supplied "-" instead of a format, he
2330 * wants the data to be read from stdin.
2332 if ((datastr != NULL)
2333 && (datastr[0] == '-'))
2336 buff_encode_visit(data_ptr, data_bytes, datastr,
2342 hook.argc = argc - optind;
2343 hook.argv = argv + optind;
2345 resstr = cget(&hook, NULL);
2346 if ((resstr != NULL) && (resstr[0] == '-'))
2356 * If fd_data is set, and we're writing to the device, we need to
2357 * read the data the user wants written from stdin.
2359 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
2361 int amt_to_read = data_bytes;
2362 u_int8_t *buf_ptr = data_ptr;
2364 for (amt_read = 0; amt_to_read > 0;
2365 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
2366 if (amt_read == -1) {
2367 warn("error reading data from stdin");
2369 goto scsicmd_bailout;
2371 amt_to_read -= amt_read;
2372 buf_ptr += amt_read;
2376 if (arglist & CAM_ARG_ERR_RECOVER)
2377 flags |= CAM_PASS_ERR_RECOVER;
2379 /* Disable freezing the device queue */
2380 flags |= CAM_DEV_QFRZDIS;
2384 * This is taken from the SCSI-3 draft spec.
2385 * (T10/1157D revision 0.3)
2386 * The top 3 bits of an opcode are the group code.
2387 * The next 5 bits are the command code.
2388 * Group 0: six byte commands
2389 * Group 1: ten byte commands
2390 * Group 2: ten byte commands
2392 * Group 4: sixteen byte commands
2393 * Group 5: twelve byte commands
2394 * Group 6: vendor specific
2395 * Group 7: vendor specific
2397 switch((cdb[0] >> 5) & 0x7) {
2408 /* computed by buff_encode_visit */
2419 * We should probably use csio_build_visit or something like that
2420 * here, but it's easier to encode arguments as you go. The
2421 * alternative would be skipping the CDB argument and then encoding
2422 * it here, since we've got the data buffer argument by now.
2424 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
2426 cam_fill_csio(&ccb->csio,
2427 /*retries*/ retry_count,
2430 /*tag_action*/ MSG_SIMPLE_Q_TAG,
2431 /*data_ptr*/ data_ptr,
2432 /*dxfer_len*/ data_bytes,
2433 /*sense_len*/ SSD_FULL_SIZE,
2434 /*cdb_len*/ cdb_len,
2435 /*timeout*/ timeout ? timeout : 5000);
2438 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
2440 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
2442 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
2444 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
2446 cam_fill_ataio(&ccb->ataio,
2447 /*retries*/ retry_count,
2451 /*data_ptr*/ data_ptr,
2452 /*dxfer_len*/ data_bytes,
2453 /*timeout*/ timeout ? timeout : 5000);
2456 if (((retval = cam_send_ccb(device, ccb)) < 0)
2457 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
2459 warn("error sending command");
2461 warnx("error sending command");
2463 if (arglist & CAM_ARG_VERBOSE) {
2464 cam_error_print(device, ccb, CAM_ESF_ALL,
2465 CAM_EPF_ALL, stderr);
2469 goto scsicmd_bailout;
2472 if (atacmd_len && need_res) {
2474 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
2476 fprintf(stdout, "\n");
2479 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
2480 ccb->ataio.res.status,
2481 ccb->ataio.res.error,
2482 ccb->ataio.res.lba_low,
2483 ccb->ataio.res.lba_mid,
2484 ccb->ataio.res.lba_high,
2485 ccb->ataio.res.device,
2486 ccb->ataio.res.lba_low_exp,
2487 ccb->ataio.res.lba_mid_exp,
2488 ccb->ataio.res.lba_high_exp,
2489 ccb->ataio.res.sector_count,
2490 ccb->ataio.res.sector_count_exp);
2495 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
2496 && (arglist & CAM_ARG_CMD_IN)
2497 && (data_bytes > 0)) {
2499 buff_decode_visit(data_ptr, data_bytes, datastr,
2501 fprintf(stdout, "\n");
2503 ssize_t amt_written;
2504 int amt_to_write = data_bytes;
2505 u_int8_t *buf_ptr = data_ptr;
2507 for (amt_written = 0; (amt_to_write > 0) &&
2508 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
2509 amt_to_write -= amt_written;
2510 buf_ptr += amt_written;
2512 if (amt_written == -1) {
2513 warn("error writing data to stdout");
2515 goto scsicmd_bailout;
2516 } else if ((amt_written == 0)
2517 && (amt_to_write > 0)) {
2518 warnx("only wrote %u bytes out of %u",
2519 data_bytes - amt_to_write, data_bytes);
2526 if ((data_bytes > 0) && (data_ptr != NULL))
2535 camdebug(int argc, char **argv, char *combinedopt)
2538 int bus = -1, target = -1, lun = -1;
2539 char *tstr, *tmpstr = NULL;
2543 bzero(&ccb, sizeof(union ccb));
2545 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2548 arglist |= CAM_ARG_DEBUG_INFO;
2549 ccb.cdbg.flags |= CAM_DEBUG_INFO;
2552 arglist |= CAM_ARG_DEBUG_PERIPH;
2553 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
2556 arglist |= CAM_ARG_DEBUG_SUBTRACE;
2557 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
2560 arglist |= CAM_ARG_DEBUG_TRACE;
2561 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
2564 arglist |= CAM_ARG_DEBUG_XPT;
2565 ccb.cdbg.flags |= CAM_DEBUG_XPT;
2568 arglist |= CAM_ARG_DEBUG_CDB;
2569 ccb.cdbg.flags |= CAM_DEBUG_CDB;
2576 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
2577 warnx("error opening transport layer device %s", XPT_DEVICE);
2578 warn("%s", XPT_DEVICE);
2585 warnx("you must specify \"off\", \"all\" or a bus,");
2586 warnx("bus:target, or bus:target:lun");
2593 while (isspace(*tstr) && (*tstr != '\0'))
2596 if (strncmp(tstr, "off", 3) == 0) {
2597 ccb.cdbg.flags = CAM_DEBUG_NONE;
2598 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
2599 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
2601 } else if (strncmp(tstr, "all", 3) != 0) {
2602 tmpstr = (char *)strtok(tstr, ":");
2603 if ((tmpstr != NULL) && (*tmpstr != '\0')){
2604 bus = strtol(tmpstr, NULL, 0);
2605 arglist |= CAM_ARG_BUS;
2606 tmpstr = (char *)strtok(NULL, ":");
2607 if ((tmpstr != NULL) && (*tmpstr != '\0')){
2608 target = strtol(tmpstr, NULL, 0);
2609 arglist |= CAM_ARG_TARGET;
2610 tmpstr = (char *)strtok(NULL, ":");
2611 if ((tmpstr != NULL) && (*tmpstr != '\0')){
2612 lun = strtol(tmpstr, NULL, 0);
2613 arglist |= CAM_ARG_LUN;
2618 warnx("you must specify \"all\", \"off\", or a bus,");
2619 warnx("bus:target, or bus:target:lun to debug");
2625 ccb.ccb_h.func_code = XPT_DEBUG;
2626 ccb.ccb_h.path_id = bus;
2627 ccb.ccb_h.target_id = target;
2628 ccb.ccb_h.target_lun = lun;
2630 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
2631 warn("CAMIOCOMMAND ioctl failed");
2636 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
2637 CAM_FUNC_NOTAVAIL) {
2638 warnx("CAM debugging not available");
2639 warnx("you need to put options CAMDEBUG in"
2640 " your kernel config file!");
2642 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
2644 warnx("XPT_DEBUG CCB failed with status %#x",
2648 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
2650 "Debugging turned off\n");
2653 "Debugging enabled for "
2666 tagcontrol(struct cam_device *device, int argc, char **argv,
2676 ccb = cam_getccb(device);
2679 warnx("tagcontrol: error allocating ccb");
2683 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2686 numtags = strtol(optarg, NULL, 0);
2688 warnx("tag count %d is < 0", numtags);
2690 goto tagcontrol_bailout;
2701 cam_path_string(device, pathstr, sizeof(pathstr));
2704 bzero(&(&ccb->ccb_h)[1],
2705 sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
2706 ccb->ccb_h.func_code = XPT_REL_SIMQ;
2707 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
2708 ccb->crs.openings = numtags;
2711 if (cam_send_ccb(device, ccb) < 0) {
2712 perror("error sending XPT_REL_SIMQ CCB");
2714 goto tagcontrol_bailout;
2717 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2718 warnx("XPT_REL_SIMQ CCB failed");
2719 cam_error_print(device, ccb, CAM_ESF_ALL,
2720 CAM_EPF_ALL, stderr);
2722 goto tagcontrol_bailout;
2727 fprintf(stdout, "%stagged openings now %d\n",
2728 pathstr, ccb->crs.openings);
2731 bzero(&(&ccb->ccb_h)[1],
2732 sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr));
2734 ccb->ccb_h.func_code = XPT_GDEV_STATS;
2736 if (cam_send_ccb(device, ccb) < 0) {
2737 perror("error sending XPT_GDEV_STATS CCB");
2739 goto tagcontrol_bailout;
2742 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2743 warnx("XPT_GDEV_STATS CCB failed");
2744 cam_error_print(device, ccb, CAM_ESF_ALL,
2745 CAM_EPF_ALL, stderr);
2747 goto tagcontrol_bailout;
2750 if (arglist & CAM_ARG_VERBOSE) {
2751 fprintf(stdout, "%s", pathstr);
2752 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
2753 fprintf(stdout, "%s", pathstr);
2754 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
2755 fprintf(stdout, "%s", pathstr);
2756 fprintf(stdout, "devq_openings %d\n", ccb->cgds.devq_openings);
2757 fprintf(stdout, "%s", pathstr);
2758 fprintf(stdout, "devq_queued %d\n", ccb->cgds.devq_queued);
2759 fprintf(stdout, "%s", pathstr);
2760 fprintf(stdout, "held %d\n", ccb->cgds.held);
2761 fprintf(stdout, "%s", pathstr);
2762 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
2763 fprintf(stdout, "%s", pathstr);
2764 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
2767 fprintf(stdout, "%s", pathstr);
2768 fprintf(stdout, "device openings: ");
2770 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
2771 ccb->cgds.dev_active);
2781 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
2785 cam_path_string(device, pathstr, sizeof(pathstr));
2787 if (cts->transport == XPORT_SPI) {
2788 struct ccb_trans_settings_spi *spi =
2789 &cts->xport_specific.spi;
2791 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
2793 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
2796 if (spi->sync_offset != 0) {
2799 freq = scsi_calc_syncsrate(spi->sync_period);
2800 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
2801 pathstr, freq / 1000, freq % 1000);
2805 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
2806 fprintf(stdout, "%soffset: %d\n", pathstr,
2810 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
2811 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
2812 (0x01 << spi->bus_width) * 8);
2815 if (spi->valid & CTS_SPI_VALID_DISC) {
2816 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
2817 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
2818 "enabled" : "disabled");
2821 if (cts->transport == XPORT_FC) {
2822 struct ccb_trans_settings_fc *fc =
2823 &cts->xport_specific.fc;
2825 if (fc->valid & CTS_FC_VALID_WWNN)
2826 fprintf(stdout, "%sWWNN: 0x%llx", pathstr,
2827 (long long) fc->wwnn);
2828 if (fc->valid & CTS_FC_VALID_WWPN)
2829 fprintf(stdout, "%sWWPN: 0x%llx", pathstr,
2830 (long long) fc->wwpn);
2831 if (fc->valid & CTS_FC_VALID_PORT)
2832 fprintf(stdout, "%sPortID: 0x%x", pathstr, fc->port);
2833 if (fc->valid & CTS_FC_VALID_SPEED)
2834 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
2835 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
2837 if (cts->transport == XPORT_SAS) {
2838 struct ccb_trans_settings_sas *sas =
2839 &cts->xport_specific.sas;
2841 if (sas->valid & CTS_SAS_VALID_SPEED)
2842 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
2843 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
2845 if (cts->transport == XPORT_ATA) {
2846 struct ccb_trans_settings_pata *pata =
2847 &cts->xport_specific.ata;
2849 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
2850 fprintf(stdout, "%sATA mode: %s\n", pathstr,
2851 ata_mode2string(pata->mode));
2853 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
2854 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
2857 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
2858 fprintf(stdout, "%sPIO transaction length: %d\n",
2859 pathstr, pata->bytecount);
2862 if (cts->transport == XPORT_SATA) {
2863 struct ccb_trans_settings_sata *sata =
2864 &cts->xport_specific.sata;
2866 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
2867 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
2870 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
2871 fprintf(stdout, "%sATA mode: %s\n", pathstr,
2872 ata_mode2string(sata->mode));
2874 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
2875 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
2878 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
2879 fprintf(stdout, "%sPIO transaction length: %d\n",
2880 pathstr, sata->bytecount);
2882 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
2883 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
2886 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
2887 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
2890 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
2891 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
2895 if (cts->protocol == PROTO_ATA) {
2896 struct ccb_trans_settings_ata *ata=
2897 &cts->proto_specific.ata;
2899 if (ata->valid & CTS_ATA_VALID_TQ) {
2900 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
2901 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
2902 "enabled" : "disabled");
2905 if (cts->protocol == PROTO_SCSI) {
2906 struct ccb_trans_settings_scsi *scsi=
2907 &cts->proto_specific.scsi;
2909 if (scsi->valid & CTS_SCSI_VALID_TQ) {
2910 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
2911 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
2912 "enabled" : "disabled");
2919 * Get a path inquiry CCB for the specified device.
2922 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
2927 ccb = cam_getccb(device);
2929 warnx("get_cpi: couldn't allocate CCB");
2932 bzero(&(&ccb->ccb_h)[1],
2933 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
2934 ccb->ccb_h.func_code = XPT_PATH_INQ;
2935 if (cam_send_ccb(device, ccb) < 0) {
2936 warn("get_cpi: error sending Path Inquiry CCB");
2937 if (arglist & CAM_ARG_VERBOSE)
2938 cam_error_print(device, ccb, CAM_ESF_ALL,
2939 CAM_EPF_ALL, stderr);
2941 goto get_cpi_bailout;
2943 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2944 if (arglist & CAM_ARG_VERBOSE)
2945 cam_error_print(device, ccb, CAM_ESF_ALL,
2946 CAM_EPF_ALL, stderr);
2948 goto get_cpi_bailout;
2950 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
2958 * Get a get device CCB for the specified device.
2961 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
2966 ccb = cam_getccb(device);
2968 warnx("get_cgd: couldn't allocate CCB");
2971 bzero(&(&ccb->ccb_h)[1],
2972 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
2973 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
2974 if (cam_send_ccb(device, ccb) < 0) {
2975 warn("get_cgd: error sending Path Inquiry CCB");
2976 if (arglist & CAM_ARG_VERBOSE)
2977 cam_error_print(device, ccb, CAM_ESF_ALL,
2978 CAM_EPF_ALL, stderr);
2980 goto get_cgd_bailout;
2982 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2983 if (arglist & CAM_ARG_VERBOSE)
2984 cam_error_print(device, ccb, CAM_ESF_ALL,
2985 CAM_EPF_ALL, stderr);
2987 goto get_cgd_bailout;
2989 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
2997 cpi_print(struct ccb_pathinq *cpi)
2999 char adapter_str[1024];
3002 snprintf(adapter_str, sizeof(adapter_str),
3003 "%s%d:", cpi->dev_name, cpi->unit_number);
3005 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
3008 for (i = 1; i < 0xff; i = i << 1) {
3011 if ((i & cpi->hba_inquiry) == 0)
3014 fprintf(stdout, "%s supports ", adapter_str);
3018 str = "MDP message";
3021 str = "32 bit wide SCSI";
3024 str = "16 bit wide SCSI";
3027 str = "SDTR message";
3030 str = "linked CDBs";
3033 str = "tag queue messages";
3036 str = "soft reset alternative";
3039 str = "SATA Port Multiplier";
3042 str = "unknown PI bit set";
3045 fprintf(stdout, "%s\n", str);
3048 for (i = 1; i < 0xff; i = i << 1) {
3051 if ((i & cpi->hba_misc) == 0)
3054 fprintf(stdout, "%s ", adapter_str);
3058 str = "bus scans from high ID to low ID";
3061 str = "removable devices not included in scan";
3063 case PIM_NOINITIATOR:
3064 str = "initiator role not supported";
3066 case PIM_NOBUSRESET:
3067 str = "user has disabled initial BUS RESET or"
3068 " controller is in target/mixed mode";
3071 str = "do not send 6-byte commands";
3074 str = "scan bus sequentially";
3077 str = "unknown PIM bit set";
3080 fprintf(stdout, "%s\n", str);
3083 for (i = 1; i < 0xff; i = i << 1) {
3086 if ((i & cpi->target_sprt) == 0)
3089 fprintf(stdout, "%s supports ", adapter_str);
3092 str = "target mode processor mode";
3095 str = "target mode phase cog. mode";
3097 case PIT_DISCONNECT:
3098 str = "disconnects in target mode";
3101 str = "terminate I/O message in target mode";
3104 str = "group 6 commands in target mode";
3107 str = "group 7 commands in target mode";
3110 str = "unknown PIT bit set";
3114 fprintf(stdout, "%s\n", str);
3116 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
3118 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
3120 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
3122 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
3123 adapter_str, cpi->hpath_id);
3124 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
3126 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
3127 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
3128 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
3129 fprintf(stdout, "%s base transfer speed: ", adapter_str);
3130 if (cpi->base_transfer_speed > 1000)
3131 fprintf(stdout, "%d.%03dMB/sec\n",
3132 cpi->base_transfer_speed / 1000,
3133 cpi->base_transfer_speed % 1000);
3135 fprintf(stdout, "%dKB/sec\n",
3136 (cpi->base_transfer_speed % 1000) * 1000);
3140 get_print_cts(struct cam_device *device, int user_settings, int quiet,
3141 struct ccb_trans_settings *cts)
3147 ccb = cam_getccb(device);
3150 warnx("get_print_cts: error allocating ccb");
3154 bzero(&(&ccb->ccb_h)[1],
3155 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
3157 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
3159 if (user_settings == 0)
3160 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
3162 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
3164 if (cam_send_ccb(device, ccb) < 0) {
3165 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
3166 if (arglist & CAM_ARG_VERBOSE)
3167 cam_error_print(device, ccb, CAM_ESF_ALL,
3168 CAM_EPF_ALL, stderr);
3170 goto get_print_cts_bailout;
3173 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3174 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
3175 if (arglist & CAM_ARG_VERBOSE)
3176 cam_error_print(device, ccb, CAM_ESF_ALL,
3177 CAM_EPF_ALL, stderr);
3179 goto get_print_cts_bailout;
3183 cts_print(device, &ccb->cts);
3186 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
3188 get_print_cts_bailout:
3196 ratecontrol(struct cam_device *device, int retry_count, int timeout,
3197 int argc, char **argv, char *combinedopt)
3201 int user_settings = 0;
3203 int disc_enable = -1, tag_enable = -1;
3206 double syncrate = -1;
3209 int change_settings = 0, send_tur = 0;
3210 struct ccb_pathinq cpi;
3212 ccb = cam_getccb(device);
3214 warnx("ratecontrol: error allocating ccb");
3217 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3226 if (strncasecmp(optarg, "enable", 6) == 0)
3228 else if (strncasecmp(optarg, "disable", 7) == 0)
3231 warnx("-D argument \"%s\" is unknown", optarg);
3233 goto ratecontrol_bailout;
3235 change_settings = 1;
3238 mode = ata_string2mode(optarg);
3240 warnx("unknown mode '%s'", optarg);
3242 goto ratecontrol_bailout;
3244 change_settings = 1;
3247 offset = strtol(optarg, NULL, 0);
3249 warnx("offset value %d is < 0", offset);
3251 goto ratecontrol_bailout;
3253 change_settings = 1;
3259 syncrate = atof(optarg);
3261 warnx("sync rate %f is < 0", syncrate);
3263 goto ratecontrol_bailout;
3265 change_settings = 1;
3268 if (strncasecmp(optarg, "enable", 6) == 0)
3270 else if (strncasecmp(optarg, "disable", 7) == 0)
3273 warnx("-T argument \"%s\" is unknown", optarg);
3275 goto ratecontrol_bailout;
3277 change_settings = 1;
3283 bus_width = strtol(optarg, NULL, 0);
3284 if (bus_width < 0) {
3285 warnx("bus width %d is < 0", bus_width);
3287 goto ratecontrol_bailout;
3289 change_settings = 1;
3295 bzero(&(&ccb->ccb_h)[1],
3296 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
3298 * Grab path inquiry information, so we can determine whether
3299 * or not the initiator is capable of the things that the user
3302 ccb->ccb_h.func_code = XPT_PATH_INQ;
3303 if (cam_send_ccb(device, ccb) < 0) {
3304 perror("error sending XPT_PATH_INQ CCB");
3305 if (arglist & CAM_ARG_VERBOSE) {
3306 cam_error_print(device, ccb, CAM_ESF_ALL,
3307 CAM_EPF_ALL, stderr);
3310 goto ratecontrol_bailout;
3312 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3313 warnx("XPT_PATH_INQ CCB failed");
3314 if (arglist & CAM_ARG_VERBOSE) {
3315 cam_error_print(device, ccb, CAM_ESF_ALL,
3316 CAM_EPF_ALL, stderr);
3319 goto ratecontrol_bailout;
3321 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
3322 bzero(&(&ccb->ccb_h)[1],
3323 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
3325 fprintf(stdout, "%s parameters:\n",
3326 user_settings ? "User" : "Current");
3328 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
3330 goto ratecontrol_bailout;
3332 if (arglist & CAM_ARG_VERBOSE)
3335 if (change_settings) {
3336 int didsettings = 0;
3337 struct ccb_trans_settings_spi *spi = NULL;
3338 struct ccb_trans_settings_pata *pata = NULL;
3339 struct ccb_trans_settings_sata *sata = NULL;
3340 struct ccb_trans_settings_ata *ata = NULL;
3341 struct ccb_trans_settings_scsi *scsi = NULL;
3343 if (ccb->cts.transport == XPORT_SPI)
3344 spi = &ccb->cts.xport_specific.spi;
3345 if (ccb->cts.transport == XPORT_ATA)
3346 pata = &ccb->cts.xport_specific.ata;
3347 if (ccb->cts.transport == XPORT_SATA)
3348 sata = &ccb->cts.xport_specific.sata;
3349 if (ccb->cts.protocol == PROTO_ATA)
3350 ata = &ccb->cts.proto_specific.ata;
3351 if (ccb->cts.protocol == PROTO_SCSI)
3352 scsi = &ccb->cts.proto_specific.scsi;
3353 ccb->cts.xport_specific.valid = 0;
3354 ccb->cts.proto_specific.valid = 0;
3355 if (spi && disc_enable != -1) {
3356 spi->valid |= CTS_SPI_VALID_DISC;
3357 if (disc_enable == 0)
3358 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
3360 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
3363 if (tag_enable != -1) {
3364 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
3365 warnx("HBA does not support tagged queueing, "
3366 "so you cannot modify tag settings");
3368 goto ratecontrol_bailout;
3371 ata->valid |= CTS_SCSI_VALID_TQ;
3372 if (tag_enable == 0)
3373 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
3375 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
3378 scsi->valid |= CTS_SCSI_VALID_TQ;
3379 if (tag_enable == 0)
3380 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
3382 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
3386 if (spi && offset != -1) {
3387 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3388 warnx("HBA is not capable of changing offset");
3390 goto ratecontrol_bailout;
3392 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
3393 spi->sync_offset = offset;
3396 if (spi && syncrate != -1) {
3397 int prelim_sync_period;
3400 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3401 warnx("HBA is not capable of changing "
3404 goto ratecontrol_bailout;
3406 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
3408 * The sync rate the user gives us is in MHz.
3409 * We need to translate it into KHz for this
3414 * Next, we calculate a "preliminary" sync period
3415 * in tenths of a nanosecond.
3418 prelim_sync_period = 0;
3420 prelim_sync_period = 10000000 / syncrate;
3422 scsi_calc_syncparam(prelim_sync_period);
3423 freq = scsi_calc_syncsrate(spi->sync_period);
3426 if (sata && syncrate != -1) {
3427 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3428 warnx("HBA is not capable of changing "
3431 goto ratecontrol_bailout;
3433 if (!user_settings) {
3434 warnx("You can modify only user rate "
3435 "settings for SATA");
3437 goto ratecontrol_bailout;
3439 sata->revision = ata_speed2revision(syncrate * 100);
3440 if (sata->revision < 0) {
3441 warnx("Invalid rate %f", syncrate);
3443 goto ratecontrol_bailout;
3445 sata->valid |= CTS_SATA_VALID_REVISION;
3448 if ((pata || sata) && mode != -1) {
3449 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3450 warnx("HBA is not capable of changing "
3453 goto ratecontrol_bailout;
3455 if (!user_settings) {
3456 warnx("You can modify only user mode "
3457 "settings for ATA/SATA");
3459 goto ratecontrol_bailout;
3463 pata->valid |= CTS_ATA_VALID_MODE;
3466 sata->valid |= CTS_SATA_VALID_MODE;
3471 * The bus_width argument goes like this:
3475 * Therefore, if you shift the number of bits given on the
3476 * command line right by 4, you should get the correct
3479 if (spi && bus_width != -1) {
3481 * We might as well validate things here with a
3482 * decipherable error message, rather than what
3483 * will probably be an indecipherable error message
3484 * by the time it gets back to us.
3486 if ((bus_width == 16)
3487 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
3488 warnx("HBA does not support 16 bit bus width");
3490 goto ratecontrol_bailout;
3491 } else if ((bus_width == 32)
3492 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
3493 warnx("HBA does not support 32 bit bus width");
3495 goto ratecontrol_bailout;
3496 } else if ((bus_width != 8)
3497 && (bus_width != 16)
3498 && (bus_width != 32)) {
3499 warnx("Invalid bus width %d", bus_width);
3501 goto ratecontrol_bailout;
3503 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
3504 spi->bus_width = bus_width >> 4;
3507 if (didsettings == 0) {
3508 goto ratecontrol_bailout;
3510 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
3511 if (cam_send_ccb(device, ccb) < 0) {
3512 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
3513 if (arglist & CAM_ARG_VERBOSE) {
3514 cam_error_print(device, ccb, CAM_ESF_ALL,
3515 CAM_EPF_ALL, stderr);
3518 goto ratecontrol_bailout;
3520 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3521 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
3522 if (arglist & CAM_ARG_VERBOSE) {
3523 cam_error_print(device, ccb, CAM_ESF_ALL,
3524 CAM_EPF_ALL, stderr);
3527 goto ratecontrol_bailout;
3531 retval = testunitready(device, retry_count, timeout,
3532 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
3534 * If the TUR didn't succeed, just bail.
3538 fprintf(stderr, "Test Unit Ready failed\n");
3539 goto ratecontrol_bailout;
3542 if ((change_settings || send_tur) && !quiet &&
3543 (ccb->cts.transport == XPORT_ATA ||
3544 ccb->cts.transport == XPORT_SATA || send_tur)) {
3545 fprintf(stdout, "New parameters:\n");
3546 retval = get_print_cts(device, user_settings, 0, NULL);
3549 ratecontrol_bailout:
3555 scsiformat(struct cam_device *device, int argc, char **argv,
3556 char *combinedopt, int retry_count, int timeout)
3560 int ycount = 0, quiet = 0;
3561 int error = 0, response = 0, retval = 0;
3562 int use_timeout = 10800 * 1000;
3564 struct format_defect_list_header fh;
3565 u_int8_t *data_ptr = NULL;
3566 u_int32_t dxfer_len = 0;
3568 int num_warnings = 0;
3571 ccb = cam_getccb(device);
3574 warnx("scsiformat: error allocating ccb");
3578 bzero(&(&ccb->ccb_h)[1],
3579 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3581 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3602 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
3603 "following device:\n");
3605 error = scsidoinquiry(device, argc, argv, combinedopt,
3606 retry_count, timeout);
3609 warnx("scsiformat: error sending inquiry");
3610 goto scsiformat_bailout;
3619 fprintf(stdout, "Are you SURE you want to do "
3622 if (fgets(str, sizeof(str), stdin) != NULL) {
3624 if (strncasecmp(str, "yes", 3) == 0)
3626 else if (strncasecmp(str, "no", 2) == 0)
3629 fprintf(stdout, "Please answer"
3630 " \"yes\" or \"no\"\n");
3633 } while (response == 0);
3635 if (response == -1) {
3637 goto scsiformat_bailout;
3642 use_timeout = timeout;
3645 fprintf(stdout, "Current format timeout is %d seconds\n",
3646 use_timeout / 1000);
3650 * If the user hasn't disabled questions and didn't specify a
3651 * timeout on the command line, ask them if they want the current
3655 && (timeout == 0)) {
3657 int new_timeout = 0;
3659 fprintf(stdout, "Enter new timeout in seconds or press\n"
3660 "return to keep the current timeout [%d] ",
3661 use_timeout / 1000);
3663 if (fgets(str, sizeof(str), stdin) != NULL) {
3665 new_timeout = atoi(str);
3668 if (new_timeout != 0) {
3669 use_timeout = new_timeout * 1000;
3670 fprintf(stdout, "Using new timeout value %d\n",
3671 use_timeout / 1000);
3676 * Keep this outside the if block below to silence any unused
3677 * variable warnings.
3679 bzero(&fh, sizeof(fh));
3682 * If we're in immediate mode, we've got to include the format
3685 if (immediate != 0) {
3686 fh.byte2 = FU_DLH_IMMED;
3687 data_ptr = (u_int8_t *)&fh;
3688 dxfer_len = sizeof(fh);
3689 byte2 = FU_FMT_DATA;
3690 } else if (quiet == 0) {
3691 fprintf(stdout, "Formatting...");
3695 scsi_format_unit(&ccb->csio,
3696 /* retries */ retry_count,
3698 /* tag_action */ MSG_SIMPLE_Q_TAG,
3701 /* data_ptr */ data_ptr,
3702 /* dxfer_len */ dxfer_len,
3703 /* sense_len */ SSD_FULL_SIZE,
3704 /* timeout */ use_timeout);
3706 /* Disable freezing the device queue */
3707 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3709 if (arglist & CAM_ARG_ERR_RECOVER)
3710 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3712 if (((retval = cam_send_ccb(device, ccb)) < 0)
3713 || ((immediate == 0)
3714 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
3715 const char errstr[] = "error sending format command";
3722 if (arglist & CAM_ARG_VERBOSE) {
3723 cam_error_print(device, ccb, CAM_ESF_ALL,
3724 CAM_EPF_ALL, stderr);
3727 goto scsiformat_bailout;
3731 * If we ran in non-immediate mode, we already checked for errors
3732 * above and printed out any necessary information. If we're in
3733 * immediate mode, we need to loop through and get status
3734 * information periodically.
3736 if (immediate == 0) {
3738 fprintf(stdout, "Format Complete\n");
3740 goto scsiformat_bailout;
3747 bzero(&(&ccb->ccb_h)[1],
3748 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3751 * There's really no need to do error recovery or
3752 * retries here, since we're just going to sit in a
3753 * loop and wait for the device to finish formatting.
3755 scsi_test_unit_ready(&ccb->csio,
3758 /* tag_action */ MSG_SIMPLE_Q_TAG,
3759 /* sense_len */ SSD_FULL_SIZE,
3760 /* timeout */ 5000);
3762 /* Disable freezing the device queue */
3763 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3765 retval = cam_send_ccb(device, ccb);
3768 * If we get an error from the ioctl, bail out. SCSI
3769 * errors are expected.
3772 warn("error sending CAMIOCOMMAND ioctl");
3773 if (arglist & CAM_ARG_VERBOSE) {
3774 cam_error_print(device, ccb, CAM_ESF_ALL,
3775 CAM_EPF_ALL, stderr);
3778 goto scsiformat_bailout;
3781 status = ccb->ccb_h.status & CAM_STATUS_MASK;
3783 if ((status != CAM_REQ_CMP)
3784 && (status == CAM_SCSI_STATUS_ERROR)
3785 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3786 struct scsi_sense_data *sense;
3787 int error_code, sense_key, asc, ascq;
3789 sense = &ccb->csio.sense_data;
3790 scsi_extract_sense(sense, &error_code, &sense_key,
3794 * According to the SCSI-2 and SCSI-3 specs, a
3795 * drive that is in the middle of a format should
3796 * return NOT READY with an ASC of "logical unit
3797 * not ready, format in progress". The sense key
3798 * specific bytes will then be a progress indicator.
3800 if ((sense_key == SSD_KEY_NOT_READY)
3801 && (asc == 0x04) && (ascq == 0x04)) {
3802 if ((sense->extra_len >= 10)
3803 && ((sense->sense_key_spec[0] &
3804 SSD_SCS_VALID) != 0)
3807 u_int64_t percentage;
3810 &sense->sense_key_spec[1]);
3811 percentage = 10000 * val;
3814 "\rFormatting: %ju.%02u %% "
3816 (uintmax_t)(percentage /
3818 (unsigned)((percentage /
3822 } else if ((quiet == 0)
3823 && (++num_warnings <= 1)) {
3824 warnx("Unexpected SCSI Sense Key "
3825 "Specific value returned "
3827 scsi_sense_print(device, &ccb->csio,
3829 warnx("Unable to print status "
3830 "information, but format will "
3832 warnx("will exit when format is "
3837 warnx("Unexpected SCSI error during format");
3838 cam_error_print(device, ccb, CAM_ESF_ALL,
3839 CAM_EPF_ALL, stderr);
3841 goto scsiformat_bailout;
3844 } else if (status != CAM_REQ_CMP) {
3845 warnx("Unexpected CAM status %#x", status);
3846 if (arglist & CAM_ARG_VERBOSE)
3847 cam_error_print(device, ccb, CAM_ESF_ALL,
3848 CAM_EPF_ALL, stderr);
3850 goto scsiformat_bailout;
3853 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
3856 fprintf(stdout, "\nFormat Complete\n");
3866 scsireportluns(struct cam_device *device, int argc, char **argv,
3867 char *combinedopt, int retry_count, int timeout)
3870 int c, countonly, lunsonly;
3871 struct scsi_report_luns_data *lundata;
3873 uint8_t report_type;
3874 uint32_t list_len, i, j;
3879 report_type = RPL_REPORT_DEFAULT;
3880 ccb = cam_getccb(device);
3883 warnx("%s: error allocating ccb", __func__);
3887 bzero(&(&ccb->ccb_h)[1],
3888 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3893 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3902 if (strcasecmp(optarg, "default") == 0)
3903 report_type = RPL_REPORT_DEFAULT;
3904 else if (strcasecmp(optarg, "wellknown") == 0)
3905 report_type = RPL_REPORT_WELLKNOWN;
3906 else if (strcasecmp(optarg, "all") == 0)
3907 report_type = RPL_REPORT_ALL;
3909 warnx("%s: invalid report type \"%s\"",
3920 if ((countonly != 0)
3921 && (lunsonly != 0)) {
3922 warnx("%s: you can only specify one of -c or -l", __func__);
3927 * According to SPC-4, the allocation length must be at least 16
3928 * bytes -- enough for the header and one LUN.
3930 alloc_len = sizeof(*lundata) + 8;
3934 lundata = malloc(alloc_len);
3936 if (lundata == NULL) {
3937 warn("%s: error mallocing %d bytes", __func__, alloc_len);
3942 scsi_report_luns(&ccb->csio,
3943 /*retries*/ retry_count,
3945 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3946 /*select_report*/ report_type,
3947 /*rpl_buf*/ lundata,
3948 /*alloc_len*/ alloc_len,
3949 /*sense_len*/ SSD_FULL_SIZE,
3950 /*timeout*/ timeout ? timeout : 5000);
3952 /* Disable freezing the device queue */
3953 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3955 if (arglist & CAM_ARG_ERR_RECOVER)
3956 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3958 if (cam_send_ccb(device, ccb) < 0) {
3959 warn("error sending REPORT LUNS command");
3961 if (arglist & CAM_ARG_VERBOSE)
3962 cam_error_print(device, ccb, CAM_ESF_ALL,
3963 CAM_EPF_ALL, stderr);
3969 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3970 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
3976 list_len = scsi_4btoul(lundata->length);
3979 * If we need to list the LUNs, and our allocation
3980 * length was too short, reallocate and retry.
3982 if ((countonly == 0)
3983 && (list_len > (alloc_len - sizeof(*lundata)))) {
3984 alloc_len = list_len + sizeof(*lundata);
3990 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
3991 ((list_len / 8) > 1) ? "s" : "");
3996 for (i = 0; i < (list_len / 8); i++) {
4000 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
4002 fprintf(stdout, ",");
4003 switch (lundata->luns[i].lundata[j] &
4004 RPL_LUNDATA_ATYP_MASK) {
4005 case RPL_LUNDATA_ATYP_PERIPH:
4006 if ((lundata->luns[i].lundata[j] &
4007 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
4008 fprintf(stdout, "%d:",
4009 lundata->luns[i].lundata[j] &
4010 RPL_LUNDATA_PERIPH_BUS_MASK);
4012 && ((lundata->luns[i].lundata[j+2] &
4013 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
4016 fprintf(stdout, "%d",
4017 lundata->luns[i].lundata[j+1]);
4019 case RPL_LUNDATA_ATYP_FLAT: {
4021 tmplun[0] = lundata->luns[i].lundata[j] &
4022 RPL_LUNDATA_FLAT_LUN_MASK;
4023 tmplun[1] = lundata->luns[i].lundata[j+1];
4025 fprintf(stdout, "%d", scsi_2btoul(tmplun));
4029 case RPL_LUNDATA_ATYP_LUN:
4030 fprintf(stdout, "%d:%d:%d",
4031 (lundata->luns[i].lundata[j+1] &
4032 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
4033 lundata->luns[i].lundata[j] &
4034 RPL_LUNDATA_LUN_TARG_MASK,
4035 lundata->luns[i].lundata[j+1] &
4036 RPL_LUNDATA_LUN_LUN_MASK);
4038 case RPL_LUNDATA_ATYP_EXTLUN: {
4039 int field_len, field_len_code, eam_code;
4041 eam_code = lundata->luns[i].lundata[j] &
4042 RPL_LUNDATA_EXT_EAM_MASK;
4043 field_len_code = (lundata->luns[i].lundata[j] &
4044 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
4045 field_len = field_len_code * 2;
4047 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
4048 && (field_len_code == 0x00)) {
4049 fprintf(stdout, "%d",
4050 lundata->luns[i].lundata[j+1]);
4051 } else if ((eam_code ==
4052 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
4053 && (field_len_code == 0x03)) {
4057 * This format takes up all 8 bytes.
4058 * If we aren't starting at offset 0,
4062 fprintf(stdout, "Invalid "
4065 "specified format", j);
4069 bzero(tmp_lun, sizeof(tmp_lun));
4070 bcopy(&lundata->luns[i].lundata[j+1],
4071 &tmp_lun[1], sizeof(tmp_lun) - 1);
4072 fprintf(stdout, "%#jx",
4073 (intmax_t)scsi_8btou64(tmp_lun));
4076 fprintf(stderr, "Unknown Extended LUN"
4077 "Address method %#x, length "
4078 "code %#x", eam_code,
4085 fprintf(stderr, "Unknown LUN address method "
4086 "%#x\n", lundata->luns[i].lundata[0] &
4087 RPL_LUNDATA_ATYP_MASK);
4091 * For the flat addressing method, there are no
4092 * other levels after it.
4097 fprintf(stdout, "\n");
4110 scsireadcapacity(struct cam_device *device, int argc, char **argv,
4111 char *combinedopt, int retry_count, int timeout)
4114 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
4115 struct scsi_read_capacity_data rcap;
4116 struct scsi_read_capacity_data_long rcaplong;
4130 ccb = cam_getccb(device);
4133 warnx("%s: error allocating ccb", __func__);
4137 bzero(&(&ccb->ccb_h)[1],
4138 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
4140 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4167 if ((blocksizeonly != 0)
4168 && (numblocks != 0)) {
4169 warnx("%s: you can only specify one of -b or -N", __func__);
4174 if ((blocksizeonly != 0)
4175 && (sizeonly != 0)) {
4176 warnx("%s: you can only specify one of -b or -s", __func__);
4183 warnx("%s: you can only specify one of -h/-H or -q", __func__);
4189 && (blocksizeonly != 0)) {
4190 warnx("%s: you can only specify one of -h/-H or -b", __func__);
4195 scsi_read_capacity(&ccb->csio,
4196 /*retries*/ retry_count,
4198 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4201 /*timeout*/ timeout ? timeout : 5000);
4203 /* Disable freezing the device queue */
4204 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4206 if (arglist & CAM_ARG_ERR_RECOVER)
4207 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4209 if (cam_send_ccb(device, ccb) < 0) {
4210 warn("error sending READ CAPACITY command");
4212 if (arglist & CAM_ARG_VERBOSE)
4213 cam_error_print(device, ccb, CAM_ESF_ALL,
4214 CAM_EPF_ALL, stderr);
4220 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4221 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4226 maxsector = scsi_4btoul(rcap.addr);
4227 block_len = scsi_4btoul(rcap.length);
4230 * A last block of 2^32-1 means that the true capacity is over 2TB,
4231 * and we need to issue the long READ CAPACITY to get the real
4232 * capacity. Otherwise, we're all set.
4234 if (maxsector != 0xffffffff)
4237 scsi_read_capacity_16(&ccb->csio,
4238 /*retries*/ retry_count,
4240 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4245 /*sense_len*/ SSD_FULL_SIZE,
4246 /*timeout*/ timeout ? timeout : 5000);
4248 /* Disable freezing the device queue */
4249 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4251 if (arglist & CAM_ARG_ERR_RECOVER)
4252 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4254 if (cam_send_ccb(device, ccb) < 0) {
4255 warn("error sending READ CAPACITY (16) command");
4257 if (arglist & CAM_ARG_VERBOSE)
4258 cam_error_print(device, ccb, CAM_ESF_ALL,
4259 CAM_EPF_ALL, stderr);
4265 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4266 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4271 maxsector = scsi_8btou64(rcaplong.addr);
4272 block_len = scsi_4btoul(rcaplong.length);
4275 if (blocksizeonly == 0) {
4277 * Humanize implies !quiet, and also implies numblocks.
4279 if (humanize != 0) {
4284 tmpbytes = (maxsector + 1) * block_len;
4285 ret = humanize_number(tmpstr, sizeof(tmpstr),
4286 tmpbytes, "", HN_AUTOSCALE,
4289 HN_DIVISOR_1000 : 0));
4291 warnx("%s: humanize_number failed!", __func__);
4295 fprintf(stdout, "Device Size: %s%s", tmpstr,
4296 (sizeonly == 0) ? ", " : "\n");
4297 } else if (numblocks != 0) {
4298 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
4299 "Blocks: " : "", (uintmax_t)maxsector + 1,
4300 (sizeonly == 0) ? ", " : "\n");
4302 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
4303 "Last Block: " : "", (uintmax_t)maxsector,
4304 (sizeonly == 0) ? ", " : "\n");
4308 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
4309 "Block Length: " : "", block_len, (quiet == 0) ?
4318 atapm(struct cam_device *device, int argc, char **argv,
4319 char *combinedopt, int retry_count, int timeout)
4327 ccb = cam_getccb(device);
4330 warnx("%s: error allocating ccb", __func__);
4334 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4343 if (strcmp(argv[1], "idle") == 0) {
4345 cmd = ATA_IDLE_IMMEDIATE;
4348 } else if (strcmp(argv[1], "standby") == 0) {
4350 cmd = ATA_STANDBY_IMMEDIATE;
4352 cmd = ATA_STANDBY_CMD;
4360 else if (t <= (240 * 5))
4362 else if (t <= (252 * 5))
4363 /* special encoding for 21 minutes */
4365 else if (t <= (11 * 30 * 60))
4366 sc = (t - 1) / (30 * 60) + 241;
4370 cam_fill_ataio(&ccb->ataio,
4373 /*flags*/CAM_DIR_NONE,
4377 timeout ? timeout : 30 * 1000);
4378 ata_28bit_cmd(&ccb->ataio, cmd, 0, 0, sc);
4380 /* Disable freezing the device queue */
4381 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4383 if (arglist & CAM_ARG_ERR_RECOVER)
4384 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4386 if (cam_send_ccb(device, ccb) < 0) {
4387 warn("error sending command");
4389 if (arglist & CAM_ARG_VERBOSE)
4390 cam_error_print(device, ccb, CAM_ESF_ALL,
4391 CAM_EPF_ALL, stderr);
4397 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4398 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4407 #endif /* MINIMALISTIC */
4412 fprintf(verbose ? stdout : stderr,
4413 "usage: camcontrol <command> [device id][generic args][command args]\n"
4414 " camcontrol devlist [-v]\n"
4415 #ifndef MINIMALISTIC
4416 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
4417 " camcontrol tur [dev_id][generic args]\n"
4418 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
4419 " camcontrol identify [dev_id][generic args] [-v]\n"
4420 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
4421 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
4423 " camcontrol start [dev_id][generic args]\n"
4424 " camcontrol stop [dev_id][generic args]\n"
4425 " camcontrol load [dev_id][generic args]\n"
4426 " camcontrol eject [dev_id][generic args]\n"
4427 #endif /* MINIMALISTIC */
4428 " camcontrol rescan <all | bus[:target:lun]>\n"
4429 " camcontrol reset <all | bus[:target:lun]>\n"
4430 #ifndef MINIMALISTIC
4431 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
4432 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
4433 " [-P pagectl][-e | -b][-d]\n"
4434 " camcontrol cmd [dev_id][generic args]\n"
4435 " <-a cmd [args] | -c cmd [args]>\n"
4436 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
4437 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
4438 " <all|bus[:target[:lun]]|off>\n"
4439 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
4440 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
4441 " [-D <enable|disable>][-M mode][-O offset]\n"
4442 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
4443 " [-U][-W bus_width]\n"
4444 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
4445 " camcontrol idle [dev_id][generic args][-t time]\n"
4446 " camcontrol standby [dev_id][generic args][-t time]\n"
4447 " camcontrol sleep [dev_id][generic args]\n"
4448 #endif /* MINIMALISTIC */
4449 " camcontrol help\n");
4452 #ifndef MINIMALISTIC
4454 "Specify one of the following options:\n"
4455 "devlist list all CAM devices\n"
4456 "periphlist list all CAM peripheral drivers attached to a device\n"
4457 "tur send a test unit ready to the named device\n"
4458 "inquiry send a SCSI inquiry command to the named device\n"
4459 "identify send a ATA identify command to the named device\n"
4460 "reportluns send a SCSI report luns command to the device\n"
4461 "readcap send a SCSI read capacity command to the device\n"
4462 "start send a Start Unit command to the device\n"
4463 "stop send a Stop Unit command to the device\n"
4464 "load send a Start Unit command to the device with the load bit set\n"
4465 "eject send a Stop Unit command to the device with the eject bit set\n"
4466 "rescan rescan all busses, the given bus, or bus:target:lun\n"
4467 "reset reset all busses, the given bus, or bus:target:lun\n"
4468 "defects read the defect list of the specified device\n"
4469 "modepage display or edit (-e) the given mode page\n"
4470 "cmd send the given scsi command, may need -i or -o as well\n"
4471 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
4472 "tags report or set the number of transaction slots for a device\n"
4473 "negotiate report or set device negotiation parameters\n"
4474 "format send the SCSI FORMAT UNIT command to the named device\n"
4475 "idle send the ATA IDLE command to the named device\n"
4476 "standby send the ATA STANDBY command to the named device\n"
4477 "sleep send the ATA SLEEP command to the named device\n"
4478 "help this message\n"
4479 "Device Identifiers:\n"
4480 "bus:target specify the bus and target, lun defaults to 0\n"
4481 "bus:target:lun specify the bus, target and lun\n"
4482 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
4483 "Generic arguments:\n"
4484 "-v be verbose, print out sense information\n"
4485 "-t timeout command timeout in seconds, overrides default timeout\n"
4486 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
4487 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
4488 "-E have the kernel attempt to perform SCSI error recovery\n"
4489 "-C count specify the SCSI command retry count (needs -E to work)\n"
4490 "modepage arguments:\n"
4491 "-l list all available mode pages\n"
4492 "-m page specify the mode page to view or edit\n"
4493 "-e edit the specified mode page\n"
4494 "-b force view to binary mode\n"
4495 "-d disable block descriptors for mode sense\n"
4496 "-P pgctl page control field 0-3\n"
4497 "defects arguments:\n"
4498 "-f format specify defect list format (block, bfi or phys)\n"
4499 "-G get the grown defect list\n"
4500 "-P get the permanant defect list\n"
4501 "inquiry arguments:\n"
4502 "-D get the standard inquiry data\n"
4503 "-S get the serial number\n"
4504 "-R get the transfer rate, etc.\n"
4505 "reportluns arguments:\n"
4506 "-c only report a count of available LUNs\n"
4507 "-l only print out luns, and not a count\n"
4508 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
4509 "readcap arguments\n"
4510 "-b only report the blocksize\n"
4511 "-h human readable device size, base 2\n"
4512 "-H human readable device size, base 10\n"
4513 "-N print the number of blocks instead of last block\n"
4514 "-q quiet, print numbers only\n"
4515 "-s only report the last block/device size\n"
4517 "-c cdb [args] specify the SCSI CDB\n"
4518 "-i len fmt specify input data and input data format\n"
4519 "-o len fmt [args] specify output data and output data fmt\n"
4520 "debug arguments:\n"
4521 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
4522 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
4523 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
4524 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
4526 "-N tags specify the number of tags to use for this device\n"
4527 "-q be quiet, don't report the number of tags\n"
4528 "-v report a number of tag-related parameters\n"
4529 "negotiate arguments:\n"
4530 "-a send a test unit ready after negotiation\n"
4531 "-c report/set current negotiation settings\n"
4532 "-D <arg> \"enable\" or \"disable\" disconnection\n"
4533 "-M mode set ATA mode\n"
4534 "-O offset set command delay offset\n"
4535 "-q be quiet, don't report anything\n"
4536 "-R syncrate synchronization rate in MHz\n"
4537 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
4538 "-U report/set user negotiation settings\n"
4539 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
4540 "-v also print a Path Inquiry CCB for the controller\n"
4541 "format arguments:\n"
4542 "-q be quiet, don't print status messages\n"
4543 "-r run in report only mode\n"
4544 "-w don't send immediate format command\n"
4545 "-y don't ask any questions\n"
4546 "idle/standby arguments:\n"
4547 "-t <arg> number of seconds before respective state.\n");
4548 #endif /* MINIMALISTIC */
4552 main(int argc, char **argv)
4555 char *device = NULL;
4557 struct cam_device *cam_dev = NULL;
4558 int timeout = 0, retry_count = 1;
4559 camcontrol_optret optreturn;
4561 const char *mainopt = "C:En:t:u:v";
4562 const char *subopt = NULL;
4563 char combinedopt[256];
4564 int error = 0, optstart = 2;
4566 #ifndef MINIMALISTIC
4567 int bus, target, lun;
4568 #endif /* MINIMALISTIC */
4570 cmdlist = CAM_CMD_NONE;
4571 arglist = CAM_ARG_NONE;
4579 * Get the base option.
4581 optreturn = getoption(argv[1], &cmdlist, &arglist, &subopt);
4583 if (optreturn == CC_OR_AMBIGUOUS) {
4584 warnx("ambiguous option %s", argv[1]);
4587 } else if (optreturn == CC_OR_NOT_FOUND) {
4588 warnx("option %s not found", argv[1]);
4594 * Ahh, getopt(3) is a pain.
4596 * This is a gross hack. There really aren't many other good
4597 * options (excuse the pun) for parsing options in a situation like
4598 * this. getopt is kinda braindead, so you end up having to run
4599 * through the options twice, and give each invocation of getopt
4600 * the option string for the other invocation.
4602 * You would think that you could just have two groups of options.
4603 * The first group would get parsed by the first invocation of
4604 * getopt, and the second group would get parsed by the second
4605 * invocation of getopt. It doesn't quite work out that way. When
4606 * the first invocation of getopt finishes, it leaves optind pointing
4607 * to the argument _after_ the first argument in the second group.
4608 * So when the second invocation of getopt comes around, it doesn't
4609 * recognize the first argument it gets and then bails out.
4611 * A nice alternative would be to have a flag for getopt that says
4612 * "just keep parsing arguments even when you encounter an unknown
4613 * argument", but there isn't one. So there's no real clean way to
4614 * easily parse two sets of arguments without having one invocation
4615 * of getopt know about the other.
4617 * Without this hack, the first invocation of getopt would work as
4618 * long as the generic arguments are first, but the second invocation
4619 * (in the subfunction) would fail in one of two ways. In the case
4620 * where you don't set optreset, it would fail because optind may be
4621 * pointing to the argument after the one it should be pointing at.
4622 * In the case where you do set optreset, and reset optind, it would
4623 * fail because getopt would run into the first set of options, which
4624 * it doesn't understand.
4626 * All of this would "sort of" work if you could somehow figure out
4627 * whether optind had been incremented one option too far. The
4628 * mechanics of that, however, are more daunting than just giving
4629 * both invocations all of the expect options for either invocation.
4631 * Needless to say, I wouldn't mind if someone invented a better
4632 * (non-GPL!) command line parsing interface than getopt. I
4633 * wouldn't mind if someone added more knobs to getopt to make it
4634 * work better. Who knows, I may talk myself into doing it someday,
4635 * if the standards weenies let me. As it is, it just leads to
4636 * hackery like this and causes people to avoid it in some cases.
4638 * KDM, September 8th, 1998
4641 sprintf(combinedopt, "%s%s", mainopt, subopt);
4643 sprintf(combinedopt, "%s", mainopt);
4646 * For these options we do not parse optional device arguments and
4647 * we do not open a passthrough device.
4649 if ((cmdlist == CAM_CMD_RESCAN)
4650 || (cmdlist == CAM_CMD_RESET)
4651 || (cmdlist == CAM_CMD_DEVTREE)
4652 || (cmdlist == CAM_CMD_USAGE)
4653 || (cmdlist == CAM_CMD_DEBUG))
4656 #ifndef MINIMALISTIC
4658 && (argc > 2 && argv[2][0] != '-')) {
4662 if (isdigit(argv[2][0])) {
4663 /* device specified as bus:target[:lun] */
4664 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
4666 errx(1, "numeric device specification must "
4667 "be either bus:target, or "
4669 /* default to 0 if lun was not specified */
4670 if ((arglist & CAM_ARG_LUN) == 0) {
4672 arglist |= CAM_ARG_LUN;
4676 if (cam_get_device(argv[2], name, sizeof name, &unit)
4678 errx(1, "%s", cam_errbuf);
4679 device = strdup(name);
4680 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
4684 #endif /* MINIMALISTIC */
4686 * Start getopt processing at argv[2/3], since we've already
4687 * accepted argv[1..2] as the command name, and as a possible
4693 * Now we run through the argument list looking for generic
4694 * options, and ignoring options that possibly belong to
4697 while ((c = getopt(argc, argv, combinedopt))!= -1){
4700 retry_count = strtol(optarg, NULL, 0);
4701 if (retry_count < 0)
4702 errx(1, "retry count %d is < 0",
4704 arglist |= CAM_ARG_RETRIES;
4707 arglist |= CAM_ARG_ERR_RECOVER;
4710 arglist |= CAM_ARG_DEVICE;
4712 while (isspace(*tstr) && (*tstr != '\0'))
4714 device = (char *)strdup(tstr);
4717 timeout = strtol(optarg, NULL, 0);
4719 errx(1, "invalid timeout %d", timeout);
4720 /* Convert the timeout from seconds to ms */
4722 arglist |= CAM_ARG_TIMEOUT;
4725 arglist |= CAM_ARG_UNIT;
4726 unit = strtol(optarg, NULL, 0);
4729 arglist |= CAM_ARG_VERBOSE;
4736 #ifndef MINIMALISTIC
4738 * For most commands we'll want to open the passthrough device
4739 * associated with the specified device. In the case of the rescan
4740 * commands, we don't use a passthrough device at all, just the
4741 * transport layer device.
4744 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
4745 && (((arglist & CAM_ARG_DEVICE) == 0)
4746 || ((arglist & CAM_ARG_UNIT) == 0))) {
4747 errx(1, "subcommand \"%s\" requires a valid device "
4748 "identifier", argv[1]);
4751 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
4752 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
4753 cam_open_spec_device(device,unit,O_RDWR,NULL)))
4755 errx(1,"%s", cam_errbuf);
4757 #endif /* MINIMALISTIC */
4760 * Reset optind to 2, and reset getopt, so these routines can parse
4761 * the arguments again.
4767 #ifndef MINIMALISTIC
4768 case CAM_CMD_DEVLIST:
4769 error = getdevlist(cam_dev);
4771 #endif /* MINIMALISTIC */
4772 case CAM_CMD_DEVTREE:
4773 error = getdevtree();
4775 #ifndef MINIMALISTIC
4777 error = testunitready(cam_dev, retry_count, timeout, 0);
4779 case CAM_CMD_INQUIRY:
4780 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
4781 retry_count, timeout);
4783 case CAM_CMD_IDENTIFY:
4784 error = ataidentify(cam_dev, retry_count, timeout);
4786 case CAM_CMD_STARTSTOP:
4787 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
4788 arglist & CAM_ARG_EJECT, retry_count,
4791 #endif /* MINIMALISTIC */
4792 case CAM_CMD_RESCAN:
4793 error = dorescan_or_reset(argc, argv, 1);
4796 error = dorescan_or_reset(argc, argv, 0);
4798 #ifndef MINIMALISTIC
4799 case CAM_CMD_READ_DEFECTS:
4800 error = readdefects(cam_dev, argc, argv, combinedopt,
4801 retry_count, timeout);
4803 case CAM_CMD_MODE_PAGE:
4804 modepage(cam_dev, argc, argv, combinedopt,
4805 retry_count, timeout);
4807 case CAM_CMD_SCSI_CMD:
4808 error = scsicmd(cam_dev, argc, argv, combinedopt,
4809 retry_count, timeout);
4812 error = camdebug(argc, argv, combinedopt);
4815 error = tagcontrol(cam_dev, argc, argv, combinedopt);
4818 error = ratecontrol(cam_dev, retry_count, timeout,
4819 argc, argv, combinedopt);
4821 case CAM_CMD_FORMAT:
4822 error = scsiformat(cam_dev, argc, argv,
4823 combinedopt, retry_count, timeout);
4825 case CAM_CMD_REPORTLUNS:
4826 error = scsireportluns(cam_dev, argc, argv,
4827 combinedopt, retry_count,
4830 case CAM_CMD_READCAP:
4831 error = scsireadcapacity(cam_dev, argc, argv,
4832 combinedopt, retry_count,
4836 case CAM_CMD_STANDBY:
4838 error = atapm(cam_dev, argc, argv,
4839 combinedopt, retry_count,
4842 #endif /* MINIMALISTIC */
4852 if (cam_dev != NULL)
4853 cam_close_device(cam_dev);