2 * Copyright (c) 1997-2007 Kenneth D. Merry
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/ioctl.h>
33 #include <sys/stdint.h>
34 #include <sys/types.h>
35 #include <sys/endian.h>
47 #include <cam/cam_debug.h>
48 #include <cam/cam_ccb.h>
49 #include <cam/scsi/scsi_all.h>
50 #include <cam/scsi/scsi_da.h>
51 #include <cam/scsi/scsi_pass.h>
52 #include <cam/scsi/scsi_message.h>
53 #include <cam/ata/ata_all.h>
55 #include "camcontrol.h"
58 CAM_CMD_NONE = 0x00000000,
59 CAM_CMD_DEVLIST = 0x00000001,
60 CAM_CMD_TUR = 0x00000002,
61 CAM_CMD_INQUIRY = 0x00000003,
62 CAM_CMD_STARTSTOP = 0x00000004,
63 CAM_CMD_RESCAN = 0x00000005,
64 CAM_CMD_READ_DEFECTS = 0x00000006,
65 CAM_CMD_MODE_PAGE = 0x00000007,
66 CAM_CMD_SCSI_CMD = 0x00000008,
67 CAM_CMD_DEVTREE = 0x00000009,
68 CAM_CMD_USAGE = 0x0000000a,
69 CAM_CMD_DEBUG = 0x0000000b,
70 CAM_CMD_RESET = 0x0000000c,
71 CAM_CMD_FORMAT = 0x0000000d,
72 CAM_CMD_TAG = 0x0000000e,
73 CAM_CMD_RATE = 0x0000000f,
74 CAM_CMD_DETACH = 0x00000010,
75 CAM_CMD_REPORTLUNS = 0x00000011,
76 CAM_CMD_READCAP = 0x00000012,
77 CAM_CMD_IDENTIFY = 0x00000013,
78 CAM_CMD_IDLE = 0x00000014,
79 CAM_CMD_STANDBY = 0x00000015,
80 CAM_CMD_SLEEP = 0x00000016
84 CAM_ARG_NONE = 0x00000000,
85 CAM_ARG_VERBOSE = 0x00000001,
86 CAM_ARG_DEVICE = 0x00000002,
87 CAM_ARG_BUS = 0x00000004,
88 CAM_ARG_TARGET = 0x00000008,
89 CAM_ARG_LUN = 0x00000010,
90 CAM_ARG_EJECT = 0x00000020,
91 CAM_ARG_UNIT = 0x00000040,
92 CAM_ARG_FORMAT_BLOCK = 0x00000080,
93 CAM_ARG_FORMAT_BFI = 0x00000100,
94 CAM_ARG_FORMAT_PHYS = 0x00000200,
95 CAM_ARG_PLIST = 0x00000400,
96 CAM_ARG_GLIST = 0x00000800,
97 CAM_ARG_GET_SERIAL = 0x00001000,
98 CAM_ARG_GET_STDINQ = 0x00002000,
99 CAM_ARG_GET_XFERRATE = 0x00004000,
100 CAM_ARG_INQ_MASK = 0x00007000,
101 CAM_ARG_MODE_EDIT = 0x00008000,
102 CAM_ARG_PAGE_CNTL = 0x00010000,
103 CAM_ARG_TIMEOUT = 0x00020000,
104 CAM_ARG_CMD_IN = 0x00040000,
105 CAM_ARG_CMD_OUT = 0x00080000,
106 CAM_ARG_DBD = 0x00100000,
107 CAM_ARG_ERR_RECOVER = 0x00200000,
108 CAM_ARG_RETRIES = 0x00400000,
109 CAM_ARG_START_UNIT = 0x00800000,
110 CAM_ARG_DEBUG_INFO = 0x01000000,
111 CAM_ARG_DEBUG_TRACE = 0x02000000,
112 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
113 CAM_ARG_DEBUG_CDB = 0x08000000,
114 CAM_ARG_DEBUG_XPT = 0x10000000,
115 CAM_ARG_DEBUG_PERIPH = 0x20000000,
118 struct camcontrol_opts {
126 static const char scsicmd_opts[] = "a:c:dfi:o:r";
127 static const char readdefect_opts[] = "f:GP";
128 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
131 struct camcontrol_opts option_table[] = {
133 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
134 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
135 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
136 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
137 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
138 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
139 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
140 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
141 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
142 #endif /* MINIMALISTIC */
143 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
144 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
146 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
147 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
148 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
149 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
150 #endif /* MINIMALISTIC */
151 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, NULL},
153 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
154 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
155 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
156 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
157 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
158 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXc"},
159 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
160 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
161 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
162 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
163 #endif /* MINIMALISTIC */
164 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
165 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
166 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
180 camcontrol_optret getoption(char *arg, cam_cmdmask *cmdnum, cam_argmask *argnum,
181 const char **subopt);
183 static int getdevlist(struct cam_device *device);
184 #endif /* MINIMALISTIC */
185 static int getdevtree(void);
187 static int testunitready(struct cam_device *device, int retry_count,
188 int timeout, int quiet);
189 static int scsistart(struct cam_device *device, int startstop, int loadeject,
190 int retry_count, int timeout);
191 static int scsidoinquiry(struct cam_device *device, int argc, char **argv,
192 char *combinedopt, int retry_count, int timeout);
193 static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
194 static int scsiserial(struct cam_device *device, int retry_count, int timeout);
195 static int camxferrate(struct cam_device *device);
196 #endif /* MINIMALISTIC */
197 static int parse_btl(char *tstr, int *bus, int *target, int *lun,
198 cam_argmask *arglst);
199 static int dorescan_or_reset(int argc, char **argv, int rescan);
200 static int rescan_or_reset_bus(int bus, int rescan);
201 static int scanlun_or_reset_dev(int bus, int target, int lun, int scan);
203 static int readdefects(struct cam_device *device, int argc, char **argv,
204 char *combinedopt, int retry_count, int timeout);
205 static void modepage(struct cam_device *device, int argc, char **argv,
206 char *combinedopt, int retry_count, int timeout);
207 static int scsicmd(struct cam_device *device, int argc, char **argv,
208 char *combinedopt, int retry_count, int timeout);
209 static int tagcontrol(struct cam_device *device, int argc, char **argv,
211 static void cts_print(struct cam_device *device,
212 struct ccb_trans_settings *cts);
213 static void cpi_print(struct ccb_pathinq *cpi);
214 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
215 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
216 static int get_print_cts(struct cam_device *device, int user_settings,
217 int quiet, struct ccb_trans_settings *cts);
218 static int ratecontrol(struct cam_device *device, int retry_count,
219 int timeout, int argc, char **argv, char *combinedopt);
220 static int scsiformat(struct cam_device *device, int argc, char **argv,
221 char *combinedopt, int retry_count, int timeout);
222 static int scsireportluns(struct cam_device *device, int argc, char **argv,
223 char *combinedopt, int retry_count, int timeout);
224 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
225 char *combinedopt, int retry_count, int timeout);
226 static int atapm(struct cam_device *device, int argc, char **argv,
227 char *combinedopt, int retry_count, int timeout);
228 #endif /* MINIMALISTIC */
230 #define min(a,b) (((a)<(b))?(a):(b))
233 #define max(a,b) (((a)>(b))?(a):(b))
237 getoption(char *arg, cam_cmdmask *cmdnum, cam_argmask *argnum,
240 struct camcontrol_opts *opts;
243 for (opts = option_table; (opts != NULL) && (opts->optname != NULL);
245 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
246 *cmdnum = opts->cmdnum;
247 *argnum = opts->argnum;
248 *subopt = opts->subopt;
249 if (++num_matches > 1)
250 return(CC_OR_AMBIGUOUS);
257 return(CC_OR_NOT_FOUND);
262 getdevlist(struct cam_device *device)
268 ccb = cam_getccb(device);
270 ccb->ccb_h.func_code = XPT_GDEVLIST;
271 ccb->ccb_h.flags = CAM_DIR_NONE;
272 ccb->ccb_h.retry_count = 1;
274 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
275 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
276 if (cam_send_ccb(device, ccb) < 0) {
277 perror("error getting device list");
284 switch (ccb->cgdl.status) {
285 case CAM_GDEVLIST_MORE_DEVS:
286 strcpy(status, "MORE");
288 case CAM_GDEVLIST_LAST_DEVICE:
289 strcpy(status, "LAST");
291 case CAM_GDEVLIST_LIST_CHANGED:
292 strcpy(status, "CHANGED");
294 case CAM_GDEVLIST_ERROR:
295 strcpy(status, "ERROR");
300 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
301 ccb->cgdl.periph_name,
302 ccb->cgdl.unit_number,
303 ccb->cgdl.generation,
308 * If the list has changed, we need to start over from the
311 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
319 #endif /* MINIMALISTIC */
331 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
332 warn("couldn't open %s", XPT_DEVICE);
336 bzero(&ccb, sizeof(union ccb));
338 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
339 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
340 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
342 ccb.ccb_h.func_code = XPT_DEV_MATCH;
343 bufsize = sizeof(struct dev_match_result) * 100;
344 ccb.cdm.match_buf_len = bufsize;
345 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
346 if (ccb.cdm.matches == NULL) {
347 warnx("can't malloc memory for matches");
351 ccb.cdm.num_matches = 0;
354 * We fetch all nodes, since we display most of them in the default
355 * case, and all in the verbose case.
357 ccb.cdm.num_patterns = 0;
358 ccb.cdm.pattern_buf_len = 0;
361 * We do the ioctl multiple times if necessary, in case there are
362 * more than 100 nodes in the EDT.
365 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
366 warn("error sending CAMIOCOMMAND ioctl");
371 if ((ccb.ccb_h.status != CAM_REQ_CMP)
372 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
373 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
374 warnx("got CAM error %#x, CDM error %d\n",
375 ccb.ccb_h.status, ccb.cdm.status);
380 for (i = 0; i < ccb.cdm.num_matches; i++) {
381 switch (ccb.cdm.matches[i].type) {
382 case DEV_MATCH_BUS: {
383 struct bus_match_result *bus_result;
386 * Only print the bus information if the
387 * user turns on the verbose flag.
389 if ((arglist & CAM_ARG_VERBOSE) == 0)
393 &ccb.cdm.matches[i].result.bus_result;
396 fprintf(stdout, ")\n");
400 fprintf(stdout, "scbus%d on %s%d bus %d:\n",
402 bus_result->dev_name,
403 bus_result->unit_number,
407 case DEV_MATCH_DEVICE: {
408 struct device_match_result *dev_result;
409 char vendor[16], product[48], revision[16];
413 &ccb.cdm.matches[i].result.device_result;
415 if ((dev_result->flags
416 & DEV_RESULT_UNCONFIGURED)
417 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
423 if (dev_result->protocol == PROTO_SCSI) {
424 cam_strvis(vendor, dev_result->inq_data.vendor,
425 sizeof(dev_result->inq_data.vendor),
428 dev_result->inq_data.product,
429 sizeof(dev_result->inq_data.product),
432 dev_result->inq_data.revision,
433 sizeof(dev_result->inq_data.revision),
435 sprintf(tmpstr, "<%s %s %s>", vendor, product,
437 } else if (dev_result->protocol == PROTO_ATA ||
438 dev_result->protocol == PROTO_SATAPM) {
440 dev_result->ident_data.model,
441 sizeof(dev_result->ident_data.model),
444 dev_result->ident_data.revision,
445 sizeof(dev_result->ident_data.revision),
447 sprintf(tmpstr, "<%s %s>", product,
450 sprintf(tmpstr, "<>");
453 fprintf(stdout, ")\n");
457 fprintf(stdout, "%-33s at scbus%d "
458 "target %d lun %d (",
461 dev_result->target_id,
462 dev_result->target_lun);
468 case DEV_MATCH_PERIPH: {
469 struct periph_match_result *periph_result;
472 &ccb.cdm.matches[i].result.periph_result;
474 if (skip_device != 0)
478 fprintf(stdout, ",");
480 fprintf(stdout, "%s%d",
481 periph_result->periph_name,
482 periph_result->unit_number);
488 fprintf(stdout, "unknown match type\n");
493 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
494 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
497 fprintf(stdout, ")\n");
506 testunitready(struct cam_device *device, int retry_count, int timeout,
512 ccb = cam_getccb(device);
514 scsi_test_unit_ready(&ccb->csio,
515 /* retries */ retry_count,
517 /* tag_action */ MSG_SIMPLE_Q_TAG,
518 /* sense_len */ SSD_FULL_SIZE,
519 /* timeout */ timeout ? timeout : 5000);
521 /* Disable freezing the device queue */
522 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
524 if (arglist & CAM_ARG_ERR_RECOVER)
525 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
527 if (cam_send_ccb(device, ccb) < 0) {
529 perror("error sending test unit ready");
531 if (arglist & CAM_ARG_VERBOSE) {
532 cam_error_print(device, ccb, CAM_ESF_ALL,
533 CAM_EPF_ALL, stderr);
540 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
542 fprintf(stdout, "Unit is ready\n");
545 fprintf(stdout, "Unit is not ready\n");
548 if (arglist & CAM_ARG_VERBOSE) {
549 cam_error_print(device, ccb, CAM_ESF_ALL,
550 CAM_EPF_ALL, stderr);
560 scsistart(struct cam_device *device, int startstop, int loadeject,
561 int retry_count, int timeout)
566 ccb = cam_getccb(device);
569 * If we're stopping, send an ordered tag so the drive in question
570 * will finish any previously queued writes before stopping. If
571 * the device isn't capable of tagged queueing, or if tagged
572 * queueing is turned off, the tag action is a no-op.
574 scsi_start_stop(&ccb->csio,
575 /* retries */ retry_count,
577 /* tag_action */ startstop ? MSG_SIMPLE_Q_TAG :
579 /* start/stop */ startstop,
580 /* load_eject */ loadeject,
582 /* sense_len */ SSD_FULL_SIZE,
583 /* timeout */ timeout ? timeout : 120000);
585 /* Disable freezing the device queue */
586 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
588 if (arglist & CAM_ARG_ERR_RECOVER)
589 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
591 if (cam_send_ccb(device, ccb) < 0) {
592 perror("error sending start unit");
594 if (arglist & CAM_ARG_VERBOSE) {
595 cam_error_print(device, ccb, CAM_ESF_ALL,
596 CAM_EPF_ALL, stderr);
603 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
605 fprintf(stdout, "Unit started successfully");
607 fprintf(stdout,", Media loaded\n");
609 fprintf(stdout,"\n");
611 fprintf(stdout, "Unit stopped successfully");
613 fprintf(stdout, ", Media ejected\n");
615 fprintf(stdout, "\n");
621 "Error received from start unit command\n");
624 "Error received from stop unit command\n");
626 if (arglist & CAM_ARG_VERBOSE) {
627 cam_error_print(device, ccb, CAM_ESF_ALL,
628 CAM_EPF_ALL, stderr);
638 scsidoinquiry(struct cam_device *device, int argc, char **argv,
639 char *combinedopt, int retry_count, int timeout)
644 while ((c = getopt(argc, argv, combinedopt)) != -1) {
647 arglist |= CAM_ARG_GET_STDINQ;
650 arglist |= CAM_ARG_GET_XFERRATE;
653 arglist |= CAM_ARG_GET_SERIAL;
661 * If the user didn't specify any inquiry options, he wants all of
664 if ((arglist & CAM_ARG_INQ_MASK) == 0)
665 arglist |= CAM_ARG_INQ_MASK;
667 if (arglist & CAM_ARG_GET_STDINQ)
668 error = scsiinquiry(device, retry_count, timeout);
673 if (arglist & CAM_ARG_GET_SERIAL)
674 scsiserial(device, retry_count, timeout);
679 if (arglist & CAM_ARG_GET_XFERRATE)
680 error = camxferrate(device);
686 scsiinquiry(struct cam_device *device, int retry_count, int timeout)
689 struct scsi_inquiry_data *inq_buf;
692 ccb = cam_getccb(device);
695 warnx("couldn't allocate CCB");
699 /* cam_getccb cleans up the header, caller has to zero the payload */
700 bzero(&(&ccb->ccb_h)[1],
701 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
703 inq_buf = (struct scsi_inquiry_data *)malloc(
704 sizeof(struct scsi_inquiry_data));
706 if (inq_buf == NULL) {
708 warnx("can't malloc memory for inquiry\n");
711 bzero(inq_buf, sizeof(*inq_buf));
714 * Note that although the size of the inquiry buffer is the full
715 * 256 bytes specified in the SCSI spec, we only tell the device
716 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
717 * two reasons for this:
719 * - The SCSI spec says that when a length field is only 1 byte,
720 * a value of 0 will be interpreted as 256. Therefore
721 * scsi_inquiry() will convert an inq_len (which is passed in as
722 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
723 * to 0. Evidently, very few devices meet the spec in that
724 * regard. Some devices, like many Seagate disks, take the 0 as
725 * 0, and don't return any data. One Pioneer DVD-R drive
726 * returns more data than the command asked for.
728 * So, since there are numerous devices that just don't work
729 * right with the full inquiry size, we don't send the full size.
731 * - The second reason not to use the full inquiry data length is
732 * that we don't need it here. The only reason we issue a
733 * standard inquiry is to get the vendor name, device name,
734 * and revision so scsi_print_inquiry() can print them.
736 * If, at some point in the future, more inquiry data is needed for
737 * some reason, this code should use a procedure similar to the
738 * probe code. i.e., issue a short inquiry, and determine from
739 * the additional length passed back from the device how much
740 * inquiry data the device supports. Once the amount the device
741 * supports is determined, issue an inquiry for that amount and no
746 scsi_inquiry(&ccb->csio,
747 /* retries */ retry_count,
749 /* tag_action */ MSG_SIMPLE_Q_TAG,
750 /* inq_buf */ (u_int8_t *)inq_buf,
751 /* inq_len */ SHORT_INQUIRY_LENGTH,
754 /* sense_len */ SSD_FULL_SIZE,
755 /* timeout */ timeout ? timeout : 5000);
757 /* Disable freezing the device queue */
758 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
760 if (arglist & CAM_ARG_ERR_RECOVER)
761 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
763 if (cam_send_ccb(device, ccb) < 0) {
764 perror("error sending SCSI inquiry");
766 if (arglist & CAM_ARG_VERBOSE) {
767 cam_error_print(device, ccb, CAM_ESF_ALL,
768 CAM_EPF_ALL, stderr);
775 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
778 if (arglist & CAM_ARG_VERBOSE) {
779 cam_error_print(device, ccb, CAM_ESF_ALL,
780 CAM_EPF_ALL, stderr);
791 fprintf(stdout, "%s%d: ", device->device_name,
792 device->dev_unit_num);
793 scsi_print_inquiry(inq_buf);
801 scsiserial(struct cam_device *device, int retry_count, int timeout)
804 struct scsi_vpd_unit_serial_number *serial_buf;
805 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
808 ccb = cam_getccb(device);
811 warnx("couldn't allocate CCB");
815 /* cam_getccb cleans up the header, caller has to zero the payload */
816 bzero(&(&ccb->ccb_h)[1],
817 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
819 serial_buf = (struct scsi_vpd_unit_serial_number *)
820 malloc(sizeof(*serial_buf));
822 if (serial_buf == NULL) {
824 warnx("can't malloc memory for serial number");
828 scsi_inquiry(&ccb->csio,
829 /*retries*/ retry_count,
831 /* tag_action */ MSG_SIMPLE_Q_TAG,
832 /* inq_buf */ (u_int8_t *)serial_buf,
833 /* inq_len */ sizeof(*serial_buf),
835 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
836 /* sense_len */ SSD_FULL_SIZE,
837 /* timeout */ timeout ? timeout : 5000);
839 /* Disable freezing the device queue */
840 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
842 if (arglist & CAM_ARG_ERR_RECOVER)
843 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
845 if (cam_send_ccb(device, ccb) < 0) {
846 warn("error getting serial number");
848 if (arglist & CAM_ARG_VERBOSE) {
849 cam_error_print(device, ccb, CAM_ESF_ALL,
850 CAM_EPF_ALL, stderr);
858 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
861 if (arglist & CAM_ARG_VERBOSE) {
862 cam_error_print(device, ccb, CAM_ESF_ALL,
863 CAM_EPF_ALL, stderr);
874 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
875 serial_num[serial_buf->length] = '\0';
877 if ((arglist & CAM_ARG_GET_STDINQ)
878 || (arglist & CAM_ARG_GET_XFERRATE))
879 fprintf(stdout, "%s%d: Serial Number ",
880 device->device_name, device->dev_unit_num);
882 fprintf(stdout, "%.60s\n", serial_num);
890 camxferrate(struct cam_device *device)
892 struct ccb_pathinq cpi;
899 if ((retval = get_cpi(device, &cpi)) != 0)
902 ccb = cam_getccb(device);
905 warnx("couldn't allocate CCB");
909 bzero(&(&ccb->ccb_h)[1],
910 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
912 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
913 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
915 if (((retval = cam_send_ccb(device, ccb)) < 0)
916 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
917 const char error_string[] = "error getting transfer settings";
924 if (arglist & CAM_ARG_VERBOSE)
925 cam_error_print(device, ccb, CAM_ESF_ALL,
926 CAM_EPF_ALL, stderr);
930 goto xferrate_bailout;
934 speed = cpi.base_transfer_speed;
936 if (ccb->cts.transport == XPORT_SPI) {
937 struct ccb_trans_settings_spi *spi =
938 &ccb->cts.xport_specific.spi;
940 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
941 freq = scsi_calc_syncsrate(spi->sync_period);
944 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
945 speed *= (0x01 << spi->bus_width);
947 } else if (ccb->cts.transport == XPORT_FC) {
948 struct ccb_trans_settings_fc *fc =
949 &ccb->cts.xport_specific.fc;
951 if (fc->valid & CTS_FC_VALID_SPEED)
953 } else if (ccb->cts.transport == XPORT_SAS) {
954 struct ccb_trans_settings_sas *sas =
955 &ccb->cts.xport_specific.sas;
957 if (sas->valid & CTS_SAS_VALID_SPEED)
958 speed = sas->bitrate;
959 } else if (ccb->cts.transport == XPORT_ATA) {
960 struct ccb_trans_settings_ata *ata =
961 &ccb->cts.xport_specific.ata;
963 if (ata->valid & CTS_ATA_VALID_MODE)
964 speed = ata_mode2speed(ata->mode);
965 } else if (ccb->cts.transport == XPORT_SATA) {
966 struct ccb_trans_settings_sata *sata =
967 &ccb->cts.xport_specific.sata;
969 if (sata->valid & CTS_SATA_VALID_REVISION)
970 speed = ata_revision2speed(sata->revision);
975 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
976 device->device_name, device->dev_unit_num,
979 fprintf(stdout, "%s%d: %dKB/s transfers",
980 device->device_name, device->dev_unit_num,
984 if (ccb->cts.transport == XPORT_SPI) {
985 struct ccb_trans_settings_spi *spi =
986 &ccb->cts.xport_specific.spi;
988 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
989 && (spi->sync_offset != 0))
990 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
991 freq % 1000, spi->sync_offset);
993 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
994 && (spi->bus_width > 0)) {
995 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
996 && (spi->sync_offset != 0)) {
997 fprintf(stdout, ", ");
999 fprintf(stdout, " (");
1001 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1002 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1003 && (spi->sync_offset != 0)) {
1004 fprintf(stdout, ")");
1006 } else if (ccb->cts.transport == XPORT_ATA) {
1007 struct ccb_trans_settings_ata *ata =
1008 &ccb->cts.xport_specific.ata;
1011 if (ata->valid & CTS_ATA_VALID_MODE)
1012 printf("%s, ", ata_mode2string(ata->mode));
1013 if ((ata->valid & CTS_ATA_VALID_ATAPI) && ata->atapi != 0)
1014 printf("ATAPI %dbytes, ", ata->atapi);
1015 if (ata->valid & CTS_ATA_VALID_BYTECOUNT)
1016 printf("PIO %dbytes", ata->bytecount);
1018 } else if (ccb->cts.transport == XPORT_SATA) {
1019 struct ccb_trans_settings_sata *sata =
1020 &ccb->cts.xport_specific.sata;
1023 if (sata->valid & CTS_SATA_VALID_REVISION)
1024 printf("SATA %d.x, ", sata->revision);
1027 if (sata->valid & CTS_SATA_VALID_MODE)
1028 printf("%s, ", ata_mode2string(sata->mode));
1029 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1030 printf("ATAPI %dbytes, ", sata->atapi);
1031 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1032 printf("PIO %dbytes", sata->bytecount);
1036 if (ccb->cts.protocol == PROTO_SCSI) {
1037 struct ccb_trans_settings_scsi *scsi =
1038 &ccb->cts.proto_specific.scsi;
1039 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1040 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1041 fprintf(stdout, ", Command Queueing Enabled");
1046 fprintf(stdout, "\n");
1056 atacapprint(struct ata_params *parm)
1058 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1059 ((u_int32_t)parm->lba_size_2 << 16);
1061 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1062 ((u_int64_t)parm->lba_size48_2 << 16) |
1063 ((u_int64_t)parm->lba_size48_3 << 32) |
1064 ((u_int64_t)parm->lba_size48_4 << 48);
1067 printf("protocol ");
1068 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1069 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1070 if (parm->satacapabilities & ATA_SATA_GEN3)
1071 printf(" SATA 3.x\n");
1072 else if (parm->satacapabilities & ATA_SATA_GEN2)
1073 printf(" SATA 2.x\n");
1074 else if (parm->satacapabilities & ATA_SATA_GEN1)
1075 printf(" SATA 1.x\n");
1081 printf("device model %.40s\n", parm->model);
1082 printf("firmware revision %.8s\n", parm->revision);
1083 printf("serial number %.20s\n", parm->serial);
1084 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1085 printf("WWN %02x%02x%02x%02x\n",
1086 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1088 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1089 printf("media serial number %.30s\n",
1090 parm->media_serial);
1093 printf("cylinders %d\n", parm->cylinders);
1094 printf("heads %d\n", parm->heads);
1095 printf("sectors/track %d\n", parm->sectors);
1096 printf("sector size logical %u, physical %lu, offset %lu\n",
1097 ata_logical_sector_size(parm),
1098 (unsigned long)ata_physical_sector_size(parm),
1099 (unsigned long)ata_logical_sector_offset(parm));
1101 if (parm->config == ATA_PROTO_CFA ||
1102 (parm->support.command2 & ATA_SUPPORT_CFA))
1103 printf("CFA supported\n");
1105 printf("LBA%ssupported ",
1106 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1108 printf("%d sectors\n", lbasize);
1112 printf("LBA48%ssupported ",
1113 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1115 printf("%ju sectors\n", (uintmax_t)lbasize48);
1119 printf("PIO supported PIO");
1120 switch (ata_max_pmode(parm)) {
1136 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1137 printf(" w/o IORDY");
1140 printf("DMA%ssupported ",
1141 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1142 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1143 if (parm->mwdmamodes & 0xff) {
1145 if (parm->mwdmamodes & 0x04)
1147 else if (parm->mwdmamodes & 0x02)
1149 else if (parm->mwdmamodes & 0x01)
1153 if ((parm->atavalid & ATA_FLAG_88) &&
1154 (parm->udmamodes & 0xff)) {
1156 if (parm->udmamodes & 0x40)
1158 else if (parm->udmamodes & 0x20)
1160 else if (parm->udmamodes & 0x10)
1162 else if (parm->udmamodes & 0x08)
1164 else if (parm->udmamodes & 0x04)
1166 else if (parm->udmamodes & 0x02)
1168 else if (parm->udmamodes & 0x01)
1175 if (parm->media_rotation_rate == 1) {
1176 printf("media RPM non-rotating\n");
1177 } else if (parm->media_rotation_rate >= 0x0401 &&
1178 parm->media_rotation_rate <= 0xFFFE) {
1179 printf("media RPM %d\n",
1180 parm->media_rotation_rate);
1184 "Support Enable 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 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1205 printf("Native Command Queuing (NCQ) %s ",
1206 parm->satacapabilities & ATA_SUPPORT_NCQ ?
1208 if (parm->satacapabilities & ATA_SUPPORT_NCQ) {
1209 printf(" %d tags\n",
1210 ATA_QUEUE_LEN(parm->queue) + 1);
1214 printf("SMART %s %s\n",
1215 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1216 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1217 printf("microcode download %s %s\n",
1218 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1219 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1220 printf("security %s %s\n",
1221 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1222 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1223 printf("power management %s %s\n",
1224 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1225 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1226 printf("advanced power management %s %s %d/0x%02X\n",
1227 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1228 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1229 parm->apm_value, parm->apm_value);
1230 printf("automatic acoustic management %s %s "
1231 "%d/0x%02X %d/0x%02X\n",
1232 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1233 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1234 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1235 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1236 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1237 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1238 printf("media status notification %s %s\n",
1239 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1240 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1241 printf("power-up in Standby %s %s\n",
1242 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1243 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1244 printf("write-read-verify %s %s %d/0x%x\n",
1245 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1246 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1247 parm->wrv_mode, parm->wrv_mode);
1248 printf("unload %s %s\n",
1249 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1250 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1251 printf("free-fall %s %s\n",
1252 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1253 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1254 printf("data set management (TRIM) %s\n",
1255 parm->support_dsm & ATA_SUPPORT_DSM_TRIM ? "yes" : "no");
1260 ataidentify(struct cam_device *device, int retry_count, int timeout)
1263 struct ata_params *ident_buf;
1264 struct ccb_getdev cgd;
1268 if (get_cgd(device, &cgd) != 0) {
1269 warnx("couldn't get CGD");
1272 ccb = cam_getccb(device);
1275 warnx("couldn't allocate CCB");
1279 /* cam_getccb cleans up the header, caller has to zero the payload */
1280 bzero(&(&ccb->ccb_h)[1],
1281 sizeof(struct ccb_ataio) - sizeof(struct ccb_hdr));
1283 ptr = (uint16_t *)malloc(sizeof(struct ata_params));
1287 warnx("can't malloc memory for identify\n");
1290 bzero(ptr, sizeof(struct ata_params));
1292 cam_fill_ataio(&ccb->ataio,
1295 /*flags*/CAM_DIR_IN,
1297 /*data_ptr*/(u_int8_t *)ptr,
1298 /*dxfer_len*/sizeof(struct ata_params),
1299 timeout ? timeout : 30 * 1000);
1300 if (cgd.protocol == PROTO_ATA)
1301 ata_28bit_cmd(&ccb->ataio, ATA_ATA_IDENTIFY, 0, 0, 0);
1303 ata_28bit_cmd(&ccb->ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0);
1305 /* Disable freezing the device queue */
1306 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1308 if (arglist & CAM_ARG_ERR_RECOVER)
1309 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1311 if (cam_send_ccb(device, ccb) < 0) {
1312 perror("error sending ATA identify");
1314 if (arglist & CAM_ARG_VERBOSE) {
1315 cam_error_print(device, ccb, CAM_ESF_ALL,
1316 CAM_EPF_ALL, stderr);
1324 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1327 if (arglist & CAM_ARG_VERBOSE) {
1328 cam_error_print(device, ccb, CAM_ESF_ALL,
1329 CAM_EPF_ALL, stderr);
1340 for (i = 0; i < sizeof(struct ata_params) / 2; i++)
1341 ptr[i] = le16toh(ptr[i]);
1342 if (arglist & CAM_ARG_VERBOSE) {
1343 fprintf(stdout, "%s%d: Raw identify data:\n",
1344 device->device_name, device->dev_unit_num);
1345 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
1347 fprintf(stdout, " %3d: ", i);
1348 fprintf(stdout, "%04x ", (uint16_t)ptr[i]);
1350 fprintf(stdout, "\n");
1353 ident_buf = (struct ata_params *)ptr;
1354 if (strncmp(ident_buf->model, "FX", 2) &&
1355 strncmp(ident_buf->model, "NEC", 3) &&
1356 strncmp(ident_buf->model, "Pioneer", 7) &&
1357 strncmp(ident_buf->model, "SHARP", 5)) {
1358 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
1359 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
1360 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
1361 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
1363 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
1364 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
1365 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
1366 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
1367 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
1368 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
1369 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
1370 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
1371 sizeof(ident_buf->media_serial));
1373 fprintf(stdout, "%s%d: ", device->device_name,
1374 device->dev_unit_num);
1375 ata_print_ident(ident_buf);
1376 camxferrate(device);
1377 atacapprint(ident_buf);
1383 #endif /* MINIMALISTIC */
1386 * Parse out a bus, or a bus, target and lun in the following
1392 * Returns the number of parsed components, or 0.
1395 parse_btl(char *tstr, int *bus, int *target, int *lun, cam_argmask *arglst)
1400 while (isspace(*tstr) && (*tstr != '\0'))
1403 tmpstr = (char *)strtok(tstr, ":");
1404 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
1405 *bus = strtol(tmpstr, NULL, 0);
1406 *arglst |= CAM_ARG_BUS;
1408 tmpstr = (char *)strtok(NULL, ":");
1409 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
1410 *target = strtol(tmpstr, NULL, 0);
1411 *arglst |= CAM_ARG_TARGET;
1413 tmpstr = (char *)strtok(NULL, ":");
1414 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
1415 *lun = strtol(tmpstr, NULL, 0);
1416 *arglst |= CAM_ARG_LUN;
1426 dorescan_or_reset(int argc, char **argv, int rescan)
1428 static const char must[] =
1429 "you must specify \"all\", a bus, or a bus:target:lun to %s";
1431 int bus = -1, target = -1, lun = -1;
1435 warnx(must, rescan? "rescan" : "reset");
1439 tstr = argv[optind];
1440 while (isspace(*tstr) && (*tstr != '\0'))
1442 if (strncasecmp(tstr, "all", strlen("all")) == 0)
1443 arglist |= CAM_ARG_BUS;
1445 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
1446 if (rv != 1 && rv != 3) {
1447 warnx(must, rescan? "rescan" : "reset");
1452 if ((arglist & CAM_ARG_BUS)
1453 && (arglist & CAM_ARG_TARGET)
1454 && (arglist & CAM_ARG_LUN))
1455 error = scanlun_or_reset_dev(bus, target, lun, rescan);
1457 error = rescan_or_reset_bus(bus, rescan);
1463 rescan_or_reset_bus(int bus, int rescan)
1465 union ccb ccb, matchccb;
1471 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
1472 warnx("error opening transport layer device %s", XPT_DEVICE);
1473 warn("%s", XPT_DEVICE);
1478 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
1479 ccb.ccb_h.path_id = bus;
1480 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
1481 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
1482 ccb.crcn.flags = CAM_FLAG_NONE;
1484 /* run this at a low priority */
1485 ccb.ccb_h.pinfo.priority = 5;
1487 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
1488 warn("CAMIOCOMMAND ioctl failed");
1493 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
1494 fprintf(stdout, "%s of bus %d was successful\n",
1495 rescan ? "Re-scan" : "Reset", bus);
1497 fprintf(stdout, "%s of bus %d returned error %#x\n",
1498 rescan ? "Re-scan" : "Reset", bus,
1499 ccb.ccb_h.status & CAM_STATUS_MASK);
1510 * The right way to handle this is to modify the xpt so that it can
1511 * handle a wildcarded bus in a rescan or reset CCB. At the moment
1512 * that isn't implemented, so instead we enumerate the busses and
1513 * send the rescan or reset to those busses in the case where the
1514 * given bus is -1 (wildcard). We don't send a rescan or reset
1515 * to the xpt bus; sending a rescan to the xpt bus is effectively a
1516 * no-op, sending a rescan to the xpt bus would result in a status of
1519 bzero(&(&matchccb.ccb_h)[1],
1520 sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr));
1521 matchccb.ccb_h.func_code = XPT_DEV_MATCH;
1522 bufsize = sizeof(struct dev_match_result) * 20;
1523 matchccb.cdm.match_buf_len = bufsize;
1524 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
1525 if (matchccb.cdm.matches == NULL) {
1526 warnx("can't malloc memory for matches");
1530 matchccb.cdm.num_matches = 0;
1532 matchccb.cdm.num_patterns = 1;
1533 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
1535 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
1536 matchccb.cdm.pattern_buf_len);
1537 if (matchccb.cdm.patterns == NULL) {
1538 warnx("can't malloc memory for patterns");
1542 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
1543 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
1548 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
1549 warn("CAMIOCOMMAND ioctl failed");
1554 if ((matchccb.ccb_h.status != CAM_REQ_CMP)
1555 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
1556 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
1557 warnx("got CAM error %#x, CDM error %d\n",
1558 matchccb.ccb_h.status, matchccb.cdm.status);
1563 for (i = 0; i < matchccb.cdm.num_matches; i++) {
1564 struct bus_match_result *bus_result;
1566 /* This shouldn't happen. */
1567 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
1570 bus_result = &matchccb.cdm.matches[i].result.bus_result;
1573 * We don't want to rescan or reset the xpt bus.
1576 if ((int)bus_result->path_id == -1)
1579 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
1581 ccb.ccb_h.path_id = bus_result->path_id;
1582 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
1583 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
1584 ccb.crcn.flags = CAM_FLAG_NONE;
1586 /* run this at a low priority */
1587 ccb.ccb_h.pinfo.priority = 5;
1589 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
1590 warn("CAMIOCOMMAND ioctl failed");
1595 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
1596 fprintf(stdout, "%s of bus %d was successful\n",
1597 rescan? "Re-scan" : "Reset",
1598 bus_result->path_id);
1601 * Don't bail out just yet, maybe the other
1602 * rescan or reset commands will complete
1605 fprintf(stderr, "%s of bus %d returned error "
1606 "%#x\n", rescan? "Re-scan" : "Reset",
1607 bus_result->path_id,
1608 ccb.ccb_h.status & CAM_STATUS_MASK);
1612 } while ((matchccb.ccb_h.status == CAM_REQ_CMP)
1613 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
1620 if (matchccb.cdm.patterns != NULL)
1621 free(matchccb.cdm.patterns);
1622 if (matchccb.cdm.matches != NULL)
1623 free(matchccb.cdm.matches);
1629 scanlun_or_reset_dev(int bus, int target, int lun, int scan)
1632 struct cam_device *device;
1638 warnx("invalid bus number %d", bus);
1643 warnx("invalid target number %d", target);
1648 warnx("invalid lun number %d", lun);
1654 bzero(&ccb, sizeof(union ccb));
1657 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
1658 warnx("error opening transport layer device %s\n",
1660 warn("%s", XPT_DEVICE);
1664 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
1665 if (device == NULL) {
1666 warnx("%s", cam_errbuf);
1671 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
1672 ccb.ccb_h.path_id = bus;
1673 ccb.ccb_h.target_id = target;
1674 ccb.ccb_h.target_lun = lun;
1675 ccb.ccb_h.timeout = 5000;
1676 ccb.crcn.flags = CAM_FLAG_NONE;
1678 /* run this at a low priority */
1679 ccb.ccb_h.pinfo.priority = 5;
1682 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
1683 warn("CAMIOCOMMAND ioctl failed");
1688 if (cam_send_ccb(device, &ccb) < 0) {
1689 warn("error sending XPT_RESET_DEV CCB");
1690 cam_close_device(device);
1698 cam_close_device(device);
1701 * An error code of CAM_BDR_SENT is normal for a BDR request.
1703 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
1705 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
1706 fprintf(stdout, "%s of %d:%d:%d was successful\n",
1707 scan? "Re-scan" : "Reset", bus, target, lun);
1710 fprintf(stdout, "%s of %d:%d:%d returned error %#x\n",
1711 scan? "Re-scan" : "Reset", bus, target, lun,
1712 ccb.ccb_h.status & CAM_STATUS_MASK);
1717 #ifndef MINIMALISTIC
1719 readdefects(struct cam_device *device, int argc, char **argv,
1720 char *combinedopt, int retry_count, int timeout)
1722 union ccb *ccb = NULL;
1723 struct scsi_read_defect_data_10 *rdd_cdb;
1724 u_int8_t *defect_list = NULL;
1725 u_int32_t dlist_length = 65000;
1726 u_int32_t returned_length = 0;
1727 u_int32_t num_returned = 0;
1728 u_int8_t returned_format;
1731 int lists_specified = 0;
1733 while ((c = getopt(argc, argv, combinedopt)) != -1) {
1739 while (isspace(*tstr) && (*tstr != '\0'))
1741 if (strcmp(tstr, "block") == 0)
1742 arglist |= CAM_ARG_FORMAT_BLOCK;
1743 else if (strcmp(tstr, "bfi") == 0)
1744 arglist |= CAM_ARG_FORMAT_BFI;
1745 else if (strcmp(tstr, "phys") == 0)
1746 arglist |= CAM_ARG_FORMAT_PHYS;
1749 warnx("invalid defect format %s", tstr);
1750 goto defect_bailout;
1755 arglist |= CAM_ARG_GLIST;
1758 arglist |= CAM_ARG_PLIST;
1765 ccb = cam_getccb(device);
1768 * Hopefully 65000 bytes is enough to hold the defect list. If it
1769 * isn't, the disk is probably dead already. We'd have to go with
1770 * 12 byte command (i.e. alloc_length is 32 bits instead of 16)
1773 defect_list = malloc(dlist_length);
1774 if (defect_list == NULL) {
1775 warnx("can't malloc memory for defect list");
1777 goto defect_bailout;
1780 rdd_cdb =(struct scsi_read_defect_data_10 *)&ccb->csio.cdb_io.cdb_bytes;
1783 * cam_getccb() zeros the CCB header only. So we need to zero the
1784 * payload portion of the ccb.
1786 bzero(&(&ccb->ccb_h)[1],
1787 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1789 cam_fill_csio(&ccb->csio,
1790 /*retries*/ retry_count,
1792 /*flags*/ CAM_DIR_IN | ((arglist & CAM_ARG_ERR_RECOVER) ?
1793 CAM_PASS_ERR_RECOVER : 0),
1794 /*tag_action*/ MSG_SIMPLE_Q_TAG,
1795 /*data_ptr*/ defect_list,
1796 /*dxfer_len*/ dlist_length,
1797 /*sense_len*/ SSD_FULL_SIZE,
1798 /*cdb_len*/ sizeof(struct scsi_read_defect_data_10),
1799 /*timeout*/ timeout ? timeout : 5000);
1801 rdd_cdb->opcode = READ_DEFECT_DATA_10;
1802 if (arglist & CAM_ARG_FORMAT_BLOCK)
1803 rdd_cdb->format = SRDD10_BLOCK_FORMAT;
1804 else if (arglist & CAM_ARG_FORMAT_BFI)
1805 rdd_cdb->format = SRDD10_BYTES_FROM_INDEX_FORMAT;
1806 else if (arglist & CAM_ARG_FORMAT_PHYS)
1807 rdd_cdb->format = SRDD10_PHYSICAL_SECTOR_FORMAT;
1810 warnx("no defect list format specified");
1811 goto defect_bailout;
1813 if (arglist & CAM_ARG_PLIST) {
1814 rdd_cdb->format |= SRDD10_PLIST;
1818 if (arglist & CAM_ARG_GLIST) {
1819 rdd_cdb->format |= SRDD10_GLIST;
1823 scsi_ulto2b(dlist_length, rdd_cdb->alloc_length);
1825 /* Disable freezing the device queue */
1826 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1828 if (cam_send_ccb(device, ccb) < 0) {
1829 perror("error reading defect list");
1831 if (arglist & CAM_ARG_VERBOSE) {
1832 cam_error_print(device, ccb, CAM_ESF_ALL,
1833 CAM_EPF_ALL, stderr);
1837 goto defect_bailout;
1840 returned_length = scsi_2btoul(((struct
1841 scsi_read_defect_data_hdr_10 *)defect_list)->length);
1843 returned_format = ((struct scsi_read_defect_data_hdr_10 *)
1844 defect_list)->format;
1846 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
1847 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
1848 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
1849 struct scsi_sense_data *sense;
1850 int error_code, sense_key, asc, ascq;
1852 sense = &ccb->csio.sense_data;
1853 scsi_extract_sense(sense, &error_code, &sense_key, &asc, &ascq);
1856 * According to the SCSI spec, if the disk doesn't support
1857 * the requested format, it will generally return a sense
1858 * key of RECOVERED ERROR, and an additional sense code
1859 * of "DEFECT LIST NOT FOUND". So, we check for that, and
1860 * also check to make sure that the returned length is
1861 * greater than 0, and then print out whatever format the
1864 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
1865 && (asc == 0x1c) && (ascq == 0x00)
1866 && (returned_length > 0)) {
1867 warnx("requested defect format not available");
1868 switch(returned_format & SRDDH10_DLIST_FORMAT_MASK) {
1869 case SRDD10_BLOCK_FORMAT:
1870 warnx("Device returned block format");
1872 case SRDD10_BYTES_FROM_INDEX_FORMAT:
1873 warnx("Device returned bytes from index"
1876 case SRDD10_PHYSICAL_SECTOR_FORMAT:
1877 warnx("Device returned physical sector format");
1881 warnx("Device returned unknown defect"
1882 " data format %#x", returned_format);
1883 goto defect_bailout;
1884 break; /* NOTREACHED */
1888 warnx("Error returned from read defect data command");
1889 if (arglist & CAM_ARG_VERBOSE)
1890 cam_error_print(device, ccb, CAM_ESF_ALL,
1891 CAM_EPF_ALL, stderr);
1892 goto defect_bailout;
1894 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
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;
1904 * XXX KDM I should probably clean up the printout format for the
1907 switch (returned_format & SRDDH10_DLIST_FORMAT_MASK){
1908 case SRDDH10_PHYSICAL_SECTOR_FORMAT:
1910 struct scsi_defect_desc_phys_sector *dlist;
1912 dlist = (struct scsi_defect_desc_phys_sector *)
1914 sizeof(struct scsi_read_defect_data_hdr_10));
1916 num_returned = returned_length /
1917 sizeof(struct scsi_defect_desc_phys_sector);
1919 fprintf(stderr, "Got %d defect", num_returned);
1921 if ((lists_specified == 0) || (num_returned == 0)) {
1922 fprintf(stderr, "s.\n");
1924 } else if (num_returned == 1)
1925 fprintf(stderr, ":\n");
1927 fprintf(stderr, "s:\n");
1929 for (i = 0; i < num_returned; i++) {
1930 fprintf(stdout, "%d:%d:%d\n",
1931 scsi_3btoul(dlist[i].cylinder),
1933 scsi_4btoul(dlist[i].sector));
1937 case SRDDH10_BYTES_FROM_INDEX_FORMAT:
1939 struct scsi_defect_desc_bytes_from_index *dlist;
1941 dlist = (struct scsi_defect_desc_bytes_from_index *)
1943 sizeof(struct scsi_read_defect_data_hdr_10));
1945 num_returned = returned_length /
1946 sizeof(struct scsi_defect_desc_bytes_from_index);
1948 fprintf(stderr, "Got %d defect", num_returned);
1950 if ((lists_specified == 0) || (num_returned == 0)) {
1951 fprintf(stderr, "s.\n");
1953 } else if (num_returned == 1)
1954 fprintf(stderr, ":\n");
1956 fprintf(stderr, "s:\n");
1958 for (i = 0; i < num_returned; i++) {
1959 fprintf(stdout, "%d:%d:%d\n",
1960 scsi_3btoul(dlist[i].cylinder),
1962 scsi_4btoul(dlist[i].bytes_from_index));
1966 case SRDDH10_BLOCK_FORMAT:
1968 struct scsi_defect_desc_block *dlist;
1970 dlist = (struct scsi_defect_desc_block *)(defect_list +
1971 sizeof(struct scsi_read_defect_data_hdr_10));
1973 num_returned = returned_length /
1974 sizeof(struct scsi_defect_desc_block);
1976 fprintf(stderr, "Got %d defect", num_returned);
1978 if ((lists_specified == 0) || (num_returned == 0)) {
1979 fprintf(stderr, "s.\n");
1981 } else if (num_returned == 1)
1982 fprintf(stderr, ":\n");
1984 fprintf(stderr, "s:\n");
1986 for (i = 0; i < num_returned; i++)
1987 fprintf(stdout, "%u\n",
1988 scsi_4btoul(dlist[i].address));
1992 fprintf(stderr, "Unknown defect format %d\n",
1993 returned_format & SRDDH10_DLIST_FORMAT_MASK);
1999 if (defect_list != NULL)
2007 #endif /* MINIMALISTIC */
2011 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
2015 ccb = cam_getccb(device);
2021 #ifndef MINIMALISTIC
2023 mode_sense(struct cam_device *device, int mode_page, int page_control,
2024 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
2029 ccb = cam_getccb(device);
2032 errx(1, "mode_sense: couldn't allocate CCB");
2034 bzero(&(&ccb->ccb_h)[1],
2035 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
2037 scsi_mode_sense(&ccb->csio,
2038 /* retries */ retry_count,
2040 /* tag_action */ MSG_SIMPLE_Q_TAG,
2042 /* page_code */ page_control << 6,
2043 /* page */ mode_page,
2044 /* param_buf */ data,
2045 /* param_len */ datalen,
2046 /* sense_len */ SSD_FULL_SIZE,
2047 /* timeout */ timeout ? timeout : 5000);
2049 if (arglist & CAM_ARG_ERR_RECOVER)
2050 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
2052 /* Disable freezing the device queue */
2053 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
2055 if (((retval = cam_send_ccb(device, ccb)) < 0)
2056 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
2057 if (arglist & CAM_ARG_VERBOSE) {
2058 cam_error_print(device, ccb, CAM_ESF_ALL,
2059 CAM_EPF_ALL, stderr);
2062 cam_close_device(device);
2064 err(1, "error sending mode sense command");
2066 errx(1, "error sending mode sense command");
2073 mode_select(struct cam_device *device, int save_pages, int retry_count,
2074 int timeout, u_int8_t *data, int datalen)
2079 ccb = cam_getccb(device);
2082 errx(1, "mode_select: couldn't allocate CCB");
2084 bzero(&(&ccb->ccb_h)[1],
2085 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
2087 scsi_mode_select(&ccb->csio,
2088 /* retries */ retry_count,
2090 /* tag_action */ MSG_SIMPLE_Q_TAG,
2091 /* scsi_page_fmt */ 1,
2092 /* save_pages */ save_pages,
2093 /* param_buf */ data,
2094 /* param_len */ datalen,
2095 /* sense_len */ SSD_FULL_SIZE,
2096 /* timeout */ timeout ? timeout : 5000);
2098 if (arglist & CAM_ARG_ERR_RECOVER)
2099 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
2101 /* Disable freezing the device queue */
2102 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
2104 if (((retval = cam_send_ccb(device, ccb)) < 0)
2105 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
2106 if (arglist & CAM_ARG_VERBOSE) {
2107 cam_error_print(device, ccb, CAM_ESF_ALL,
2108 CAM_EPF_ALL, stderr);
2111 cam_close_device(device);
2114 err(1, "error sending mode select command");
2116 errx(1, "error sending mode select command");
2124 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
2125 int retry_count, int timeout)
2127 int c, mode_page = -1, page_control = 0;
2128 int binary = 0, list = 0;
2130 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2136 arglist |= CAM_ARG_DBD;
2139 arglist |= CAM_ARG_MODE_EDIT;
2145 mode_page = strtol(optarg, NULL, 0);
2147 errx(1, "invalid mode page %d", mode_page);
2150 page_control = strtol(optarg, NULL, 0);
2151 if ((page_control < 0) || (page_control > 3))
2152 errx(1, "invalid page control field %d",
2154 arglist |= CAM_ARG_PAGE_CNTL;
2161 if (mode_page == -1 && list == 0)
2162 errx(1, "you must specify a mode page!");
2165 mode_list(device, page_control, arglist & CAM_ARG_DBD,
2166 retry_count, timeout);
2168 mode_edit(device, mode_page, page_control,
2169 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
2170 retry_count, timeout);
2175 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
2176 int retry_count, int timeout)
2179 u_int32_t flags = CAM_DIR_NONE;
2180 u_int8_t *data_ptr = NULL;
2182 u_int8_t atacmd[12];
2183 struct get_hook hook;
2184 int c, data_bytes = 0;
2190 char *datastr = NULL, *tstr, *resstr = NULL;
2192 int fd_data = 0, fd_res = 0;
2195 ccb = cam_getccb(device);
2198 warnx("scsicmd: error allocating ccb");
2202 bzero(&(&ccb->ccb_h)[1],
2203 sizeof(union ccb) - sizeof(struct ccb_hdr));
2205 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2209 while (isspace(*tstr) && (*tstr != '\0'))
2211 hook.argc = argc - optind;
2212 hook.argv = argv + optind;
2214 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
2217 * Increment optind by the number of arguments the
2218 * encoding routine processed. After each call to
2219 * getopt(3), optind points to the argument that
2220 * getopt should process _next_. In this case,
2221 * that means it points to the first command string
2222 * argument, if there is one. Once we increment
2223 * this, it should point to either the next command
2224 * line argument, or it should be past the end of
2231 while (isspace(*tstr) && (*tstr != '\0'))
2233 hook.argc = argc - optind;
2234 hook.argv = argv + optind;
2236 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
2239 * Increment optind by the number of arguments the
2240 * encoding routine processed. After each call to
2241 * getopt(3), optind points to the argument that
2242 * getopt should process _next_. In this case,
2243 * that means it points to the first command string
2244 * argument, if there is one. Once we increment
2245 * this, it should point to either the next command
2246 * line argument, or it should be past the end of
2258 if (arglist & CAM_ARG_CMD_OUT) {
2259 warnx("command must either be "
2260 "read or write, not both");
2262 goto scsicmd_bailout;
2264 arglist |= CAM_ARG_CMD_IN;
2266 data_bytes = strtol(optarg, NULL, 0);
2267 if (data_bytes <= 0) {
2268 warnx("invalid number of input bytes %d",
2271 goto scsicmd_bailout;
2273 hook.argc = argc - optind;
2274 hook.argv = argv + optind;
2277 datastr = cget(&hook, NULL);
2279 * If the user supplied "-" instead of a format, he
2280 * wants the data to be written to stdout.
2282 if ((datastr != NULL)
2283 && (datastr[0] == '-'))
2286 data_ptr = (u_int8_t *)malloc(data_bytes);
2287 if (data_ptr == NULL) {
2288 warnx("can't malloc memory for data_ptr");
2290 goto scsicmd_bailout;
2294 if (arglist & CAM_ARG_CMD_IN) {
2295 warnx("command must either be "
2296 "read or write, not both");
2298 goto scsicmd_bailout;
2300 arglist |= CAM_ARG_CMD_OUT;
2301 flags = CAM_DIR_OUT;
2302 data_bytes = strtol(optarg, NULL, 0);
2303 if (data_bytes <= 0) {
2304 warnx("invalid number of output bytes %d",
2307 goto scsicmd_bailout;
2309 hook.argc = argc - optind;
2310 hook.argv = argv + optind;
2312 datastr = cget(&hook, NULL);
2313 data_ptr = (u_int8_t *)malloc(data_bytes);
2314 if (data_ptr == NULL) {
2315 warnx("can't malloc memory for data_ptr");
2317 goto scsicmd_bailout;
2319 bzero(data_ptr, data_bytes);
2321 * If the user supplied "-" instead of a format, he
2322 * wants the data to be read from stdin.
2324 if ((datastr != NULL)
2325 && (datastr[0] == '-'))
2328 buff_encode_visit(data_ptr, data_bytes, datastr,
2334 hook.argc = argc - optind;
2335 hook.argv = argv + optind;
2337 resstr = cget(&hook, NULL);
2338 if ((resstr != NULL) && (resstr[0] == '-'))
2348 * If fd_data is set, and we're writing to the device, we need to
2349 * read the data the user wants written from stdin.
2351 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
2353 int amt_to_read = data_bytes;
2354 u_int8_t *buf_ptr = data_ptr;
2356 for (amt_read = 0; amt_to_read > 0;
2357 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
2358 if (amt_read == -1) {
2359 warn("error reading data from stdin");
2361 goto scsicmd_bailout;
2363 amt_to_read -= amt_read;
2364 buf_ptr += amt_read;
2368 if (arglist & CAM_ARG_ERR_RECOVER)
2369 flags |= CAM_PASS_ERR_RECOVER;
2371 /* Disable freezing the device queue */
2372 flags |= CAM_DEV_QFRZDIS;
2376 * This is taken from the SCSI-3 draft spec.
2377 * (T10/1157D revision 0.3)
2378 * The top 3 bits of an opcode are the group code.
2379 * The next 5 bits are the command code.
2380 * Group 0: six byte commands
2381 * Group 1: ten byte commands
2382 * Group 2: ten byte commands
2384 * Group 4: sixteen byte commands
2385 * Group 5: twelve byte commands
2386 * Group 6: vendor specific
2387 * Group 7: vendor specific
2389 switch((cdb[0] >> 5) & 0x7) {
2400 /* computed by buff_encode_visit */
2411 * We should probably use csio_build_visit or something like that
2412 * here, but it's easier to encode arguments as you go. The
2413 * alternative would be skipping the CDB argument and then encoding
2414 * it here, since we've got the data buffer argument by now.
2416 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
2418 cam_fill_csio(&ccb->csio,
2419 /*retries*/ retry_count,
2422 /*tag_action*/ MSG_SIMPLE_Q_TAG,
2423 /*data_ptr*/ data_ptr,
2424 /*dxfer_len*/ data_bytes,
2425 /*sense_len*/ SSD_FULL_SIZE,
2426 /*cdb_len*/ cdb_len,
2427 /*timeout*/ timeout ? timeout : 5000);
2430 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
2432 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
2434 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
2436 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
2438 cam_fill_ataio(&ccb->ataio,
2439 /*retries*/ retry_count,
2443 /*data_ptr*/ data_ptr,
2444 /*dxfer_len*/ data_bytes,
2445 /*timeout*/ timeout ? timeout : 5000);
2448 if (((retval = cam_send_ccb(device, ccb)) < 0)
2449 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
2451 warn("error sending command");
2453 warnx("error sending command");
2455 if (arglist & CAM_ARG_VERBOSE) {
2456 cam_error_print(device, ccb, CAM_ESF_ALL,
2457 CAM_EPF_ALL, stderr);
2461 goto scsicmd_bailout;
2464 if (atacmd_len && need_res) {
2466 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
2468 fprintf(stdout, "\n");
2471 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
2472 ccb->ataio.res.status,
2473 ccb->ataio.res.error,
2474 ccb->ataio.res.lba_low,
2475 ccb->ataio.res.lba_mid,
2476 ccb->ataio.res.lba_high,
2477 ccb->ataio.res.device,
2478 ccb->ataio.res.lba_low_exp,
2479 ccb->ataio.res.lba_mid_exp,
2480 ccb->ataio.res.lba_high_exp,
2481 ccb->ataio.res.sector_count,
2482 ccb->ataio.res.sector_count_exp);
2487 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
2488 && (arglist & CAM_ARG_CMD_IN)
2489 && (data_bytes > 0)) {
2491 buff_decode_visit(data_ptr, data_bytes, datastr,
2493 fprintf(stdout, "\n");
2495 ssize_t amt_written;
2496 int amt_to_write = data_bytes;
2497 u_int8_t *buf_ptr = data_ptr;
2499 for (amt_written = 0; (amt_to_write > 0) &&
2500 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
2501 amt_to_write -= amt_written;
2502 buf_ptr += amt_written;
2504 if (amt_written == -1) {
2505 warn("error writing data to stdout");
2507 goto scsicmd_bailout;
2508 } else if ((amt_written == 0)
2509 && (amt_to_write > 0)) {
2510 warnx("only wrote %u bytes out of %u",
2511 data_bytes - amt_to_write, data_bytes);
2518 if ((data_bytes > 0) && (data_ptr != NULL))
2527 camdebug(int argc, char **argv, char *combinedopt)
2530 int bus = -1, target = -1, lun = -1;
2531 char *tstr, *tmpstr = NULL;
2535 bzero(&ccb, sizeof(union ccb));
2537 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2540 arglist |= CAM_ARG_DEBUG_INFO;
2541 ccb.cdbg.flags |= CAM_DEBUG_INFO;
2544 arglist |= CAM_ARG_DEBUG_PERIPH;
2545 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
2548 arglist |= CAM_ARG_DEBUG_SUBTRACE;
2549 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
2552 arglist |= CAM_ARG_DEBUG_TRACE;
2553 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
2556 arglist |= CAM_ARG_DEBUG_XPT;
2557 ccb.cdbg.flags |= CAM_DEBUG_XPT;
2560 arglist |= CAM_ARG_DEBUG_CDB;
2561 ccb.cdbg.flags |= CAM_DEBUG_CDB;
2568 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
2569 warnx("error opening transport layer device %s", XPT_DEVICE);
2570 warn("%s", XPT_DEVICE);
2577 warnx("you must specify \"off\", \"all\" or a bus,");
2578 warnx("bus:target, or bus:target:lun");
2585 while (isspace(*tstr) && (*tstr != '\0'))
2588 if (strncmp(tstr, "off", 3) == 0) {
2589 ccb.cdbg.flags = CAM_DEBUG_NONE;
2590 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
2591 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
2593 } else if (strncmp(tstr, "all", 3) != 0) {
2594 tmpstr = (char *)strtok(tstr, ":");
2595 if ((tmpstr != NULL) && (*tmpstr != '\0')){
2596 bus = strtol(tmpstr, NULL, 0);
2597 arglist |= CAM_ARG_BUS;
2598 tmpstr = (char *)strtok(NULL, ":");
2599 if ((tmpstr != NULL) && (*tmpstr != '\0')){
2600 target = strtol(tmpstr, NULL, 0);
2601 arglist |= CAM_ARG_TARGET;
2602 tmpstr = (char *)strtok(NULL, ":");
2603 if ((tmpstr != NULL) && (*tmpstr != '\0')){
2604 lun = strtol(tmpstr, NULL, 0);
2605 arglist |= CAM_ARG_LUN;
2610 warnx("you must specify \"all\", \"off\", or a bus,");
2611 warnx("bus:target, or bus:target:lun to debug");
2617 ccb.ccb_h.func_code = XPT_DEBUG;
2618 ccb.ccb_h.path_id = bus;
2619 ccb.ccb_h.target_id = target;
2620 ccb.ccb_h.target_lun = lun;
2622 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
2623 warn("CAMIOCOMMAND ioctl failed");
2628 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
2629 CAM_FUNC_NOTAVAIL) {
2630 warnx("CAM debugging not available");
2631 warnx("you need to put options CAMDEBUG in"
2632 " your kernel config file!");
2634 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
2636 warnx("XPT_DEBUG CCB failed with status %#x",
2640 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
2642 "Debugging turned off\n");
2645 "Debugging enabled for "
2658 tagcontrol(struct cam_device *device, int argc, char **argv,
2668 ccb = cam_getccb(device);
2671 warnx("tagcontrol: error allocating ccb");
2675 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2678 numtags = strtol(optarg, NULL, 0);
2680 warnx("tag count %d is < 0", numtags);
2682 goto tagcontrol_bailout;
2693 cam_path_string(device, pathstr, sizeof(pathstr));
2696 bzero(&(&ccb->ccb_h)[1],
2697 sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
2698 ccb->ccb_h.func_code = XPT_REL_SIMQ;
2699 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
2700 ccb->crs.openings = numtags;
2703 if (cam_send_ccb(device, ccb) < 0) {
2704 perror("error sending XPT_REL_SIMQ CCB");
2706 goto tagcontrol_bailout;
2709 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2710 warnx("XPT_REL_SIMQ CCB failed");
2711 cam_error_print(device, ccb, CAM_ESF_ALL,
2712 CAM_EPF_ALL, stderr);
2714 goto tagcontrol_bailout;
2719 fprintf(stdout, "%stagged openings now %d\n",
2720 pathstr, ccb->crs.openings);
2723 bzero(&(&ccb->ccb_h)[1],
2724 sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr));
2726 ccb->ccb_h.func_code = XPT_GDEV_STATS;
2728 if (cam_send_ccb(device, ccb) < 0) {
2729 perror("error sending XPT_GDEV_STATS CCB");
2731 goto tagcontrol_bailout;
2734 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2735 warnx("XPT_GDEV_STATS CCB failed");
2736 cam_error_print(device, ccb, CAM_ESF_ALL,
2737 CAM_EPF_ALL, stderr);
2739 goto tagcontrol_bailout;
2742 if (arglist & CAM_ARG_VERBOSE) {
2743 fprintf(stdout, "%s", pathstr);
2744 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
2745 fprintf(stdout, "%s", pathstr);
2746 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
2747 fprintf(stdout, "%s", pathstr);
2748 fprintf(stdout, "devq_openings %d\n", ccb->cgds.devq_openings);
2749 fprintf(stdout, "%s", pathstr);
2750 fprintf(stdout, "devq_queued %d\n", ccb->cgds.devq_queued);
2751 fprintf(stdout, "%s", pathstr);
2752 fprintf(stdout, "held %d\n", ccb->cgds.held);
2753 fprintf(stdout, "%s", pathstr);
2754 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
2755 fprintf(stdout, "%s", pathstr);
2756 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
2759 fprintf(stdout, "%s", pathstr);
2760 fprintf(stdout, "device openings: ");
2762 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
2763 ccb->cgds.dev_active);
2773 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
2777 cam_path_string(device, pathstr, sizeof(pathstr));
2779 if (cts->transport == XPORT_SPI) {
2780 struct ccb_trans_settings_spi *spi =
2781 &cts->xport_specific.spi;
2783 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
2785 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
2788 if (spi->sync_offset != 0) {
2791 freq = scsi_calc_syncsrate(spi->sync_period);
2792 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
2793 pathstr, freq / 1000, freq % 1000);
2797 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
2798 fprintf(stdout, "%soffset: %d\n", pathstr,
2802 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
2803 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
2804 (0x01 << spi->bus_width) * 8);
2807 if (spi->valid & CTS_SPI_VALID_DISC) {
2808 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
2809 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
2810 "enabled" : "disabled");
2813 if (cts->transport == XPORT_ATA) {
2814 struct ccb_trans_settings_ata *ata =
2815 &cts->xport_specific.ata;
2817 if ((ata->valid & CTS_ATA_VALID_MODE) != 0) {
2818 fprintf(stdout, "%sATA mode: %s\n", pathstr,
2819 ata_mode2string(ata->mode));
2821 if ((ata->valid & CTS_ATA_VALID_ATAPI) != 0) {
2822 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
2825 if ((ata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
2826 fprintf(stdout, "%sPIO transaction length: %d\n",
2827 pathstr, ata->bytecount);
2830 if (cts->transport == XPORT_SATA) {
2831 struct ccb_trans_settings_sata *sata =
2832 &cts->xport_specific.sata;
2834 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
2835 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
2838 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
2839 fprintf(stdout, "%sATA mode: %s\n", pathstr,
2840 ata_mode2string(sata->mode));
2842 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
2843 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
2846 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
2847 fprintf(stdout, "%sPIO transaction length: %d\n",
2848 pathstr, sata->bytecount);
2850 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
2851 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
2854 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
2855 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
2858 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
2859 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
2863 if (cts->protocol == PROTO_SCSI) {
2864 struct ccb_trans_settings_scsi *scsi=
2865 &cts->proto_specific.scsi;
2867 if (scsi->valid & CTS_SCSI_VALID_TQ) {
2868 fprintf(stdout, "%stagged queueing is %s\n", pathstr,
2869 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
2870 "enabled" : "disabled");
2877 * Get a path inquiry CCB for the specified device.
2880 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
2885 ccb = cam_getccb(device);
2887 warnx("get_cpi: couldn't allocate CCB");
2890 bzero(&(&ccb->ccb_h)[1],
2891 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
2892 ccb->ccb_h.func_code = XPT_PATH_INQ;
2893 if (cam_send_ccb(device, ccb) < 0) {
2894 warn("get_cpi: error sending Path Inquiry CCB");
2895 if (arglist & CAM_ARG_VERBOSE)
2896 cam_error_print(device, ccb, CAM_ESF_ALL,
2897 CAM_EPF_ALL, stderr);
2899 goto get_cpi_bailout;
2901 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2902 if (arglist & CAM_ARG_VERBOSE)
2903 cam_error_print(device, ccb, CAM_ESF_ALL,
2904 CAM_EPF_ALL, stderr);
2906 goto get_cpi_bailout;
2908 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
2916 * Get a get device CCB for the specified device.
2919 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
2924 ccb = cam_getccb(device);
2926 warnx("get_cgd: couldn't allocate CCB");
2929 bzero(&(&ccb->ccb_h)[1],
2930 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
2931 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
2932 if (cam_send_ccb(device, ccb) < 0) {
2933 warn("get_cgd: error sending Path Inquiry CCB");
2934 if (arglist & CAM_ARG_VERBOSE)
2935 cam_error_print(device, ccb, CAM_ESF_ALL,
2936 CAM_EPF_ALL, stderr);
2938 goto get_cgd_bailout;
2940 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2941 if (arglist & CAM_ARG_VERBOSE)
2942 cam_error_print(device, ccb, CAM_ESF_ALL,
2943 CAM_EPF_ALL, stderr);
2945 goto get_cgd_bailout;
2947 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
2955 cpi_print(struct ccb_pathinq *cpi)
2957 char adapter_str[1024];
2960 snprintf(adapter_str, sizeof(adapter_str),
2961 "%s%d:", cpi->dev_name, cpi->unit_number);
2963 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
2966 for (i = 1; i < 0xff; i = i << 1) {
2969 if ((i & cpi->hba_inquiry) == 0)
2972 fprintf(stdout, "%s supports ", adapter_str);
2976 str = "MDP message";
2979 str = "32 bit wide SCSI";
2982 str = "16 bit wide SCSI";
2985 str = "SDTR message";
2988 str = "linked CDBs";
2991 str = "tag queue messages";
2994 str = "soft reset alternative";
2997 str = "SATA Port Multiplier";
3000 str = "unknown PI bit set";
3003 fprintf(stdout, "%s\n", str);
3006 for (i = 1; i < 0xff; i = i << 1) {
3009 if ((i & cpi->hba_misc) == 0)
3012 fprintf(stdout, "%s ", adapter_str);
3016 str = "bus scans from high ID to low ID";
3019 str = "removable devices not included in scan";
3021 case PIM_NOINITIATOR:
3022 str = "initiator role not supported";
3024 case PIM_NOBUSRESET:
3025 str = "user has disabled initial BUS RESET or"
3026 " controller is in target/mixed mode";
3029 str = "do not send 6-byte commands";
3032 str = "scan bus sequentially";
3035 str = "unknown PIM bit set";
3038 fprintf(stdout, "%s\n", str);
3041 for (i = 1; i < 0xff; i = i << 1) {
3044 if ((i & cpi->target_sprt) == 0)
3047 fprintf(stdout, "%s supports ", adapter_str);
3050 str = "target mode processor mode";
3053 str = "target mode phase cog. mode";
3055 case PIT_DISCONNECT:
3056 str = "disconnects in target mode";
3059 str = "terminate I/O message in target mode";
3062 str = "group 6 commands in target mode";
3065 str = "group 7 commands in target mode";
3068 str = "unknown PIT bit set";
3072 fprintf(stdout, "%s\n", str);
3074 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
3076 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
3078 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
3080 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
3081 adapter_str, cpi->hpath_id);
3082 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
3084 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
3085 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
3086 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
3087 fprintf(stdout, "%s base transfer speed: ", adapter_str);
3088 if (cpi->base_transfer_speed > 1000)
3089 fprintf(stdout, "%d.%03dMB/sec\n",
3090 cpi->base_transfer_speed / 1000,
3091 cpi->base_transfer_speed % 1000);
3093 fprintf(stdout, "%dKB/sec\n",
3094 (cpi->base_transfer_speed % 1000) * 1000);
3098 get_print_cts(struct cam_device *device, int user_settings, int quiet,
3099 struct ccb_trans_settings *cts)
3105 ccb = cam_getccb(device);
3108 warnx("get_print_cts: error allocating ccb");
3112 bzero(&(&ccb->ccb_h)[1],
3113 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
3115 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
3117 if (user_settings == 0)
3118 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
3120 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
3122 if (cam_send_ccb(device, ccb) < 0) {
3123 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
3124 if (arglist & CAM_ARG_VERBOSE)
3125 cam_error_print(device, ccb, CAM_ESF_ALL,
3126 CAM_EPF_ALL, stderr);
3128 goto get_print_cts_bailout;
3131 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3132 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
3133 if (arglist & CAM_ARG_VERBOSE)
3134 cam_error_print(device, ccb, CAM_ESF_ALL,
3135 CAM_EPF_ALL, stderr);
3137 goto get_print_cts_bailout;
3141 cts_print(device, &ccb->cts);
3144 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
3146 get_print_cts_bailout:
3154 ratecontrol(struct cam_device *device, int retry_count, int timeout,
3155 int argc, char **argv, char *combinedopt)
3159 int user_settings = 0;
3161 int disc_enable = -1, tag_enable = -1;
3164 double syncrate = -1;
3167 int change_settings = 0, send_tur = 0;
3168 struct ccb_pathinq cpi;
3170 ccb = cam_getccb(device);
3172 warnx("ratecontrol: error allocating ccb");
3175 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3184 if (strncasecmp(optarg, "enable", 6) == 0)
3186 else if (strncasecmp(optarg, "disable", 7) == 0)
3189 warnx("-D argument \"%s\" is unknown", optarg);
3191 goto ratecontrol_bailout;
3193 change_settings = 1;
3196 mode = ata_string2mode(optarg);
3198 warnx("unknown mode '%s'", optarg);
3200 goto ratecontrol_bailout;
3202 change_settings = 1;
3205 offset = strtol(optarg, NULL, 0);
3207 warnx("offset value %d is < 0", offset);
3209 goto ratecontrol_bailout;
3211 change_settings = 1;
3217 syncrate = atof(optarg);
3219 warnx("sync rate %f is < 0", syncrate);
3221 goto ratecontrol_bailout;
3223 change_settings = 1;
3226 if (strncasecmp(optarg, "enable", 6) == 0)
3228 else if (strncasecmp(optarg, "disable", 7) == 0)
3231 warnx("-T argument \"%s\" is unknown", optarg);
3233 goto ratecontrol_bailout;
3235 change_settings = 1;
3241 bus_width = strtol(optarg, NULL, 0);
3242 if (bus_width < 0) {
3243 warnx("bus width %d is < 0", bus_width);
3245 goto ratecontrol_bailout;
3247 change_settings = 1;
3253 bzero(&(&ccb->ccb_h)[1],
3254 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
3256 * Grab path inquiry information, so we can determine whether
3257 * or not the initiator is capable of the things that the user
3260 ccb->ccb_h.func_code = XPT_PATH_INQ;
3261 if (cam_send_ccb(device, ccb) < 0) {
3262 perror("error sending XPT_PATH_INQ CCB");
3263 if (arglist & CAM_ARG_VERBOSE) {
3264 cam_error_print(device, ccb, CAM_ESF_ALL,
3265 CAM_EPF_ALL, stderr);
3268 goto ratecontrol_bailout;
3270 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3271 warnx("XPT_PATH_INQ CCB failed");
3272 if (arglist & CAM_ARG_VERBOSE) {
3273 cam_error_print(device, ccb, CAM_ESF_ALL,
3274 CAM_EPF_ALL, stderr);
3277 goto ratecontrol_bailout;
3279 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
3280 bzero(&(&ccb->ccb_h)[1],
3281 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
3283 fprintf(stdout, "%s parameters:\n",
3284 user_settings ? "User" : "Current");
3286 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
3288 goto ratecontrol_bailout;
3290 if (arglist & CAM_ARG_VERBOSE)
3293 if (change_settings) {
3294 int didsettings = 0;
3295 struct ccb_trans_settings_spi *spi = NULL;
3296 struct ccb_trans_settings_ata *ata = NULL;
3297 struct ccb_trans_settings_sata *sata = NULL;
3298 struct ccb_trans_settings_scsi *scsi = NULL;
3300 if (ccb->cts.transport == XPORT_SPI)
3301 spi = &ccb->cts.xport_specific.spi;
3302 if (ccb->cts.transport == XPORT_ATA)
3303 ata = &ccb->cts.xport_specific.ata;
3304 if (ccb->cts.transport == XPORT_SATA)
3305 sata = &ccb->cts.xport_specific.sata;
3306 if (ccb->cts.protocol == PROTO_SCSI)
3307 scsi = &ccb->cts.proto_specific.scsi;
3308 ccb->cts.xport_specific.valid = 0;
3309 ccb->cts.proto_specific.valid = 0;
3310 if (spi && disc_enable != -1) {
3311 spi->valid |= CTS_SPI_VALID_DISC;
3312 if (disc_enable == 0)
3313 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
3315 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
3317 if (scsi && tag_enable != -1) {
3318 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
3319 warnx("HBA does not support tagged queueing, "
3320 "so you cannot modify tag settings");
3322 goto ratecontrol_bailout;
3324 scsi->valid |= CTS_SCSI_VALID_TQ;
3325 if (tag_enable == 0)
3326 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
3328 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
3331 if (spi && offset != -1) {
3332 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3333 warnx("HBA is not capable of changing offset");
3335 goto ratecontrol_bailout;
3337 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
3338 spi->sync_offset = offset;
3341 if (spi && syncrate != -1) {
3342 int prelim_sync_period;
3345 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3346 warnx("HBA is not capable of changing "
3349 goto ratecontrol_bailout;
3351 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
3353 * The sync rate the user gives us is in MHz.
3354 * We need to translate it into KHz for this
3359 * Next, we calculate a "preliminary" sync period
3360 * in tenths of a nanosecond.
3363 prelim_sync_period = 0;
3365 prelim_sync_period = 10000000 / syncrate;
3367 scsi_calc_syncparam(prelim_sync_period);
3368 freq = scsi_calc_syncsrate(spi->sync_period);
3371 if (sata && syncrate != -1) {
3372 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3373 warnx("HBA is not capable of changing "
3376 goto ratecontrol_bailout;
3378 sata->revision = ata_speed2revision(syncrate * 100);
3379 if (sata->revision < 0) {
3380 warnx("Invalid rate %f", syncrate);
3382 goto ratecontrol_bailout;
3384 sata->valid |= CTS_SATA_VALID_REVISION;
3387 if ((ata || sata) && mode != -1) {
3388 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3389 warnx("HBA is not capable of changing "
3392 goto ratecontrol_bailout;
3396 ata->valid |= CTS_ATA_VALID_MODE;
3399 sata->valid |= CTS_SATA_VALID_MODE;
3404 * The bus_width argument goes like this:
3408 * Therefore, if you shift the number of bits given on the
3409 * command line right by 4, you should get the correct
3412 if (spi && bus_width != -1) {
3414 * We might as well validate things here with a
3415 * decipherable error message, rather than what
3416 * will probably be an indecipherable error message
3417 * by the time it gets back to us.
3419 if ((bus_width == 16)
3420 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
3421 warnx("HBA does not support 16 bit bus width");
3423 goto ratecontrol_bailout;
3424 } else if ((bus_width == 32)
3425 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
3426 warnx("HBA does not support 32 bit bus width");
3428 goto ratecontrol_bailout;
3429 } else if ((bus_width != 8)
3430 && (bus_width != 16)
3431 && (bus_width != 32)) {
3432 warnx("Invalid bus width %d", bus_width);
3434 goto ratecontrol_bailout;
3436 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
3437 spi->bus_width = bus_width >> 4;
3440 if (didsettings == 0) {
3441 goto ratecontrol_bailout;
3443 if (!user_settings && (ata || sata)) {
3444 warnx("You can modify only user settings for ATA/SATA");
3446 goto ratecontrol_bailout;
3448 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
3449 if (cam_send_ccb(device, ccb) < 0) {
3450 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
3451 if (arglist & CAM_ARG_VERBOSE) {
3452 cam_error_print(device, ccb, CAM_ESF_ALL,
3453 CAM_EPF_ALL, stderr);
3456 goto ratecontrol_bailout;
3458 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3459 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
3460 if (arglist & CAM_ARG_VERBOSE) {
3461 cam_error_print(device, ccb, CAM_ESF_ALL,
3462 CAM_EPF_ALL, stderr);
3465 goto ratecontrol_bailout;
3469 retval = testunitready(device, retry_count, timeout,
3470 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
3472 * If the TUR didn't succeed, just bail.
3476 fprintf(stderr, "Test Unit Ready failed\n");
3477 goto ratecontrol_bailout;
3480 * If the user wants things quiet, there's no sense in
3481 * getting the transfer settings, if we're not going
3485 goto ratecontrol_bailout;
3486 fprintf(stdout, "New parameters:\n");
3487 retval = get_print_cts(device, user_settings, 0, NULL);
3490 ratecontrol_bailout:
3496 scsiformat(struct cam_device *device, int argc, char **argv,
3497 char *combinedopt, int retry_count, int timeout)
3501 int ycount = 0, quiet = 0;
3502 int error = 0, response = 0, retval = 0;
3503 int use_timeout = 10800 * 1000;
3505 struct format_defect_list_header fh;
3506 u_int8_t *data_ptr = NULL;
3507 u_int32_t dxfer_len = 0;
3509 int num_warnings = 0;
3512 ccb = cam_getccb(device);
3515 warnx("scsiformat: error allocating ccb");
3519 bzero(&(&ccb->ccb_h)[1],
3520 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3522 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3543 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
3544 "following device:\n");
3546 error = scsidoinquiry(device, argc, argv, combinedopt,
3547 retry_count, timeout);
3550 warnx("scsiformat: error sending inquiry");
3551 goto scsiformat_bailout;
3560 fprintf(stdout, "Are you SURE you want to do "
3563 if (fgets(str, sizeof(str), stdin) != NULL) {
3565 if (strncasecmp(str, "yes", 3) == 0)
3567 else if (strncasecmp(str, "no", 2) == 0)
3570 fprintf(stdout, "Please answer"
3571 " \"yes\" or \"no\"\n");
3574 } while (response == 0);
3576 if (response == -1) {
3578 goto scsiformat_bailout;
3583 use_timeout = timeout;
3586 fprintf(stdout, "Current format timeout is %d seconds\n",
3587 use_timeout / 1000);
3591 * If the user hasn't disabled questions and didn't specify a
3592 * timeout on the command line, ask them if they want the current
3596 && (timeout == 0)) {
3598 int new_timeout = 0;
3600 fprintf(stdout, "Enter new timeout in seconds or press\n"
3601 "return to keep the current timeout [%d] ",
3602 use_timeout / 1000);
3604 if (fgets(str, sizeof(str), stdin) != NULL) {
3606 new_timeout = atoi(str);
3609 if (new_timeout != 0) {
3610 use_timeout = new_timeout * 1000;
3611 fprintf(stdout, "Using new timeout value %d\n",
3612 use_timeout / 1000);
3617 * Keep this outside the if block below to silence any unused
3618 * variable warnings.
3620 bzero(&fh, sizeof(fh));
3623 * If we're in immediate mode, we've got to include the format
3626 if (immediate != 0) {
3627 fh.byte2 = FU_DLH_IMMED;
3628 data_ptr = (u_int8_t *)&fh;
3629 dxfer_len = sizeof(fh);
3630 byte2 = FU_FMT_DATA;
3631 } else if (quiet == 0) {
3632 fprintf(stdout, "Formatting...");
3636 scsi_format_unit(&ccb->csio,
3637 /* retries */ retry_count,
3639 /* tag_action */ MSG_SIMPLE_Q_TAG,
3642 /* data_ptr */ data_ptr,
3643 /* dxfer_len */ dxfer_len,
3644 /* sense_len */ SSD_FULL_SIZE,
3645 /* timeout */ use_timeout);
3647 /* Disable freezing the device queue */
3648 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3650 if (arglist & CAM_ARG_ERR_RECOVER)
3651 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3653 if (((retval = cam_send_ccb(device, ccb)) < 0)
3654 || ((immediate == 0)
3655 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
3656 const char errstr[] = "error sending format command";
3663 if (arglist & CAM_ARG_VERBOSE) {
3664 cam_error_print(device, ccb, CAM_ESF_ALL,
3665 CAM_EPF_ALL, stderr);
3668 goto scsiformat_bailout;
3672 * If we ran in non-immediate mode, we already checked for errors
3673 * above and printed out any necessary information. If we're in
3674 * immediate mode, we need to loop through and get status
3675 * information periodically.
3677 if (immediate == 0) {
3679 fprintf(stdout, "Format Complete\n");
3681 goto scsiformat_bailout;
3688 bzero(&(&ccb->ccb_h)[1],
3689 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3692 * There's really no need to do error recovery or
3693 * retries here, since we're just going to sit in a
3694 * loop and wait for the device to finish formatting.
3696 scsi_test_unit_ready(&ccb->csio,
3699 /* tag_action */ MSG_SIMPLE_Q_TAG,
3700 /* sense_len */ SSD_FULL_SIZE,
3701 /* timeout */ 5000);
3703 /* Disable freezing the device queue */
3704 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3706 retval = cam_send_ccb(device, ccb);
3709 * If we get an error from the ioctl, bail out. SCSI
3710 * errors are expected.
3713 warn("error sending CAMIOCOMMAND ioctl");
3714 if (arglist & CAM_ARG_VERBOSE) {
3715 cam_error_print(device, ccb, CAM_ESF_ALL,
3716 CAM_EPF_ALL, stderr);
3719 goto scsiformat_bailout;
3722 status = ccb->ccb_h.status & CAM_STATUS_MASK;
3724 if ((status != CAM_REQ_CMP)
3725 && (status == CAM_SCSI_STATUS_ERROR)
3726 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3727 struct scsi_sense_data *sense;
3728 int error_code, sense_key, asc, ascq;
3730 sense = &ccb->csio.sense_data;
3731 scsi_extract_sense(sense, &error_code, &sense_key,
3735 * According to the SCSI-2 and SCSI-3 specs, a
3736 * drive that is in the middle of a format should
3737 * return NOT READY with an ASC of "logical unit
3738 * not ready, format in progress". The sense key
3739 * specific bytes will then be a progress indicator.
3741 if ((sense_key == SSD_KEY_NOT_READY)
3742 && (asc == 0x04) && (ascq == 0x04)) {
3743 if ((sense->extra_len >= 10)
3744 && ((sense->sense_key_spec[0] &
3745 SSD_SCS_VALID) != 0)
3748 u_int64_t percentage;
3751 &sense->sense_key_spec[1]);
3752 percentage = 10000 * val;
3755 "\rFormatting: %ju.%02u %% "
3757 (uintmax_t)(percentage /
3759 (unsigned)((percentage /
3763 } else if ((quiet == 0)
3764 && (++num_warnings <= 1)) {
3765 warnx("Unexpected SCSI Sense Key "
3766 "Specific value returned "
3768 scsi_sense_print(device, &ccb->csio,
3770 warnx("Unable to print status "
3771 "information, but format will "
3773 warnx("will exit when format is "
3778 warnx("Unexpected SCSI error during format");
3779 cam_error_print(device, ccb, CAM_ESF_ALL,
3780 CAM_EPF_ALL, stderr);
3782 goto scsiformat_bailout;
3785 } else if (status != CAM_REQ_CMP) {
3786 warnx("Unexpected CAM status %#x", status);
3787 if (arglist & CAM_ARG_VERBOSE)
3788 cam_error_print(device, ccb, CAM_ESF_ALL,
3789 CAM_EPF_ALL, stderr);
3791 goto scsiformat_bailout;
3794 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
3797 fprintf(stdout, "\nFormat Complete\n");
3807 scsireportluns(struct cam_device *device, int argc, char **argv,
3808 char *combinedopt, int retry_count, int timeout)
3811 int c, countonly, lunsonly;
3812 struct scsi_report_luns_data *lundata;
3814 uint8_t report_type;
3815 uint32_t list_len, i, j;
3820 report_type = RPL_REPORT_DEFAULT;
3821 ccb = cam_getccb(device);
3824 warnx("%s: error allocating ccb", __func__);
3828 bzero(&(&ccb->ccb_h)[1],
3829 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3834 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3843 if (strcasecmp(optarg, "default") == 0)
3844 report_type = RPL_REPORT_DEFAULT;
3845 else if (strcasecmp(optarg, "wellknown") == 0)
3846 report_type = RPL_REPORT_WELLKNOWN;
3847 else if (strcasecmp(optarg, "all") == 0)
3848 report_type = RPL_REPORT_ALL;
3850 warnx("%s: invalid report type \"%s\"",
3861 if ((countonly != 0)
3862 && (lunsonly != 0)) {
3863 warnx("%s: you can only specify one of -c or -l", __func__);
3868 * According to SPC-4, the allocation length must be at least 16
3869 * bytes -- enough for the header and one LUN.
3871 alloc_len = sizeof(*lundata) + 8;
3875 lundata = malloc(alloc_len);
3877 if (lundata == NULL) {
3878 warn("%s: error mallocing %d bytes", __func__, alloc_len);
3883 scsi_report_luns(&ccb->csio,
3884 /*retries*/ retry_count,
3886 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3887 /*select_report*/ report_type,
3888 /*rpl_buf*/ lundata,
3889 /*alloc_len*/ alloc_len,
3890 /*sense_len*/ SSD_FULL_SIZE,
3891 /*timeout*/ timeout ? timeout : 5000);
3893 /* Disable freezing the device queue */
3894 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3896 if (arglist & CAM_ARG_ERR_RECOVER)
3897 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3899 if (cam_send_ccb(device, ccb) < 0) {
3900 warn("error sending REPORT LUNS command");
3902 if (arglist & CAM_ARG_VERBOSE)
3903 cam_error_print(device, ccb, CAM_ESF_ALL,
3904 CAM_EPF_ALL, stderr);
3910 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3911 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
3917 list_len = scsi_4btoul(lundata->length);
3920 * If we need to list the LUNs, and our allocation
3921 * length was too short, reallocate and retry.
3923 if ((countonly == 0)
3924 && (list_len > (alloc_len - sizeof(*lundata)))) {
3925 alloc_len = list_len + sizeof(*lundata);
3931 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
3932 ((list_len / 8) > 1) ? "s" : "");
3937 for (i = 0; i < (list_len / 8); i++) {
3941 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
3943 fprintf(stdout, ",");
3944 switch (lundata->luns[i].lundata[j] &
3945 RPL_LUNDATA_ATYP_MASK) {
3946 case RPL_LUNDATA_ATYP_PERIPH:
3947 if ((lundata->luns[i].lundata[j] &
3948 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
3949 fprintf(stdout, "%d:",
3950 lundata->luns[i].lundata[j] &
3951 RPL_LUNDATA_PERIPH_BUS_MASK);
3953 && ((lundata->luns[i].lundata[j+2] &
3954 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
3957 fprintf(stdout, "%d",
3958 lundata->luns[i].lundata[j+1]);
3960 case RPL_LUNDATA_ATYP_FLAT: {
3962 tmplun[0] = lundata->luns[i].lundata[j] &
3963 RPL_LUNDATA_FLAT_LUN_MASK;
3964 tmplun[1] = lundata->luns[i].lundata[j+1];
3966 fprintf(stdout, "%d", scsi_2btoul(tmplun));
3970 case RPL_LUNDATA_ATYP_LUN:
3971 fprintf(stdout, "%d:%d:%d",
3972 (lundata->luns[i].lundata[j+1] &
3973 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
3974 lundata->luns[i].lundata[j] &
3975 RPL_LUNDATA_LUN_TARG_MASK,
3976 lundata->luns[i].lundata[j+1] &
3977 RPL_LUNDATA_LUN_LUN_MASK);
3979 case RPL_LUNDATA_ATYP_EXTLUN: {
3980 int field_len, field_len_code, eam_code;
3982 eam_code = lundata->luns[i].lundata[j] &
3983 RPL_LUNDATA_EXT_EAM_MASK;
3984 field_len_code = (lundata->luns[i].lundata[j] &
3985 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
3986 field_len = field_len_code * 2;
3988 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
3989 && (field_len_code == 0x00)) {
3990 fprintf(stdout, "%d",
3991 lundata->luns[i].lundata[j+1]);
3992 } else if ((eam_code ==
3993 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
3994 && (field_len_code == 0x03)) {
3998 * This format takes up all 8 bytes.
3999 * If we aren't starting at offset 0,
4003 fprintf(stdout, "Invalid "
4006 "specified format", j);
4010 bzero(tmp_lun, sizeof(tmp_lun));
4011 bcopy(&lundata->luns[i].lundata[j+1],
4012 &tmp_lun[1], sizeof(tmp_lun) - 1);
4013 fprintf(stdout, "%#jx",
4014 (intmax_t)scsi_8btou64(tmp_lun));
4017 fprintf(stderr, "Unknown Extended LUN"
4018 "Address method %#x, length "
4019 "code %#x", eam_code,
4026 fprintf(stderr, "Unknown LUN address method "
4027 "%#x\n", lundata->luns[i].lundata[0] &
4028 RPL_LUNDATA_ATYP_MASK);
4032 * For the flat addressing method, there are no
4033 * other levels after it.
4038 fprintf(stdout, "\n");
4051 scsireadcapacity(struct cam_device *device, int argc, char **argv,
4052 char *combinedopt, int retry_count, int timeout)
4055 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
4056 struct scsi_read_capacity_data rcap;
4057 struct scsi_read_capacity_data_long rcaplong;
4071 ccb = cam_getccb(device);
4074 warnx("%s: error allocating ccb", __func__);
4078 bzero(&(&ccb->ccb_h)[1],
4079 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
4081 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4108 if ((blocksizeonly != 0)
4109 && (numblocks != 0)) {
4110 warnx("%s: you can only specify one of -b or -N", __func__);
4115 if ((blocksizeonly != 0)
4116 && (sizeonly != 0)) {
4117 warnx("%s: you can only specify one of -b or -s", __func__);
4124 warnx("%s: you can only specify one of -h/-H or -q", __func__);
4130 && (blocksizeonly != 0)) {
4131 warnx("%s: you can only specify one of -h/-H or -b", __func__);
4136 scsi_read_capacity(&ccb->csio,
4137 /*retries*/ retry_count,
4139 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4142 /*timeout*/ timeout ? timeout : 5000);
4144 /* Disable freezing the device queue */
4145 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4147 if (arglist & CAM_ARG_ERR_RECOVER)
4148 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4150 if (cam_send_ccb(device, ccb) < 0) {
4151 warn("error sending READ CAPACITY command");
4153 if (arglist & CAM_ARG_VERBOSE)
4154 cam_error_print(device, ccb, CAM_ESF_ALL,
4155 CAM_EPF_ALL, stderr);
4161 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4162 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4167 maxsector = scsi_4btoul(rcap.addr);
4168 block_len = scsi_4btoul(rcap.length);
4171 * A last block of 2^32-1 means that the true capacity is over 2TB,
4172 * and we need to issue the long READ CAPACITY to get the real
4173 * capacity. Otherwise, we're all set.
4175 if (maxsector != 0xffffffff)
4178 scsi_read_capacity_16(&ccb->csio,
4179 /*retries*/ retry_count,
4181 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4186 /*sense_len*/ SSD_FULL_SIZE,
4187 /*timeout*/ timeout ? timeout : 5000);
4189 /* Disable freezing the device queue */
4190 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4192 if (arglist & CAM_ARG_ERR_RECOVER)
4193 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4195 if (cam_send_ccb(device, ccb) < 0) {
4196 warn("error sending READ CAPACITY (16) command");
4198 if (arglist & CAM_ARG_VERBOSE)
4199 cam_error_print(device, ccb, CAM_ESF_ALL,
4200 CAM_EPF_ALL, stderr);
4206 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4207 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4212 maxsector = scsi_8btou64(rcaplong.addr);
4213 block_len = scsi_4btoul(rcaplong.length);
4216 if (blocksizeonly == 0) {
4218 * Humanize implies !quiet, and also implies numblocks.
4220 if (humanize != 0) {
4225 tmpbytes = (maxsector + 1) * block_len;
4226 ret = humanize_number(tmpstr, sizeof(tmpstr),
4227 tmpbytes, "", HN_AUTOSCALE,
4230 HN_DIVISOR_1000 : 0));
4232 warnx("%s: humanize_number failed!", __func__);
4236 fprintf(stdout, "Device Size: %s%s", tmpstr,
4237 (sizeonly == 0) ? ", " : "\n");
4238 } else if (numblocks != 0) {
4239 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
4240 "Blocks: " : "", (uintmax_t)maxsector + 1,
4241 (sizeonly == 0) ? ", " : "\n");
4243 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
4244 "Last Block: " : "", (uintmax_t)maxsector,
4245 (sizeonly == 0) ? ", " : "\n");
4249 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
4250 "Block Length: " : "", block_len, (quiet == 0) ?
4259 atapm(struct cam_device *device, int argc, char **argv,
4260 char *combinedopt, int retry_count, int timeout)
4268 ccb = cam_getccb(device);
4271 warnx("%s: error allocating ccb", __func__);
4275 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4284 if (strcmp(argv[1], "idle") == 0) {
4286 cmd = ATA_IDLE_IMMEDIATE;
4289 } else if (strcmp(argv[1], "standby") == 0) {
4291 cmd = ATA_STANDBY_IMMEDIATE;
4293 cmd = ATA_STANDBY_CMD;
4300 else if (t <= (240 * 5))
4302 else if (t <= (11 * 30 * 60))
4303 sc = t / (30 * 60) + 241;
4306 cam_fill_ataio(&ccb->ataio,
4309 /*flags*/CAM_DIR_NONE,
4313 timeout ? timeout : 30 * 1000);
4314 ata_28bit_cmd(&ccb->ataio, cmd, 0, 0, sc);
4316 /* Disable freezing the device queue */
4317 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4319 if (arglist & CAM_ARG_ERR_RECOVER)
4320 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4322 if (cam_send_ccb(device, ccb) < 0) {
4323 warn("error sending command");
4325 if (arglist & CAM_ARG_VERBOSE)
4326 cam_error_print(device, ccb, CAM_ESF_ALL,
4327 CAM_EPF_ALL, stderr);
4333 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4334 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4343 #endif /* MINIMALISTIC */
4348 fprintf(verbose ? stdout : stderr,
4349 "usage: camcontrol <command> [device id][generic args][command args]\n"
4350 " camcontrol devlist [-v]\n"
4351 #ifndef MINIMALISTIC
4352 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
4353 " camcontrol tur [dev_id][generic args]\n"
4354 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
4355 " camcontrol identify [dev_id][generic args] [-v]\n"
4356 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
4357 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
4359 " camcontrol start [dev_id][generic args]\n"
4360 " camcontrol stop [dev_id][generic args]\n"
4361 " camcontrol load [dev_id][generic args]\n"
4362 " camcontrol eject [dev_id][generic args]\n"
4363 #endif /* MINIMALISTIC */
4364 " camcontrol rescan <all | bus[:target:lun]>\n"
4365 " camcontrol reset <all | bus[:target:lun]>\n"
4366 #ifndef MINIMALISTIC
4367 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
4368 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
4369 " [-P pagectl][-e | -b][-d]\n"
4370 " camcontrol cmd [dev_id][generic args]\n"
4371 " <-a cmd [args] | -c cmd [args]>\n"
4372 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
4373 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
4374 " <all|bus[:target[:lun]]|off>\n"
4375 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
4376 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
4377 " [-D <enable|disable>][-M mode][-O offset]\n"
4378 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
4379 " [-U][-W bus_width]\n"
4380 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
4381 " camcontrol idle [dev_id][generic args][-t time]\n"
4382 " camcontrol standby [dev_id][generic args][-t time]\n"
4383 " camcontrol sleep [dev_id][generic args]\n"
4384 #endif /* MINIMALISTIC */
4385 " camcontrol help\n");
4388 #ifndef MINIMALISTIC
4390 "Specify one of the following options:\n"
4391 "devlist list all CAM devices\n"
4392 "periphlist list all CAM peripheral drivers attached to a device\n"
4393 "tur send a test unit ready to the named device\n"
4394 "inquiry send a SCSI inquiry command to the named device\n"
4395 "identify send a ATA identify command to the named device\n"
4396 "reportluns send a SCSI report luns command to the device\n"
4397 "readcap send a SCSI read capacity command to the device\n"
4398 "start send a Start Unit command to the device\n"
4399 "stop send a Stop Unit command to the device\n"
4400 "load send a Start Unit command to the device with the load bit set\n"
4401 "eject send a Stop Unit command to the device with the eject bit set\n"
4402 "rescan rescan all busses, the given bus, or bus:target:lun\n"
4403 "reset reset all busses, the given bus, or bus:target:lun\n"
4404 "defects read the defect list of the specified device\n"
4405 "modepage display or edit (-e) the given mode page\n"
4406 "cmd send the given scsi command, may need -i or -o as well\n"
4407 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
4408 "tags report or set the number of transaction slots for a device\n"
4409 "negotiate report or set device negotiation parameters\n"
4410 "format send the SCSI FORMAT UNIT command to the named device\n"
4411 "idle send the ATA IDLE command to the named device\n"
4412 "standby send the ATA STANDBY command to the named device\n"
4413 "sleep send the ATA SLEEP command to the named device\n"
4414 "help this message\n"
4415 "Device Identifiers:\n"
4416 "bus:target specify the bus and target, lun defaults to 0\n"
4417 "bus:target:lun specify the bus, target and lun\n"
4418 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
4419 "Generic arguments:\n"
4420 "-v be verbose, print out sense information\n"
4421 "-t timeout command timeout in seconds, overrides default timeout\n"
4422 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
4423 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
4424 "-E have the kernel attempt to perform SCSI error recovery\n"
4425 "-C count specify the SCSI command retry count (needs -E to work)\n"
4426 "modepage arguments:\n"
4427 "-l list all available mode pages\n"
4428 "-m page specify the mode page to view or edit\n"
4429 "-e edit the specified mode page\n"
4430 "-b force view to binary mode\n"
4431 "-d disable block descriptors for mode sense\n"
4432 "-P pgctl page control field 0-3\n"
4433 "defects arguments:\n"
4434 "-f format specify defect list format (block, bfi or phys)\n"
4435 "-G get the grown defect list\n"
4436 "-P get the permanant defect list\n"
4437 "inquiry arguments:\n"
4438 "-D get the standard inquiry data\n"
4439 "-S get the serial number\n"
4440 "-R get the transfer rate, etc.\n"
4441 "reportluns arguments:\n"
4442 "-c only report a count of available LUNs\n"
4443 "-l only print out luns, and not a count\n"
4444 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
4445 "readcap arguments\n"
4446 "-b only report the blocksize\n"
4447 "-h human readable device size, base 2\n"
4448 "-H human readable device size, base 10\n"
4449 "-N print the number of blocks instead of last block\n"
4450 "-q quiet, print numbers only\n"
4451 "-s only report the last block/device size\n"
4453 "-c cdb [args] specify the SCSI CDB\n"
4454 "-i len fmt specify input data and input data format\n"
4455 "-o len fmt [args] specify output data and output data fmt\n"
4456 "debug arguments:\n"
4457 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
4458 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
4459 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
4460 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
4462 "-N tags specify the number of tags to use for this device\n"
4463 "-q be quiet, don't report the number of tags\n"
4464 "-v report a number of tag-related parameters\n"
4465 "negotiate arguments:\n"
4466 "-a send a test unit ready after negotiation\n"
4467 "-c report/set current negotiation settings\n"
4468 "-D <arg> \"enable\" or \"disable\" disconnection\n"
4469 "-M mode set ATA mode\n"
4470 "-O offset set command delay offset\n"
4471 "-q be quiet, don't report anything\n"
4472 "-R syncrate synchronization rate in MHz\n"
4473 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
4474 "-U report/set user negotiation settings\n"
4475 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
4476 "-v also print a Path Inquiry CCB for the controller\n"
4477 "format arguments:\n"
4478 "-q be quiet, don't print status messages\n"
4479 "-r run in report only mode\n"
4480 "-w don't send immediate format command\n"
4481 "-y don't ask any questions\n"
4482 "idle/standby arguments:\n"
4483 "-t <arg> number of seconds before respective state.\n");
4484 #endif /* MINIMALISTIC */
4488 main(int argc, char **argv)
4491 char *device = NULL;
4493 struct cam_device *cam_dev = NULL;
4494 int timeout = 0, retry_count = 1;
4495 camcontrol_optret optreturn;
4497 const char *mainopt = "C:En:t:u:v";
4498 const char *subopt = NULL;
4499 char combinedopt[256];
4500 int error = 0, optstart = 2;
4502 #ifndef MINIMALISTIC
4503 int bus, target, lun;
4504 #endif /* MINIMALISTIC */
4506 cmdlist = CAM_CMD_NONE;
4507 arglist = CAM_ARG_NONE;
4515 * Get the base option.
4517 optreturn = getoption(argv[1], &cmdlist, &arglist, &subopt);
4519 if (optreturn == CC_OR_AMBIGUOUS) {
4520 warnx("ambiguous option %s", argv[1]);
4523 } else if (optreturn == CC_OR_NOT_FOUND) {
4524 warnx("option %s not found", argv[1]);
4530 * Ahh, getopt(3) is a pain.
4532 * This is a gross hack. There really aren't many other good
4533 * options (excuse the pun) for parsing options in a situation like
4534 * this. getopt is kinda braindead, so you end up having to run
4535 * through the options twice, and give each invocation of getopt
4536 * the option string for the other invocation.
4538 * You would think that you could just have two groups of options.
4539 * The first group would get parsed by the first invocation of
4540 * getopt, and the second group would get parsed by the second
4541 * invocation of getopt. It doesn't quite work out that way. When
4542 * the first invocation of getopt finishes, it leaves optind pointing
4543 * to the argument _after_ the first argument in the second group.
4544 * So when the second invocation of getopt comes around, it doesn't
4545 * recognize the first argument it gets and then bails out.
4547 * A nice alternative would be to have a flag for getopt that says
4548 * "just keep parsing arguments even when you encounter an unknown
4549 * argument", but there isn't one. So there's no real clean way to
4550 * easily parse two sets of arguments without having one invocation
4551 * of getopt know about the other.
4553 * Without this hack, the first invocation of getopt would work as
4554 * long as the generic arguments are first, but the second invocation
4555 * (in the subfunction) would fail in one of two ways. In the case
4556 * where you don't set optreset, it would fail because optind may be
4557 * pointing to the argument after the one it should be pointing at.
4558 * In the case where you do set optreset, and reset optind, it would
4559 * fail because getopt would run into the first set of options, which
4560 * it doesn't understand.
4562 * All of this would "sort of" work if you could somehow figure out
4563 * whether optind had been incremented one option too far. The
4564 * mechanics of that, however, are more daunting than just giving
4565 * both invocations all of the expect options for either invocation.
4567 * Needless to say, I wouldn't mind if someone invented a better
4568 * (non-GPL!) command line parsing interface than getopt. I
4569 * wouldn't mind if someone added more knobs to getopt to make it
4570 * work better. Who knows, I may talk myself into doing it someday,
4571 * if the standards weenies let me. As it is, it just leads to
4572 * hackery like this and causes people to avoid it in some cases.
4574 * KDM, September 8th, 1998
4577 sprintf(combinedopt, "%s%s", mainopt, subopt);
4579 sprintf(combinedopt, "%s", mainopt);
4582 * For these options we do not parse optional device arguments and
4583 * we do not open a passthrough device.
4585 if ((cmdlist == CAM_CMD_RESCAN)
4586 || (cmdlist == CAM_CMD_RESET)
4587 || (cmdlist == CAM_CMD_DEVTREE)
4588 || (cmdlist == CAM_CMD_USAGE)
4589 || (cmdlist == CAM_CMD_DEBUG))
4592 #ifndef MINIMALISTIC
4594 && (argc > 2 && argv[2][0] != '-')) {
4599 * First catch people who try to do things like:
4600 * camcontrol tur /dev/da0
4601 * camcontrol doesn't take device nodes as arguments.
4603 if (argv[2][0] == '/') {
4604 warnx("%s is not a valid device identifier", argv[2]);
4605 errx(1, "please read the camcontrol(8) man page");
4606 } else if (isdigit(argv[2][0])) {
4607 /* device specified as bus:target[:lun] */
4608 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
4610 errx(1, "numeric device specification must "
4611 "be either bus:target, or "
4613 /* default to 0 if lun was not specified */
4614 if ((arglist & CAM_ARG_LUN) == 0) {
4616 arglist |= CAM_ARG_LUN;
4620 if (cam_get_device(argv[2], name, sizeof name, &unit)
4622 errx(1, "%s", cam_errbuf);
4623 device = strdup(name);
4624 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
4628 #endif /* MINIMALISTIC */
4630 * Start getopt processing at argv[2/3], since we've already
4631 * accepted argv[1..2] as the command name, and as a possible
4637 * Now we run through the argument list looking for generic
4638 * options, and ignoring options that possibly belong to
4641 while ((c = getopt(argc, argv, combinedopt))!= -1){
4644 retry_count = strtol(optarg, NULL, 0);
4645 if (retry_count < 0)
4646 errx(1, "retry count %d is < 0",
4648 arglist |= CAM_ARG_RETRIES;
4651 arglist |= CAM_ARG_ERR_RECOVER;
4654 arglist |= CAM_ARG_DEVICE;
4656 while (isspace(*tstr) && (*tstr != '\0'))
4658 device = (char *)strdup(tstr);
4661 timeout = strtol(optarg, NULL, 0);
4663 errx(1, "invalid timeout %d", timeout);
4664 /* Convert the timeout from seconds to ms */
4666 arglist |= CAM_ARG_TIMEOUT;
4669 arglist |= CAM_ARG_UNIT;
4670 unit = strtol(optarg, NULL, 0);
4673 arglist |= CAM_ARG_VERBOSE;
4680 #ifndef MINIMALISTIC
4682 * For most commands we'll want to open the passthrough device
4683 * associated with the specified device. In the case of the rescan
4684 * commands, we don't use a passthrough device at all, just the
4685 * transport layer device.
4688 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
4689 && (((arglist & CAM_ARG_DEVICE) == 0)
4690 || ((arglist & CAM_ARG_UNIT) == 0))) {
4691 errx(1, "subcommand \"%s\" requires a valid device "
4692 "identifier", argv[1]);
4695 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
4696 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
4697 cam_open_spec_device(device,unit,O_RDWR,NULL)))
4699 errx(1,"%s", cam_errbuf);
4701 #endif /* MINIMALISTIC */
4704 * Reset optind to 2, and reset getopt, so these routines can parse
4705 * the arguments again.
4711 #ifndef MINIMALISTIC
4712 case CAM_CMD_DEVLIST:
4713 error = getdevlist(cam_dev);
4715 #endif /* MINIMALISTIC */
4716 case CAM_CMD_DEVTREE:
4717 error = getdevtree();
4719 #ifndef MINIMALISTIC
4721 error = testunitready(cam_dev, retry_count, timeout, 0);
4723 case CAM_CMD_INQUIRY:
4724 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
4725 retry_count, timeout);
4727 case CAM_CMD_IDENTIFY:
4728 error = ataidentify(cam_dev, retry_count, timeout);
4730 case CAM_CMD_STARTSTOP:
4731 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
4732 arglist & CAM_ARG_EJECT, retry_count,
4735 #endif /* MINIMALISTIC */
4736 case CAM_CMD_RESCAN:
4737 error = dorescan_or_reset(argc, argv, 1);
4740 error = dorescan_or_reset(argc, argv, 0);
4742 #ifndef MINIMALISTIC
4743 case CAM_CMD_READ_DEFECTS:
4744 error = readdefects(cam_dev, argc, argv, combinedopt,
4745 retry_count, timeout);
4747 case CAM_CMD_MODE_PAGE:
4748 modepage(cam_dev, argc, argv, combinedopt,
4749 retry_count, timeout);
4751 case CAM_CMD_SCSI_CMD:
4752 error = scsicmd(cam_dev, argc, argv, combinedopt,
4753 retry_count, timeout);
4756 error = camdebug(argc, argv, combinedopt);
4759 error = tagcontrol(cam_dev, argc, argv, combinedopt);
4762 error = ratecontrol(cam_dev, retry_count, timeout,
4763 argc, argv, combinedopt);
4765 case CAM_CMD_FORMAT:
4766 error = scsiformat(cam_dev, argc, argv,
4767 combinedopt, retry_count, timeout);
4769 case CAM_CMD_REPORTLUNS:
4770 error = scsireportluns(cam_dev, argc, argv,
4771 combinedopt, retry_count,
4774 case CAM_CMD_READCAP:
4775 error = scsireadcapacity(cam_dev, argc, argv,
4776 combinedopt, retry_count,
4780 case CAM_CMD_STANDBY:
4782 error = atapm(cam_dev, argc, argv,
4783 combinedopt, retry_count,
4786 #endif /* MINIMALISTIC */
4796 if (cam_dev != NULL)
4797 cam_close_device(cam_dev);