2 * Copyright (c) 1997-2007 Kenneth D. Merry
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/ioctl.h>
33 #include <sys/stdint.h>
34 #include <sys/types.h>
35 #include <sys/endian.h>
47 #include <cam/cam_debug.h>
48 #include <cam/cam_ccb.h>
49 #include <cam/scsi/scsi_all.h>
50 #include <cam/scsi/scsi_da.h>
51 #include <cam/scsi/scsi_pass.h>
52 #include <cam/scsi/scsi_message.h>
53 #include <cam/ata/ata_all.h>
55 #include "camcontrol.h"
58 CAM_CMD_NONE = 0x00000000,
59 CAM_CMD_DEVLIST = 0x00000001,
60 CAM_CMD_TUR = 0x00000002,
61 CAM_CMD_INQUIRY = 0x00000003,
62 CAM_CMD_STARTSTOP = 0x00000004,
63 CAM_CMD_RESCAN = 0x00000005,
64 CAM_CMD_READ_DEFECTS = 0x00000006,
65 CAM_CMD_MODE_PAGE = 0x00000007,
66 CAM_CMD_SCSI_CMD = 0x00000008,
67 CAM_CMD_DEVTREE = 0x00000009,
68 CAM_CMD_USAGE = 0x0000000a,
69 CAM_CMD_DEBUG = 0x0000000b,
70 CAM_CMD_RESET = 0x0000000c,
71 CAM_CMD_FORMAT = 0x0000000d,
72 CAM_CMD_TAG = 0x0000000e,
73 CAM_CMD_RATE = 0x0000000f,
74 CAM_CMD_DETACH = 0x00000010,
75 CAM_CMD_REPORTLUNS = 0x00000011,
76 CAM_CMD_READCAP = 0x00000012,
77 CAM_CMD_IDENTIFY = 0x00000013,
78 CAM_CMD_IDLE = 0x00000014,
79 CAM_CMD_STANDBY = 0x00000015,
80 CAM_CMD_SLEEP = 0x00000016
84 CAM_ARG_NONE = 0x00000000,
85 CAM_ARG_VERBOSE = 0x00000001,
86 CAM_ARG_DEVICE = 0x00000002,
87 CAM_ARG_BUS = 0x00000004,
88 CAM_ARG_TARGET = 0x00000008,
89 CAM_ARG_LUN = 0x00000010,
90 CAM_ARG_EJECT = 0x00000020,
91 CAM_ARG_UNIT = 0x00000040,
92 CAM_ARG_FORMAT_BLOCK = 0x00000080,
93 CAM_ARG_FORMAT_BFI = 0x00000100,
94 CAM_ARG_FORMAT_PHYS = 0x00000200,
95 CAM_ARG_PLIST = 0x00000400,
96 CAM_ARG_GLIST = 0x00000800,
97 CAM_ARG_GET_SERIAL = 0x00001000,
98 CAM_ARG_GET_STDINQ = 0x00002000,
99 CAM_ARG_GET_XFERRATE = 0x00004000,
100 CAM_ARG_INQ_MASK = 0x00007000,
101 CAM_ARG_MODE_EDIT = 0x00008000,
102 CAM_ARG_PAGE_CNTL = 0x00010000,
103 CAM_ARG_TIMEOUT = 0x00020000,
104 CAM_ARG_CMD_IN = 0x00040000,
105 CAM_ARG_CMD_OUT = 0x00080000,
106 CAM_ARG_DBD = 0x00100000,
107 CAM_ARG_ERR_RECOVER = 0x00200000,
108 CAM_ARG_RETRIES = 0x00400000,
109 CAM_ARG_START_UNIT = 0x00800000,
110 CAM_ARG_DEBUG_INFO = 0x01000000,
111 CAM_ARG_DEBUG_TRACE = 0x02000000,
112 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
113 CAM_ARG_DEBUG_CDB = 0x08000000,
114 CAM_ARG_DEBUG_XPT = 0x10000000,
115 CAM_ARG_DEBUG_PERIPH = 0x20000000,
118 struct camcontrol_opts {
126 static const char scsicmd_opts[] = "a:c:i:o:r";
127 static const char readdefect_opts[] = "f:GP";
128 static const char negotiate_opts[] = "acD: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 */
231 getoption(char *arg, cam_cmdmask *cmdnum, cam_argmask *argnum,
234 struct camcontrol_opts *opts;
237 for (opts = option_table; (opts != NULL) && (opts->optname != NULL);
239 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
240 *cmdnum = opts->cmdnum;
241 *argnum = opts->argnum;
242 *subopt = opts->subopt;
243 if (++num_matches > 1)
244 return(CC_OR_AMBIGUOUS);
251 return(CC_OR_NOT_FOUND);
256 getdevlist(struct cam_device *device)
262 ccb = cam_getccb(device);
264 ccb->ccb_h.func_code = XPT_GDEVLIST;
265 ccb->ccb_h.flags = CAM_DIR_NONE;
266 ccb->ccb_h.retry_count = 1;
268 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
269 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
270 if (cam_send_ccb(device, ccb) < 0) {
271 perror("error getting device list");
278 switch (ccb->cgdl.status) {
279 case CAM_GDEVLIST_MORE_DEVS:
280 strcpy(status, "MORE");
282 case CAM_GDEVLIST_LAST_DEVICE:
283 strcpy(status, "LAST");
285 case CAM_GDEVLIST_LIST_CHANGED:
286 strcpy(status, "CHANGED");
288 case CAM_GDEVLIST_ERROR:
289 strcpy(status, "ERROR");
294 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
295 ccb->cgdl.periph_name,
296 ccb->cgdl.unit_number,
297 ccb->cgdl.generation,
302 * If the list has changed, we need to start over from the
305 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
313 #endif /* MINIMALISTIC */
325 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
326 warn("couldn't open %s", XPT_DEVICE);
330 bzero(&ccb, sizeof(union ccb));
332 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
333 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
334 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
336 ccb.ccb_h.func_code = XPT_DEV_MATCH;
337 bufsize = sizeof(struct dev_match_result) * 100;
338 ccb.cdm.match_buf_len = bufsize;
339 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
340 if (ccb.cdm.matches == NULL) {
341 warnx("can't malloc memory for matches");
345 ccb.cdm.num_matches = 0;
348 * We fetch all nodes, since we display most of them in the default
349 * case, and all in the verbose case.
351 ccb.cdm.num_patterns = 0;
352 ccb.cdm.pattern_buf_len = 0;
355 * We do the ioctl multiple times if necessary, in case there are
356 * more than 100 nodes in the EDT.
359 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
360 warn("error sending CAMIOCOMMAND ioctl");
365 if ((ccb.ccb_h.status != CAM_REQ_CMP)
366 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
367 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
368 warnx("got CAM error %#x, CDM error %d\n",
369 ccb.ccb_h.status, ccb.cdm.status);
374 for (i = 0; i < ccb.cdm.num_matches; i++) {
375 switch (ccb.cdm.matches[i].type) {
376 case DEV_MATCH_BUS: {
377 struct bus_match_result *bus_result;
380 * Only print the bus information if the
381 * user turns on the verbose flag.
383 if ((arglist & CAM_ARG_VERBOSE) == 0)
387 &ccb.cdm.matches[i].result.bus_result;
390 fprintf(stdout, ")\n");
394 fprintf(stdout, "scbus%d on %s%d bus %d:\n",
396 bus_result->dev_name,
397 bus_result->unit_number,
401 case DEV_MATCH_DEVICE: {
402 struct device_match_result *dev_result;
403 char vendor[16], product[48], revision[16];
407 &ccb.cdm.matches[i].result.device_result;
409 if ((dev_result->flags
410 & DEV_RESULT_UNCONFIGURED)
411 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
417 if (dev_result->protocol == PROTO_SCSI) {
418 cam_strvis(vendor, dev_result->inq_data.vendor,
419 sizeof(dev_result->inq_data.vendor),
422 dev_result->inq_data.product,
423 sizeof(dev_result->inq_data.product),
426 dev_result->inq_data.revision,
427 sizeof(dev_result->inq_data.revision),
429 sprintf(tmpstr, "<%s %s %s>", vendor, product,
431 } else if (dev_result->protocol == PROTO_ATA ||
432 dev_result->protocol == PROTO_SATAPM) {
434 dev_result->ident_data.model,
435 sizeof(dev_result->ident_data.model),
438 dev_result->ident_data.revision,
439 sizeof(dev_result->ident_data.revision),
441 sprintf(tmpstr, "<%s %s>", product,
444 sprintf(tmpstr, "<>");
447 fprintf(stdout, ")\n");
451 fprintf(stdout, "%-33s at scbus%d "
452 "target %d lun %d (",
455 dev_result->target_id,
456 dev_result->target_lun);
462 case DEV_MATCH_PERIPH: {
463 struct periph_match_result *periph_result;
466 &ccb.cdm.matches[i].result.periph_result;
468 if (skip_device != 0)
472 fprintf(stdout, ",");
474 fprintf(stdout, "%s%d",
475 periph_result->periph_name,
476 periph_result->unit_number);
482 fprintf(stdout, "unknown match type\n");
487 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
488 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
491 fprintf(stdout, ")\n");
500 testunitready(struct cam_device *device, int retry_count, int timeout,
506 ccb = cam_getccb(device);
508 scsi_test_unit_ready(&ccb->csio,
509 /* retries */ retry_count,
511 /* tag_action */ MSG_SIMPLE_Q_TAG,
512 /* sense_len */ SSD_FULL_SIZE,
513 /* timeout */ timeout ? timeout : 5000);
515 /* Disable freezing the device queue */
516 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
518 if (arglist & CAM_ARG_ERR_RECOVER)
519 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
521 if (cam_send_ccb(device, ccb) < 0) {
523 perror("error sending test unit ready");
525 if (arglist & CAM_ARG_VERBOSE) {
526 cam_error_print(device, ccb, CAM_ESF_ALL,
527 CAM_EPF_ALL, stderr);
534 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
536 fprintf(stdout, "Unit is ready\n");
539 fprintf(stdout, "Unit is not ready\n");
542 if (arglist & CAM_ARG_VERBOSE) {
543 cam_error_print(device, ccb, CAM_ESF_ALL,
544 CAM_EPF_ALL, stderr);
554 scsistart(struct cam_device *device, int startstop, int loadeject,
555 int retry_count, int timeout)
560 ccb = cam_getccb(device);
563 * If we're stopping, send an ordered tag so the drive in question
564 * will finish any previously queued writes before stopping. If
565 * the device isn't capable of tagged queueing, or if tagged
566 * queueing is turned off, the tag action is a no-op.
568 scsi_start_stop(&ccb->csio,
569 /* retries */ retry_count,
571 /* tag_action */ startstop ? MSG_SIMPLE_Q_TAG :
573 /* start/stop */ startstop,
574 /* load_eject */ loadeject,
576 /* sense_len */ SSD_FULL_SIZE,
577 /* timeout */ timeout ? timeout : 120000);
579 /* Disable freezing the device queue */
580 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
582 if (arglist & CAM_ARG_ERR_RECOVER)
583 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
585 if (cam_send_ccb(device, ccb) < 0) {
586 perror("error sending start unit");
588 if (arglist & CAM_ARG_VERBOSE) {
589 cam_error_print(device, ccb, CAM_ESF_ALL,
590 CAM_EPF_ALL, stderr);
597 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
599 fprintf(stdout, "Unit started successfully");
601 fprintf(stdout,", Media loaded\n");
603 fprintf(stdout,"\n");
605 fprintf(stdout, "Unit stopped successfully");
607 fprintf(stdout, ", Media ejected\n");
609 fprintf(stdout, "\n");
615 "Error received from start unit command\n");
618 "Error received from stop unit command\n");
620 if (arglist & CAM_ARG_VERBOSE) {
621 cam_error_print(device, ccb, CAM_ESF_ALL,
622 CAM_EPF_ALL, stderr);
632 scsidoinquiry(struct cam_device *device, int argc, char **argv,
633 char *combinedopt, int retry_count, int timeout)
638 while ((c = getopt(argc, argv, combinedopt)) != -1) {
641 arglist |= CAM_ARG_GET_STDINQ;
644 arglist |= CAM_ARG_GET_XFERRATE;
647 arglist |= CAM_ARG_GET_SERIAL;
655 * If the user didn't specify any inquiry options, he wants all of
658 if ((arglist & CAM_ARG_INQ_MASK) == 0)
659 arglist |= CAM_ARG_INQ_MASK;
661 if (arglist & CAM_ARG_GET_STDINQ)
662 error = scsiinquiry(device, retry_count, timeout);
667 if (arglist & CAM_ARG_GET_SERIAL)
668 scsiserial(device, retry_count, timeout);
673 if (arglist & CAM_ARG_GET_XFERRATE)
674 error = camxferrate(device);
680 scsiinquiry(struct cam_device *device, int retry_count, int timeout)
683 struct scsi_inquiry_data *inq_buf;
686 ccb = cam_getccb(device);
689 warnx("couldn't allocate CCB");
693 /* cam_getccb cleans up the header, caller has to zero the payload */
694 bzero(&(&ccb->ccb_h)[1],
695 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
697 inq_buf = (struct scsi_inquiry_data *)malloc(
698 sizeof(struct scsi_inquiry_data));
700 if (inq_buf == NULL) {
702 warnx("can't malloc memory for inquiry\n");
705 bzero(inq_buf, sizeof(*inq_buf));
708 * Note that although the size of the inquiry buffer is the full
709 * 256 bytes specified in the SCSI spec, we only tell the device
710 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
711 * two reasons for this:
713 * - The SCSI spec says that when a length field is only 1 byte,
714 * a value of 0 will be interpreted as 256. Therefore
715 * scsi_inquiry() will convert an inq_len (which is passed in as
716 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
717 * to 0. Evidently, very few devices meet the spec in that
718 * regard. Some devices, like many Seagate disks, take the 0 as
719 * 0, and don't return any data. One Pioneer DVD-R drive
720 * returns more data than the command asked for.
722 * So, since there are numerous devices that just don't work
723 * right with the full inquiry size, we don't send the full size.
725 * - The second reason not to use the full inquiry data length is
726 * that we don't need it here. The only reason we issue a
727 * standard inquiry is to get the vendor name, device name,
728 * and revision so scsi_print_inquiry() can print them.
730 * If, at some point in the future, more inquiry data is needed for
731 * some reason, this code should use a procedure similar to the
732 * probe code. i.e., issue a short inquiry, and determine from
733 * the additional length passed back from the device how much
734 * inquiry data the device supports. Once the amount the device
735 * supports is determined, issue an inquiry for that amount and no
740 scsi_inquiry(&ccb->csio,
741 /* retries */ retry_count,
743 /* tag_action */ MSG_SIMPLE_Q_TAG,
744 /* inq_buf */ (u_int8_t *)inq_buf,
745 /* inq_len */ SHORT_INQUIRY_LENGTH,
748 /* sense_len */ SSD_FULL_SIZE,
749 /* timeout */ timeout ? timeout : 5000);
751 /* Disable freezing the device queue */
752 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
754 if (arglist & CAM_ARG_ERR_RECOVER)
755 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
757 if (cam_send_ccb(device, ccb) < 0) {
758 perror("error sending SCSI inquiry");
760 if (arglist & CAM_ARG_VERBOSE) {
761 cam_error_print(device, ccb, CAM_ESF_ALL,
762 CAM_EPF_ALL, stderr);
769 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
772 if (arglist & CAM_ARG_VERBOSE) {
773 cam_error_print(device, ccb, CAM_ESF_ALL,
774 CAM_EPF_ALL, stderr);
785 fprintf(stdout, "%s%d: ", device->device_name,
786 device->dev_unit_num);
787 scsi_print_inquiry(inq_buf);
795 scsiserial(struct cam_device *device, int retry_count, int timeout)
798 struct scsi_vpd_unit_serial_number *serial_buf;
799 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
802 ccb = cam_getccb(device);
805 warnx("couldn't allocate CCB");
809 /* cam_getccb cleans up the header, caller has to zero the payload */
810 bzero(&(&ccb->ccb_h)[1],
811 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
813 serial_buf = (struct scsi_vpd_unit_serial_number *)
814 malloc(sizeof(*serial_buf));
816 if (serial_buf == NULL) {
818 warnx("can't malloc memory for serial number");
822 scsi_inquiry(&ccb->csio,
823 /*retries*/ retry_count,
825 /* tag_action */ MSG_SIMPLE_Q_TAG,
826 /* inq_buf */ (u_int8_t *)serial_buf,
827 /* inq_len */ sizeof(*serial_buf),
829 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
830 /* sense_len */ SSD_FULL_SIZE,
831 /* timeout */ timeout ? timeout : 5000);
833 /* Disable freezing the device queue */
834 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
836 if (arglist & CAM_ARG_ERR_RECOVER)
837 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
839 if (cam_send_ccb(device, ccb) < 0) {
840 warn("error getting serial number");
842 if (arglist & CAM_ARG_VERBOSE) {
843 cam_error_print(device, ccb, CAM_ESF_ALL,
844 CAM_EPF_ALL, stderr);
852 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
855 if (arglist & CAM_ARG_VERBOSE) {
856 cam_error_print(device, ccb, CAM_ESF_ALL,
857 CAM_EPF_ALL, stderr);
868 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
869 serial_num[serial_buf->length] = '\0';
871 if ((arglist & CAM_ARG_GET_STDINQ)
872 || (arglist & CAM_ARG_GET_XFERRATE))
873 fprintf(stdout, "%s%d: Serial Number ",
874 device->device_name, device->dev_unit_num);
876 fprintf(stdout, "%.60s\n", serial_num);
884 camxferrate(struct cam_device *device)
886 struct ccb_pathinq cpi;
893 if ((retval = get_cpi(device, &cpi)) != 0)
896 ccb = cam_getccb(device);
899 warnx("couldn't allocate CCB");
903 bzero(&(&ccb->ccb_h)[1],
904 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
906 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
907 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
909 if (((retval = cam_send_ccb(device, ccb)) < 0)
910 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
911 const char error_string[] = "error getting transfer settings";
918 if (arglist & CAM_ARG_VERBOSE)
919 cam_error_print(device, ccb, CAM_ESF_ALL,
920 CAM_EPF_ALL, stderr);
924 goto xferrate_bailout;
928 speed = cpi.base_transfer_speed;
930 if (ccb->cts.transport == XPORT_SPI) {
931 struct ccb_trans_settings_spi *spi =
932 &ccb->cts.xport_specific.spi;
934 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
935 freq = scsi_calc_syncsrate(spi->sync_period);
938 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
939 speed *= (0x01 << spi->bus_width);
941 } else if (ccb->cts.transport == XPORT_FC) {
942 struct ccb_trans_settings_fc *fc =
943 &ccb->cts.xport_specific.fc;
945 if (fc->valid & CTS_FC_VALID_SPEED)
947 } else if (ccb->cts.transport == XPORT_SAS) {
948 struct ccb_trans_settings_sas *sas =
949 &ccb->cts.xport_specific.sas;
951 if (sas->valid & CTS_SAS_VALID_SPEED)
952 speed = sas->bitrate;
953 } else if (ccb->cts.transport == XPORT_SATA) {
954 struct ccb_trans_settings_sata *sata =
955 &ccb->cts.xport_specific.sata;
957 if (sata->valid & CTS_SATA_VALID_SPEED)
958 speed = sata->bitrate;
963 fprintf(stdout, "%s%d: %d.%03dMB/s transfers ",
964 device->device_name, device->dev_unit_num,
967 fprintf(stdout, "%s%d: %dKB/s transfers ",
968 device->device_name, device->dev_unit_num,
972 if (ccb->cts.transport == XPORT_SPI) {
973 struct ccb_trans_settings_spi *spi =
974 &ccb->cts.xport_specific.spi;
976 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
977 && (spi->sync_offset != 0))
978 fprintf(stdout, "(%d.%03dMHz, offset %d", freq / 1000,
979 freq % 1000, spi->sync_offset);
981 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
982 && (spi->bus_width > 0)) {
983 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
984 && (spi->sync_offset != 0)) {
985 fprintf(stdout, ", ");
987 fprintf(stdout, " (");
989 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
990 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
991 && (spi->sync_offset != 0)) {
992 fprintf(stdout, ")");
994 } else if (ccb->cts.transport == XPORT_ATA) {
995 struct ccb_trans_settings_ata *ata =
996 &ccb->cts.xport_specific.ata;
998 if (ata->valid & CTS_ATA_VALID_BYTECOUNT) {
999 fprintf(stdout, "(PIO size %dbytes)",
1002 } else if (ccb->cts.transport == XPORT_SATA) {
1003 struct ccb_trans_settings_sata *sata =
1004 &ccb->cts.xport_specific.sata;
1006 if (sata->valid & CTS_SATA_VALID_BYTECOUNT) {
1007 fprintf(stdout, "(PIO size %dbytes)",
1012 if (ccb->cts.protocol == PROTO_SCSI) {
1013 struct ccb_trans_settings_scsi *scsi =
1014 &ccb->cts.proto_specific.scsi;
1015 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1016 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1017 fprintf(stdout, ", Command Queueing Enabled");
1022 fprintf(stdout, "\n");
1032 atacapprint(struct ata_params *parm)
1034 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1035 ((u_int32_t)parm->lba_size_2 << 16);
1037 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1038 ((u_int64_t)parm->lba_size48_2 << 16) |
1039 ((u_int64_t)parm->lba_size48_3 << 32) |
1040 ((u_int64_t)parm->lba_size48_4 << 48);
1043 printf("protocol ");
1044 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1045 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1046 if (parm->satacapabilities & ATA_SATA_GEN3)
1047 printf(" SATA 3.x\n");
1048 else if (parm->satacapabilities & ATA_SATA_GEN2)
1049 printf(" SATA 2.x\n");
1050 else if (parm->satacapabilities & ATA_SATA_GEN1)
1051 printf(" SATA 1.x\n");
1057 printf("device model %.40s\n", parm->model);
1058 printf("firmware revision %.8s\n", parm->revision);
1059 printf("serial number %.20s\n", parm->serial);
1060 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1061 printf("WWN %02x%02x%02x%02x\n",
1062 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1064 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1065 printf("media serial number %.30s\n",
1066 parm->media_serial);
1069 printf("cylinders %d\n", parm->cylinders);
1070 printf("heads %d\n", parm->heads);
1071 printf("sectors/track %d\n", parm->sectors);
1072 printf("sector size logical %u, physical %lu, offset %lu\n",
1073 ata_logical_sector_size(parm),
1074 (unsigned long)ata_physical_sector_size(parm),
1075 (unsigned long)ata_logical_sector_offset(parm));
1077 if (parm->config == ATA_PROTO_CFA ||
1078 (parm->support.command2 & ATA_SUPPORT_CFA))
1079 printf("CFA supported\n");
1081 printf("LBA%ssupported ",
1082 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1084 printf("%d sectors\n", lbasize);
1088 printf("LBA48%ssupported ",
1089 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1091 printf("%ju sectors\n", (uintmax_t)lbasize48);
1095 printf("PIO supported PIO");
1096 switch (ata_max_pmode(parm)) {
1112 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1113 printf(" w/o IORDY");
1116 printf("DMA%ssupported ",
1117 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1118 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1119 if (parm->mwdmamodes & 0xff) {
1121 if (parm->mwdmamodes & 0x04)
1123 else if (parm->mwdmamodes & 0x02)
1125 else if (parm->mwdmamodes & 0x01)
1129 if ((parm->atavalid & ATA_FLAG_88) &&
1130 (parm->udmamodes & 0xff)) {
1132 if (parm->udmamodes & 0x40)
1134 else if (parm->udmamodes & 0x20)
1136 else if (parm->udmamodes & 0x10)
1138 else if (parm->udmamodes & 0x08)
1140 else if (parm->udmamodes & 0x04)
1142 else if (parm->udmamodes & 0x02)
1144 else if (parm->udmamodes & 0x01)
1151 printf("overlap%ssupported\n",
1152 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? " " : " not ");
1153 if (parm->media_rotation_rate == 1) {
1154 printf("media RPM non-rotating\n");
1155 } else if (parm->media_rotation_rate >= 0x0401 &&
1156 parm->media_rotation_rate <= 0xFFFE) {
1157 printf("media RPM %d\n",
1158 parm->media_rotation_rate);
1162 "Support Enable Value Vendor\n");
1163 printf("read ahead %s %s\n",
1164 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1165 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1166 printf("write cache %s %s\n",
1167 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1168 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1169 printf("flush cache %s %s\n",
1170 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1171 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1172 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1173 printf("Native Command Queuing (NCQ) %s "
1175 parm->satacapabilities & ATA_SUPPORT_NCQ ?
1177 (parm->satacapabilities & ATA_SUPPORT_NCQ) ?
1178 ATA_QUEUE_LEN(parm->queue) : 0,
1179 (parm->satacapabilities & ATA_SUPPORT_NCQ) ?
1180 ATA_QUEUE_LEN(parm->queue) : 0);
1182 printf("Tagged Command Queuing (TCQ) %s %s %d/0x%02X\n",
1183 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1184 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1185 ATA_QUEUE_LEN(parm->queue), ATA_QUEUE_LEN(parm->queue));
1186 printf("SMART %s %s\n",
1187 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1188 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1189 printf("microcode download %s %s\n",
1190 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1191 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1192 printf("security %s %s\n",
1193 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1194 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1195 printf("power management %s %s\n",
1196 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1197 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1198 printf("advanced power management %s %s %d/0x%02X\n",
1199 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1200 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1201 parm->apm_value, parm->apm_value);
1202 printf("automatic acoustic management %s %s "
1203 "%d/0x%02X %d/0x%02X\n",
1204 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1205 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1206 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1207 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1208 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1209 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1210 printf("media status notification %s %s\n",
1211 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1212 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1213 printf("power-up in Standby %s %s\n",
1214 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1215 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1216 printf("write-read-verify %s %s %d/0x%x\n",
1217 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1218 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1219 parm->wrv_mode, parm->wrv_mode);
1220 printf("unload %s %s\n",
1221 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1222 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1223 printf("free-fall %s %s\n",
1224 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1225 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1230 ataidentify(struct cam_device *device, int retry_count, int timeout)
1233 struct ata_params *ident_buf;
1234 struct ccb_getdev cgd;
1238 if (get_cgd(device, &cgd) != 0) {
1239 warnx("couldn't get CGD");
1242 ccb = cam_getccb(device);
1245 warnx("couldn't allocate CCB");
1249 /* cam_getccb cleans up the header, caller has to zero the payload */
1250 bzero(&(&ccb->ccb_h)[1],
1251 sizeof(struct ccb_ataio) - sizeof(struct ccb_hdr));
1253 ptr = (uint16_t *)malloc(sizeof(struct ata_params));
1257 warnx("can't malloc memory for identify\n");
1260 bzero(ptr, sizeof(struct ata_params));
1262 cam_fill_ataio(&ccb->ataio,
1265 /*flags*/CAM_DIR_IN,
1267 /*data_ptr*/(u_int8_t *)ptr,
1268 /*dxfer_len*/sizeof(struct ata_params),
1269 timeout ? timeout : 30 * 1000);
1270 if (cgd.protocol == PROTO_ATA)
1271 ata_28bit_cmd(&ccb->ataio, ATA_ATA_IDENTIFY, 0, 0, 0);
1273 ata_28bit_cmd(&ccb->ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0);
1275 /* Disable freezing the device queue */
1276 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1278 if (arglist & CAM_ARG_ERR_RECOVER)
1279 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1281 if (cam_send_ccb(device, ccb) < 0) {
1282 perror("error sending ATA identify");
1284 if (arglist & CAM_ARG_VERBOSE) {
1285 cam_error_print(device, ccb, CAM_ESF_ALL,
1286 CAM_EPF_ALL, stderr);
1294 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1297 if (arglist & CAM_ARG_VERBOSE) {
1298 cam_error_print(device, ccb, CAM_ESF_ALL,
1299 CAM_EPF_ALL, stderr);
1310 for (i = 0; i < sizeof(struct ata_params) / 2; i++)
1311 ptr[i] = le16toh(ptr[i]);
1312 ident_buf = (struct ata_params *)ptr;
1314 if (strncmp(ident_buf->model, "FX", 2) &&
1315 strncmp(ident_buf->model, "NEC", 3) &&
1316 strncmp(ident_buf->model, "Pioneer", 7) &&
1317 strncmp(ident_buf->model, "SHARP", 5)) {
1318 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
1319 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
1320 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
1321 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
1323 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
1324 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
1325 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
1326 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
1327 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
1328 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
1329 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
1330 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
1331 sizeof(ident_buf->media_serial));
1333 fprintf(stdout, "%s%d: ", device->device_name,
1334 device->dev_unit_num);
1335 ata_print_ident(ident_buf);
1336 camxferrate(device);
1337 atacapprint(ident_buf);
1343 #endif /* MINIMALISTIC */
1346 * Parse out a bus, or a bus, target and lun in the following
1352 * Returns the number of parsed components, or 0.
1355 parse_btl(char *tstr, int *bus, int *target, int *lun, cam_argmask *arglst)
1360 while (isspace(*tstr) && (*tstr != '\0'))
1363 tmpstr = (char *)strtok(tstr, ":");
1364 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
1365 *bus = strtol(tmpstr, NULL, 0);
1366 *arglst |= CAM_ARG_BUS;
1368 tmpstr = (char *)strtok(NULL, ":");
1369 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
1370 *target = strtol(tmpstr, NULL, 0);
1371 *arglst |= CAM_ARG_TARGET;
1373 tmpstr = (char *)strtok(NULL, ":");
1374 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
1375 *lun = strtol(tmpstr, NULL, 0);
1376 *arglst |= CAM_ARG_LUN;
1386 dorescan_or_reset(int argc, char **argv, int rescan)
1388 static const char must[] =
1389 "you must specify \"all\", a bus, or a bus:target:lun to %s";
1391 int bus = -1, target = -1, lun = -1;
1395 warnx(must, rescan? "rescan" : "reset");
1399 tstr = argv[optind];
1400 while (isspace(*tstr) && (*tstr != '\0'))
1402 if (strncasecmp(tstr, "all", strlen("all")) == 0)
1403 arglist |= CAM_ARG_BUS;
1405 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
1406 if (rv != 1 && rv != 3) {
1407 warnx(must, rescan? "rescan" : "reset");
1412 if ((arglist & CAM_ARG_BUS)
1413 && (arglist & CAM_ARG_TARGET)
1414 && (arglist & CAM_ARG_LUN))
1415 error = scanlun_or_reset_dev(bus, target, lun, rescan);
1417 error = rescan_or_reset_bus(bus, rescan);
1423 rescan_or_reset_bus(int bus, int rescan)
1425 union ccb ccb, matchccb;
1431 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
1432 warnx("error opening transport layer device %s", XPT_DEVICE);
1433 warn("%s", XPT_DEVICE);
1438 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
1439 ccb.ccb_h.path_id = bus;
1440 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
1441 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
1442 ccb.crcn.flags = CAM_FLAG_NONE;
1444 /* run this at a low priority */
1445 ccb.ccb_h.pinfo.priority = 5;
1447 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
1448 warn("CAMIOCOMMAND ioctl failed");
1453 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
1454 fprintf(stdout, "%s of bus %d was successful\n",
1455 rescan ? "Re-scan" : "Reset", bus);
1457 fprintf(stdout, "%s of bus %d returned error %#x\n",
1458 rescan ? "Re-scan" : "Reset", bus,
1459 ccb.ccb_h.status & CAM_STATUS_MASK);
1470 * The right way to handle this is to modify the xpt so that it can
1471 * handle a wildcarded bus in a rescan or reset CCB. At the moment
1472 * that isn't implemented, so instead we enumerate the busses and
1473 * send the rescan or reset to those busses in the case where the
1474 * given bus is -1 (wildcard). We don't send a rescan or reset
1475 * to the xpt bus; sending a rescan to the xpt bus is effectively a
1476 * no-op, sending a rescan to the xpt bus would result in a status of
1479 bzero(&(&matchccb.ccb_h)[1],
1480 sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr));
1481 matchccb.ccb_h.func_code = XPT_DEV_MATCH;
1482 bufsize = sizeof(struct dev_match_result) * 20;
1483 matchccb.cdm.match_buf_len = bufsize;
1484 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
1485 if (matchccb.cdm.matches == NULL) {
1486 warnx("can't malloc memory for matches");
1490 matchccb.cdm.num_matches = 0;
1492 matchccb.cdm.num_patterns = 1;
1493 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
1495 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
1496 matchccb.cdm.pattern_buf_len);
1497 if (matchccb.cdm.patterns == NULL) {
1498 warnx("can't malloc memory for patterns");
1502 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
1503 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
1508 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
1509 warn("CAMIOCOMMAND ioctl failed");
1514 if ((matchccb.ccb_h.status != CAM_REQ_CMP)
1515 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
1516 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
1517 warnx("got CAM error %#x, CDM error %d\n",
1518 matchccb.ccb_h.status, matchccb.cdm.status);
1523 for (i = 0; i < matchccb.cdm.num_matches; i++) {
1524 struct bus_match_result *bus_result;
1526 /* This shouldn't happen. */
1527 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
1530 bus_result = &matchccb.cdm.matches[i].result.bus_result;
1533 * We don't want to rescan or reset the xpt bus.
1536 if ((int)bus_result->path_id == -1)
1539 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
1541 ccb.ccb_h.path_id = bus_result->path_id;
1542 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
1543 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
1544 ccb.crcn.flags = CAM_FLAG_NONE;
1546 /* run this at a low priority */
1547 ccb.ccb_h.pinfo.priority = 5;
1549 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
1550 warn("CAMIOCOMMAND ioctl failed");
1555 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
1556 fprintf(stdout, "%s of bus %d was successful\n",
1557 rescan? "Re-scan" : "Reset",
1558 bus_result->path_id);
1561 * Don't bail out just yet, maybe the other
1562 * rescan or reset commands will complete
1565 fprintf(stderr, "%s of bus %d returned error "
1566 "%#x\n", rescan? "Re-scan" : "Reset",
1567 bus_result->path_id,
1568 ccb.ccb_h.status & CAM_STATUS_MASK);
1572 } while ((matchccb.ccb_h.status == CAM_REQ_CMP)
1573 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
1580 if (matchccb.cdm.patterns != NULL)
1581 free(matchccb.cdm.patterns);
1582 if (matchccb.cdm.matches != NULL)
1583 free(matchccb.cdm.matches);
1589 scanlun_or_reset_dev(int bus, int target, int lun, int scan)
1592 struct cam_device *device;
1598 warnx("invalid bus number %d", bus);
1603 warnx("invalid target number %d", target);
1608 warnx("invalid lun number %d", lun);
1614 bzero(&ccb, sizeof(union ccb));
1617 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
1618 warnx("error opening transport layer device %s\n",
1620 warn("%s", XPT_DEVICE);
1624 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
1625 if (device == NULL) {
1626 warnx("%s", cam_errbuf);
1631 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
1632 ccb.ccb_h.path_id = bus;
1633 ccb.ccb_h.target_id = target;
1634 ccb.ccb_h.target_lun = lun;
1635 ccb.ccb_h.timeout = 5000;
1636 ccb.crcn.flags = CAM_FLAG_NONE;
1638 /* run this at a low priority */
1639 ccb.ccb_h.pinfo.priority = 5;
1642 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
1643 warn("CAMIOCOMMAND ioctl failed");
1648 if (cam_send_ccb(device, &ccb) < 0) {
1649 warn("error sending XPT_RESET_DEV CCB");
1650 cam_close_device(device);
1658 cam_close_device(device);
1661 * An error code of CAM_BDR_SENT is normal for a BDR request.
1663 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
1665 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
1666 fprintf(stdout, "%s of %d:%d:%d was successful\n",
1667 scan? "Re-scan" : "Reset", bus, target, lun);
1670 fprintf(stdout, "%s of %d:%d:%d returned error %#x\n",
1671 scan? "Re-scan" : "Reset", bus, target, lun,
1672 ccb.ccb_h.status & CAM_STATUS_MASK);
1677 #ifndef MINIMALISTIC
1679 readdefects(struct cam_device *device, int argc, char **argv,
1680 char *combinedopt, int retry_count, int timeout)
1682 union ccb *ccb = NULL;
1683 struct scsi_read_defect_data_10 *rdd_cdb;
1684 u_int8_t *defect_list = NULL;
1685 u_int32_t dlist_length = 65000;
1686 u_int32_t returned_length = 0;
1687 u_int32_t num_returned = 0;
1688 u_int8_t returned_format;
1691 int lists_specified = 0;
1693 while ((c = getopt(argc, argv, combinedopt)) != -1) {
1699 while (isspace(*tstr) && (*tstr != '\0'))
1701 if (strcmp(tstr, "block") == 0)
1702 arglist |= CAM_ARG_FORMAT_BLOCK;
1703 else if (strcmp(tstr, "bfi") == 0)
1704 arglist |= CAM_ARG_FORMAT_BFI;
1705 else if (strcmp(tstr, "phys") == 0)
1706 arglist |= CAM_ARG_FORMAT_PHYS;
1709 warnx("invalid defect format %s", tstr);
1710 goto defect_bailout;
1715 arglist |= CAM_ARG_GLIST;
1718 arglist |= CAM_ARG_PLIST;
1725 ccb = cam_getccb(device);
1728 * Hopefully 65000 bytes is enough to hold the defect list. If it
1729 * isn't, the disk is probably dead already. We'd have to go with
1730 * 12 byte command (i.e. alloc_length is 32 bits instead of 16)
1733 defect_list = malloc(dlist_length);
1734 if (defect_list == NULL) {
1735 warnx("can't malloc memory for defect list");
1737 goto defect_bailout;
1740 rdd_cdb =(struct scsi_read_defect_data_10 *)&ccb->csio.cdb_io.cdb_bytes;
1743 * cam_getccb() zeros the CCB header only. So we need to zero the
1744 * payload portion of the ccb.
1746 bzero(&(&ccb->ccb_h)[1],
1747 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1749 cam_fill_csio(&ccb->csio,
1750 /*retries*/ retry_count,
1752 /*flags*/ CAM_DIR_IN | ((arglist & CAM_ARG_ERR_RECOVER) ?
1753 CAM_PASS_ERR_RECOVER : 0),
1754 /*tag_action*/ MSG_SIMPLE_Q_TAG,
1755 /*data_ptr*/ defect_list,
1756 /*dxfer_len*/ dlist_length,
1757 /*sense_len*/ SSD_FULL_SIZE,
1758 /*cdb_len*/ sizeof(struct scsi_read_defect_data_10),
1759 /*timeout*/ timeout ? timeout : 5000);
1761 rdd_cdb->opcode = READ_DEFECT_DATA_10;
1762 if (arglist & CAM_ARG_FORMAT_BLOCK)
1763 rdd_cdb->format = SRDD10_BLOCK_FORMAT;
1764 else if (arglist & CAM_ARG_FORMAT_BFI)
1765 rdd_cdb->format = SRDD10_BYTES_FROM_INDEX_FORMAT;
1766 else if (arglist & CAM_ARG_FORMAT_PHYS)
1767 rdd_cdb->format = SRDD10_PHYSICAL_SECTOR_FORMAT;
1770 warnx("no defect list format specified");
1771 goto defect_bailout;
1773 if (arglist & CAM_ARG_PLIST) {
1774 rdd_cdb->format |= SRDD10_PLIST;
1778 if (arglist & CAM_ARG_GLIST) {
1779 rdd_cdb->format |= SRDD10_GLIST;
1783 scsi_ulto2b(dlist_length, rdd_cdb->alloc_length);
1785 /* Disable freezing the device queue */
1786 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1788 if (cam_send_ccb(device, ccb) < 0) {
1789 perror("error reading defect list");
1791 if (arglist & CAM_ARG_VERBOSE) {
1792 cam_error_print(device, ccb, CAM_ESF_ALL,
1793 CAM_EPF_ALL, stderr);
1797 goto defect_bailout;
1800 returned_length = scsi_2btoul(((struct
1801 scsi_read_defect_data_hdr_10 *)defect_list)->length);
1803 returned_format = ((struct scsi_read_defect_data_hdr_10 *)
1804 defect_list)->format;
1806 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
1807 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
1808 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
1809 struct scsi_sense_data *sense;
1810 int error_code, sense_key, asc, ascq;
1812 sense = &ccb->csio.sense_data;
1813 scsi_extract_sense(sense, &error_code, &sense_key, &asc, &ascq);
1816 * According to the SCSI spec, if the disk doesn't support
1817 * the requested format, it will generally return a sense
1818 * key of RECOVERED ERROR, and an additional sense code
1819 * of "DEFECT LIST NOT FOUND". So, we check for that, and
1820 * also check to make sure that the returned length is
1821 * greater than 0, and then print out whatever format the
1824 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
1825 && (asc == 0x1c) && (ascq == 0x00)
1826 && (returned_length > 0)) {
1827 warnx("requested defect format not available");
1828 switch(returned_format & SRDDH10_DLIST_FORMAT_MASK) {
1829 case SRDD10_BLOCK_FORMAT:
1830 warnx("Device returned block format");
1832 case SRDD10_BYTES_FROM_INDEX_FORMAT:
1833 warnx("Device returned bytes from index"
1836 case SRDD10_PHYSICAL_SECTOR_FORMAT:
1837 warnx("Device returned physical sector format");
1841 warnx("Device returned unknown defect"
1842 " data format %#x", returned_format);
1843 goto defect_bailout;
1844 break; /* NOTREACHED */
1848 warnx("Error returned from read defect data command");
1849 if (arglist & CAM_ARG_VERBOSE)
1850 cam_error_print(device, ccb, CAM_ESF_ALL,
1851 CAM_EPF_ALL, stderr);
1852 goto defect_bailout;
1854 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1856 warnx("Error returned from read defect data command");
1857 if (arglist & CAM_ARG_VERBOSE)
1858 cam_error_print(device, ccb, CAM_ESF_ALL,
1859 CAM_EPF_ALL, stderr);
1860 goto defect_bailout;
1864 * XXX KDM I should probably clean up the printout format for the
1867 switch (returned_format & SRDDH10_DLIST_FORMAT_MASK){
1868 case SRDDH10_PHYSICAL_SECTOR_FORMAT:
1870 struct scsi_defect_desc_phys_sector *dlist;
1872 dlist = (struct scsi_defect_desc_phys_sector *)
1874 sizeof(struct scsi_read_defect_data_hdr_10));
1876 num_returned = returned_length /
1877 sizeof(struct scsi_defect_desc_phys_sector);
1879 fprintf(stderr, "Got %d defect", num_returned);
1881 if ((lists_specified == 0) || (num_returned == 0)) {
1882 fprintf(stderr, "s.\n");
1884 } else if (num_returned == 1)
1885 fprintf(stderr, ":\n");
1887 fprintf(stderr, "s:\n");
1889 for (i = 0; i < num_returned; i++) {
1890 fprintf(stdout, "%d:%d:%d\n",
1891 scsi_3btoul(dlist[i].cylinder),
1893 scsi_4btoul(dlist[i].sector));
1897 case SRDDH10_BYTES_FROM_INDEX_FORMAT:
1899 struct scsi_defect_desc_bytes_from_index *dlist;
1901 dlist = (struct scsi_defect_desc_bytes_from_index *)
1903 sizeof(struct scsi_read_defect_data_hdr_10));
1905 num_returned = returned_length /
1906 sizeof(struct scsi_defect_desc_bytes_from_index);
1908 fprintf(stderr, "Got %d defect", num_returned);
1910 if ((lists_specified == 0) || (num_returned == 0)) {
1911 fprintf(stderr, "s.\n");
1913 } else if (num_returned == 1)
1914 fprintf(stderr, ":\n");
1916 fprintf(stderr, "s:\n");
1918 for (i = 0; i < num_returned; i++) {
1919 fprintf(stdout, "%d:%d:%d\n",
1920 scsi_3btoul(dlist[i].cylinder),
1922 scsi_4btoul(dlist[i].bytes_from_index));
1926 case SRDDH10_BLOCK_FORMAT:
1928 struct scsi_defect_desc_block *dlist;
1930 dlist = (struct scsi_defect_desc_block *)(defect_list +
1931 sizeof(struct scsi_read_defect_data_hdr_10));
1933 num_returned = returned_length /
1934 sizeof(struct scsi_defect_desc_block);
1936 fprintf(stderr, "Got %d defect", num_returned);
1938 if ((lists_specified == 0) || (num_returned == 0)) {
1939 fprintf(stderr, "s.\n");
1941 } else if (num_returned == 1)
1942 fprintf(stderr, ":\n");
1944 fprintf(stderr, "s:\n");
1946 for (i = 0; i < num_returned; i++)
1947 fprintf(stdout, "%u\n",
1948 scsi_4btoul(dlist[i].address));
1952 fprintf(stderr, "Unknown defect format %d\n",
1953 returned_format & SRDDH10_DLIST_FORMAT_MASK);
1959 if (defect_list != NULL)
1967 #endif /* MINIMALISTIC */
1971 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
1975 ccb = cam_getccb(device);
1981 #ifndef MINIMALISTIC
1983 mode_sense(struct cam_device *device, int mode_page, int page_control,
1984 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
1989 ccb = cam_getccb(device);
1992 errx(1, "mode_sense: couldn't allocate CCB");
1994 bzero(&(&ccb->ccb_h)[1],
1995 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1997 scsi_mode_sense(&ccb->csio,
1998 /* retries */ retry_count,
2000 /* tag_action */ MSG_SIMPLE_Q_TAG,
2002 /* page_code */ page_control << 6,
2003 /* page */ mode_page,
2004 /* param_buf */ data,
2005 /* param_len */ datalen,
2006 /* sense_len */ SSD_FULL_SIZE,
2007 /* timeout */ timeout ? timeout : 5000);
2009 if (arglist & CAM_ARG_ERR_RECOVER)
2010 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
2012 /* Disable freezing the device queue */
2013 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
2015 if (((retval = cam_send_ccb(device, ccb)) < 0)
2016 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
2017 if (arglist & CAM_ARG_VERBOSE) {
2018 cam_error_print(device, ccb, CAM_ESF_ALL,
2019 CAM_EPF_ALL, stderr);
2022 cam_close_device(device);
2024 err(1, "error sending mode sense command");
2026 errx(1, "error sending mode sense command");
2033 mode_select(struct cam_device *device, int save_pages, int retry_count,
2034 int timeout, u_int8_t *data, int datalen)
2039 ccb = cam_getccb(device);
2042 errx(1, "mode_select: couldn't allocate CCB");
2044 bzero(&(&ccb->ccb_h)[1],
2045 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
2047 scsi_mode_select(&ccb->csio,
2048 /* retries */ retry_count,
2050 /* tag_action */ MSG_SIMPLE_Q_TAG,
2051 /* scsi_page_fmt */ 1,
2052 /* save_pages */ save_pages,
2053 /* param_buf */ data,
2054 /* param_len */ datalen,
2055 /* sense_len */ SSD_FULL_SIZE,
2056 /* timeout */ timeout ? timeout : 5000);
2058 if (arglist & CAM_ARG_ERR_RECOVER)
2059 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
2061 /* Disable freezing the device queue */
2062 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
2064 if (((retval = cam_send_ccb(device, ccb)) < 0)
2065 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
2066 if (arglist & CAM_ARG_VERBOSE) {
2067 cam_error_print(device, ccb, CAM_ESF_ALL,
2068 CAM_EPF_ALL, stderr);
2071 cam_close_device(device);
2074 err(1, "error sending mode select command");
2076 errx(1, "error sending mode select command");
2084 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
2085 int retry_count, int timeout)
2087 int c, mode_page = -1, page_control = 0;
2088 int binary = 0, list = 0;
2090 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2096 arglist |= CAM_ARG_DBD;
2099 arglist |= CAM_ARG_MODE_EDIT;
2105 mode_page = strtol(optarg, NULL, 0);
2107 errx(1, "invalid mode page %d", mode_page);
2110 page_control = strtol(optarg, NULL, 0);
2111 if ((page_control < 0) || (page_control > 3))
2112 errx(1, "invalid page control field %d",
2114 arglist |= CAM_ARG_PAGE_CNTL;
2121 if (mode_page == -1 && list == 0)
2122 errx(1, "you must specify a mode page!");
2125 mode_list(device, page_control, arglist & CAM_ARG_DBD,
2126 retry_count, timeout);
2128 mode_edit(device, mode_page, page_control,
2129 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
2130 retry_count, timeout);
2135 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
2136 int retry_count, int timeout)
2139 u_int32_t flags = CAM_DIR_NONE;
2140 u_int8_t *data_ptr = NULL;
2142 u_int8_t atacmd[12];
2143 struct get_hook hook;
2144 int c, data_bytes = 0;
2148 char *datastr = NULL, *tstr, *resstr = NULL;
2150 int fd_data = 0, fd_res = 0;
2153 ccb = cam_getccb(device);
2156 warnx("scsicmd: error allocating ccb");
2160 bzero(&(&ccb->ccb_h)[1],
2161 sizeof(union ccb) - sizeof(struct ccb_hdr));
2163 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2167 while (isspace(*tstr) && (*tstr != '\0'))
2169 hook.argc = argc - optind;
2170 hook.argv = argv + optind;
2172 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
2175 * Increment optind by the number of arguments the
2176 * encoding routine processed. After each call to
2177 * getopt(3), optind points to the argument that
2178 * getopt should process _next_. In this case,
2179 * that means it points to the first command string
2180 * argument, if there is one. Once we increment
2181 * this, it should point to either the next command
2182 * line argument, or it should be past the end of
2189 while (isspace(*tstr) && (*tstr != '\0'))
2191 hook.argc = argc - optind;
2192 hook.argv = argv + optind;
2194 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
2197 * Increment optind by the number of arguments the
2198 * encoding routine processed. After each call to
2199 * getopt(3), optind points to the argument that
2200 * getopt should process _next_. In this case,
2201 * that means it points to the first command string
2202 * argument, if there is one. Once we increment
2203 * this, it should point to either the next command
2204 * line argument, or it should be past the end of
2210 if (arglist & CAM_ARG_CMD_OUT) {
2211 warnx("command must either be "
2212 "read or write, not both");
2214 goto scsicmd_bailout;
2216 arglist |= CAM_ARG_CMD_IN;
2218 data_bytes = strtol(optarg, NULL, 0);
2219 if (data_bytes <= 0) {
2220 warnx("invalid number of input bytes %d",
2223 goto scsicmd_bailout;
2225 hook.argc = argc - optind;
2226 hook.argv = argv + optind;
2229 datastr = cget(&hook, NULL);
2231 * If the user supplied "-" instead of a format, he
2232 * wants the data to be written to stdout.
2234 if ((datastr != NULL)
2235 && (datastr[0] == '-'))
2238 data_ptr = (u_int8_t *)malloc(data_bytes);
2239 if (data_ptr == NULL) {
2240 warnx("can't malloc memory for data_ptr");
2242 goto scsicmd_bailout;
2246 if (arglist & CAM_ARG_CMD_IN) {
2247 warnx("command must either be "
2248 "read or write, not both");
2250 goto scsicmd_bailout;
2252 arglist |= CAM_ARG_CMD_OUT;
2253 flags = CAM_DIR_OUT;
2254 data_bytes = strtol(optarg, NULL, 0);
2255 if (data_bytes <= 0) {
2256 warnx("invalid number of output bytes %d",
2259 goto scsicmd_bailout;
2261 hook.argc = argc - optind;
2262 hook.argv = argv + optind;
2264 datastr = cget(&hook, NULL);
2265 data_ptr = (u_int8_t *)malloc(data_bytes);
2266 if (data_ptr == NULL) {
2267 warnx("can't malloc memory for data_ptr");
2269 goto scsicmd_bailout;
2272 * If the user supplied "-" instead of a format, he
2273 * wants the data to be read from stdin.
2275 if ((datastr != NULL)
2276 && (datastr[0] == '-'))
2279 buff_encode_visit(data_ptr, data_bytes, datastr,
2285 hook.argc = argc - optind;
2286 hook.argv = argv + optind;
2288 resstr = cget(&hook, NULL);
2289 if ((resstr != NULL) && (resstr[0] == '-'))
2299 * If fd_data is set, and we're writing to the device, we need to
2300 * read the data the user wants written from stdin.
2302 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
2304 int amt_to_read = data_bytes;
2305 u_int8_t *buf_ptr = data_ptr;
2307 for (amt_read = 0; amt_to_read > 0;
2308 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
2309 if (amt_read == -1) {
2310 warn("error reading data from stdin");
2312 goto scsicmd_bailout;
2314 amt_to_read -= amt_read;
2315 buf_ptr += amt_read;
2319 if (arglist & CAM_ARG_ERR_RECOVER)
2320 flags |= CAM_PASS_ERR_RECOVER;
2322 /* Disable freezing the device queue */
2323 flags |= CAM_DEV_QFRZDIS;
2327 * This is taken from the SCSI-3 draft spec.
2328 * (T10/1157D revision 0.3)
2329 * The top 3 bits of an opcode are the group code.
2330 * The next 5 bits are the command code.
2331 * Group 0: six byte commands
2332 * Group 1: ten byte commands
2333 * Group 2: ten byte commands
2335 * Group 4: sixteen byte commands
2336 * Group 5: twelve byte commands
2337 * Group 6: vendor specific
2338 * Group 7: vendor specific
2340 switch((cdb[0] >> 5) & 0x7) {
2351 /* computed by buff_encode_visit */
2362 * We should probably use csio_build_visit or something like that
2363 * here, but it's easier to encode arguments as you go. The
2364 * alternative would be skipping the CDB argument and then encoding
2365 * it here, since we've got the data buffer argument by now.
2367 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
2369 cam_fill_csio(&ccb->csio,
2370 /*retries*/ retry_count,
2373 /*tag_action*/ MSG_SIMPLE_Q_TAG,
2374 /*data_ptr*/ data_ptr,
2375 /*dxfer_len*/ data_bytes,
2376 /*sense_len*/ SSD_FULL_SIZE,
2377 /*cdb_len*/ cdb_len,
2378 /*timeout*/ timeout ? timeout : 5000);
2381 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
2383 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
2385 cam_fill_ataio(&ccb->ataio,
2386 /*retries*/ retry_count,
2390 /*data_ptr*/ data_ptr,
2391 /*dxfer_len*/ data_bytes,
2392 /*timeout*/ timeout ? timeout : 5000);
2395 if (((retval = cam_send_ccb(device, ccb)) < 0)
2396 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
2398 warn("error sending command");
2400 warnx("error sending command");
2402 if (arglist & CAM_ARG_VERBOSE) {
2403 cam_error_print(device, ccb, CAM_ESF_ALL,
2404 CAM_EPF_ALL, stderr);
2408 goto scsicmd_bailout;
2411 if (atacmd_len && need_res) {
2413 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
2415 fprintf(stdout, "\n");
2418 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
2419 ccb->ataio.res.status,
2420 ccb->ataio.res.error,
2421 ccb->ataio.res.lba_low,
2422 ccb->ataio.res.lba_mid,
2423 ccb->ataio.res.lba_high,
2424 ccb->ataio.res.device,
2425 ccb->ataio.res.lba_low_exp,
2426 ccb->ataio.res.lba_mid_exp,
2427 ccb->ataio.res.lba_high_exp,
2428 ccb->ataio.res.sector_count,
2429 ccb->ataio.res.sector_count_exp);
2434 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
2435 && (arglist & CAM_ARG_CMD_IN)
2436 && (data_bytes > 0)) {
2438 buff_decode_visit(data_ptr, data_bytes, datastr,
2440 fprintf(stdout, "\n");
2442 ssize_t amt_written;
2443 int amt_to_write = data_bytes;
2444 u_int8_t *buf_ptr = data_ptr;
2446 for (amt_written = 0; (amt_to_write > 0) &&
2447 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
2448 amt_to_write -= amt_written;
2449 buf_ptr += amt_written;
2451 if (amt_written == -1) {
2452 warn("error writing data to stdout");
2454 goto scsicmd_bailout;
2455 } else if ((amt_written == 0)
2456 && (amt_to_write > 0)) {
2457 warnx("only wrote %u bytes out of %u",
2458 data_bytes - amt_to_write, data_bytes);
2465 if ((data_bytes > 0) && (data_ptr != NULL))
2474 camdebug(int argc, char **argv, char *combinedopt)
2477 int bus = -1, target = -1, lun = -1;
2478 char *tstr, *tmpstr = NULL;
2482 bzero(&ccb, sizeof(union ccb));
2484 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2487 arglist |= CAM_ARG_DEBUG_INFO;
2488 ccb.cdbg.flags |= CAM_DEBUG_INFO;
2491 arglist |= CAM_ARG_DEBUG_PERIPH;
2492 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
2495 arglist |= CAM_ARG_DEBUG_SUBTRACE;
2496 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
2499 arglist |= CAM_ARG_DEBUG_TRACE;
2500 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
2503 arglist |= CAM_ARG_DEBUG_XPT;
2504 ccb.cdbg.flags |= CAM_DEBUG_XPT;
2507 arglist |= CAM_ARG_DEBUG_CDB;
2508 ccb.cdbg.flags |= CAM_DEBUG_CDB;
2515 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
2516 warnx("error opening transport layer device %s", XPT_DEVICE);
2517 warn("%s", XPT_DEVICE);
2524 warnx("you must specify \"off\", \"all\" or a bus,");
2525 warnx("bus:target, or bus:target:lun");
2532 while (isspace(*tstr) && (*tstr != '\0'))
2535 if (strncmp(tstr, "off", 3) == 0) {
2536 ccb.cdbg.flags = CAM_DEBUG_NONE;
2537 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
2538 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
2540 } else if (strncmp(tstr, "all", 3) != 0) {
2541 tmpstr = (char *)strtok(tstr, ":");
2542 if ((tmpstr != NULL) && (*tmpstr != '\0')){
2543 bus = strtol(tmpstr, NULL, 0);
2544 arglist |= CAM_ARG_BUS;
2545 tmpstr = (char *)strtok(NULL, ":");
2546 if ((tmpstr != NULL) && (*tmpstr != '\0')){
2547 target = strtol(tmpstr, NULL, 0);
2548 arglist |= CAM_ARG_TARGET;
2549 tmpstr = (char *)strtok(NULL, ":");
2550 if ((tmpstr != NULL) && (*tmpstr != '\0')){
2551 lun = strtol(tmpstr, NULL, 0);
2552 arglist |= CAM_ARG_LUN;
2557 warnx("you must specify \"all\", \"off\", or a bus,");
2558 warnx("bus:target, or bus:target:lun to debug");
2564 ccb.ccb_h.func_code = XPT_DEBUG;
2565 ccb.ccb_h.path_id = bus;
2566 ccb.ccb_h.target_id = target;
2567 ccb.ccb_h.target_lun = lun;
2569 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
2570 warn("CAMIOCOMMAND ioctl failed");
2575 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
2576 CAM_FUNC_NOTAVAIL) {
2577 warnx("CAM debugging not available");
2578 warnx("you need to put options CAMDEBUG in"
2579 " your kernel config file!");
2581 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
2583 warnx("XPT_DEBUG CCB failed with status %#x",
2587 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
2589 "Debugging turned off\n");
2592 "Debugging enabled for "
2605 tagcontrol(struct cam_device *device, int argc, char **argv,
2615 ccb = cam_getccb(device);
2618 warnx("tagcontrol: error allocating ccb");
2622 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2625 numtags = strtol(optarg, NULL, 0);
2627 warnx("tag count %d is < 0", numtags);
2629 goto tagcontrol_bailout;
2640 cam_path_string(device, pathstr, sizeof(pathstr));
2643 bzero(&(&ccb->ccb_h)[1],
2644 sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
2645 ccb->ccb_h.func_code = XPT_REL_SIMQ;
2646 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
2647 ccb->crs.openings = numtags;
2650 if (cam_send_ccb(device, ccb) < 0) {
2651 perror("error sending XPT_REL_SIMQ CCB");
2653 goto tagcontrol_bailout;
2656 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2657 warnx("XPT_REL_SIMQ CCB failed");
2658 cam_error_print(device, ccb, CAM_ESF_ALL,
2659 CAM_EPF_ALL, stderr);
2661 goto tagcontrol_bailout;
2666 fprintf(stdout, "%stagged openings now %d\n",
2667 pathstr, ccb->crs.openings);
2670 bzero(&(&ccb->ccb_h)[1],
2671 sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr));
2673 ccb->ccb_h.func_code = XPT_GDEV_STATS;
2675 if (cam_send_ccb(device, ccb) < 0) {
2676 perror("error sending XPT_GDEV_STATS CCB");
2678 goto tagcontrol_bailout;
2681 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2682 warnx("XPT_GDEV_STATS CCB failed");
2683 cam_error_print(device, ccb, CAM_ESF_ALL,
2684 CAM_EPF_ALL, stderr);
2686 goto tagcontrol_bailout;
2689 if (arglist & CAM_ARG_VERBOSE) {
2690 fprintf(stdout, "%s", pathstr);
2691 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
2692 fprintf(stdout, "%s", pathstr);
2693 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
2694 fprintf(stdout, "%s", pathstr);
2695 fprintf(stdout, "devq_openings %d\n", ccb->cgds.devq_openings);
2696 fprintf(stdout, "%s", pathstr);
2697 fprintf(stdout, "devq_queued %d\n", ccb->cgds.devq_queued);
2698 fprintf(stdout, "%s", pathstr);
2699 fprintf(stdout, "held %d\n", ccb->cgds.held);
2700 fprintf(stdout, "%s", pathstr);
2701 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
2702 fprintf(stdout, "%s", pathstr);
2703 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
2706 fprintf(stdout, "%s", pathstr);
2707 fprintf(stdout, "device openings: ");
2709 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
2710 ccb->cgds.dev_active);
2720 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
2724 cam_path_string(device, pathstr, sizeof(pathstr));
2726 if (cts->transport == XPORT_SPI) {
2727 struct ccb_trans_settings_spi *spi =
2728 &cts->xport_specific.spi;
2730 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
2732 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
2735 if (spi->sync_offset != 0) {
2738 freq = scsi_calc_syncsrate(spi->sync_period);
2739 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
2740 pathstr, freq / 1000, freq % 1000);
2744 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
2745 fprintf(stdout, "%soffset: %d\n", pathstr,
2749 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
2750 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
2751 (0x01 << spi->bus_width) * 8);
2754 if (spi->valid & CTS_SPI_VALID_DISC) {
2755 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
2756 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
2757 "enabled" : "disabled");
2761 if (cts->protocol == PROTO_SCSI) {
2762 struct ccb_trans_settings_scsi *scsi=
2763 &cts->proto_specific.scsi;
2765 if (scsi->valid & CTS_SCSI_VALID_TQ) {
2766 fprintf(stdout, "%stagged queueing is %s\n", pathstr,
2767 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
2768 "enabled" : "disabled");
2775 * Get a path inquiry CCB for the specified device.
2778 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
2783 ccb = cam_getccb(device);
2785 warnx("get_cpi: couldn't allocate CCB");
2788 bzero(&(&ccb->ccb_h)[1],
2789 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
2790 ccb->ccb_h.func_code = XPT_PATH_INQ;
2791 if (cam_send_ccb(device, ccb) < 0) {
2792 warn("get_cpi: error sending Path Inquiry CCB");
2793 if (arglist & CAM_ARG_VERBOSE)
2794 cam_error_print(device, ccb, CAM_ESF_ALL,
2795 CAM_EPF_ALL, stderr);
2797 goto get_cpi_bailout;
2799 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2800 if (arglist & CAM_ARG_VERBOSE)
2801 cam_error_print(device, ccb, CAM_ESF_ALL,
2802 CAM_EPF_ALL, stderr);
2804 goto get_cpi_bailout;
2806 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
2814 * Get a get device CCB for the specified device.
2817 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
2822 ccb = cam_getccb(device);
2824 warnx("get_cgd: couldn't allocate CCB");
2827 bzero(&(&ccb->ccb_h)[1],
2828 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
2829 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
2830 if (cam_send_ccb(device, ccb) < 0) {
2831 warn("get_cgd: error sending Path Inquiry CCB");
2832 if (arglist & CAM_ARG_VERBOSE)
2833 cam_error_print(device, ccb, CAM_ESF_ALL,
2834 CAM_EPF_ALL, stderr);
2836 goto get_cgd_bailout;
2838 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2839 if (arglist & CAM_ARG_VERBOSE)
2840 cam_error_print(device, ccb, CAM_ESF_ALL,
2841 CAM_EPF_ALL, stderr);
2843 goto get_cgd_bailout;
2845 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
2853 cpi_print(struct ccb_pathinq *cpi)
2855 char adapter_str[1024];
2858 snprintf(adapter_str, sizeof(adapter_str),
2859 "%s%d:", cpi->dev_name, cpi->unit_number);
2861 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
2864 for (i = 1; i < 0xff; i = i << 1) {
2867 if ((i & cpi->hba_inquiry) == 0)
2870 fprintf(stdout, "%s supports ", adapter_str);
2874 str = "MDP message";
2877 str = "32 bit wide SCSI";
2880 str = "16 bit wide SCSI";
2883 str = "SDTR message";
2886 str = "linked CDBs";
2889 str = "tag queue messages";
2892 str = "soft reset alternative";
2895 str = "SATA Port Multiplier";
2898 str = "unknown PI bit set";
2901 fprintf(stdout, "%s\n", str);
2904 for (i = 1; i < 0xff; i = i << 1) {
2907 if ((i & cpi->hba_misc) == 0)
2910 fprintf(stdout, "%s ", adapter_str);
2914 str = "bus scans from high ID to low ID";
2917 str = "removable devices not included in scan";
2919 case PIM_NOINITIATOR:
2920 str = "initiator role not supported";
2922 case PIM_NOBUSRESET:
2923 str = "user has disabled initial BUS RESET or"
2924 " controller is in target/mixed mode";
2927 str = "do not send 6-byte commands";
2930 str = "scan bus sequentially";
2933 str = "unknown PIM bit set";
2936 fprintf(stdout, "%s\n", str);
2939 for (i = 1; i < 0xff; i = i << 1) {
2942 if ((i & cpi->target_sprt) == 0)
2945 fprintf(stdout, "%s supports ", adapter_str);
2948 str = "target mode processor mode";
2951 str = "target mode phase cog. mode";
2953 case PIT_DISCONNECT:
2954 str = "disconnects in target mode";
2957 str = "terminate I/O message in target mode";
2960 str = "group 6 commands in target mode";
2963 str = "group 7 commands in target mode";
2966 str = "unknown PIT bit set";
2970 fprintf(stdout, "%s\n", str);
2972 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
2974 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
2976 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
2978 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
2979 adapter_str, cpi->hpath_id);
2980 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
2982 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
2983 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
2984 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
2985 fprintf(stdout, "%s base transfer speed: ", adapter_str);
2986 if (cpi->base_transfer_speed > 1000)
2987 fprintf(stdout, "%d.%03dMB/sec\n",
2988 cpi->base_transfer_speed / 1000,
2989 cpi->base_transfer_speed % 1000);
2991 fprintf(stdout, "%dKB/sec\n",
2992 (cpi->base_transfer_speed % 1000) * 1000);
2996 get_print_cts(struct cam_device *device, int user_settings, int quiet,
2997 struct ccb_trans_settings *cts)
3003 ccb = cam_getccb(device);
3006 warnx("get_print_cts: error allocating ccb");
3010 bzero(&(&ccb->ccb_h)[1],
3011 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
3013 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
3015 if (user_settings == 0)
3016 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
3018 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
3020 if (cam_send_ccb(device, ccb) < 0) {
3021 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
3022 if (arglist & CAM_ARG_VERBOSE)
3023 cam_error_print(device, ccb, CAM_ESF_ALL,
3024 CAM_EPF_ALL, stderr);
3026 goto get_print_cts_bailout;
3029 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3030 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
3031 if (arglist & CAM_ARG_VERBOSE)
3032 cam_error_print(device, ccb, CAM_ESF_ALL,
3033 CAM_EPF_ALL, stderr);
3035 goto get_print_cts_bailout;
3039 cts_print(device, &ccb->cts);
3042 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
3044 get_print_cts_bailout:
3052 ratecontrol(struct cam_device *device, int retry_count, int timeout,
3053 int argc, char **argv, char *combinedopt)
3057 int user_settings = 0;
3059 int disc_enable = -1, tag_enable = -1;
3061 double syncrate = -1;
3064 int change_settings = 0, send_tur = 0;
3065 struct ccb_pathinq cpi;
3067 ccb = cam_getccb(device);
3070 warnx("ratecontrol: error allocating ccb");
3074 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3083 if (strncasecmp(optarg, "enable", 6) == 0)
3085 else if (strncasecmp(optarg, "disable", 7) == 0)
3088 warnx("-D argument \"%s\" is unknown", optarg);
3090 goto ratecontrol_bailout;
3092 change_settings = 1;
3095 offset = strtol(optarg, NULL, 0);
3097 warnx("offset value %d is < 0", offset);
3099 goto ratecontrol_bailout;
3101 change_settings = 1;
3107 syncrate = atof(optarg);
3110 warnx("sync rate %f is < 0", syncrate);
3112 goto ratecontrol_bailout;
3114 change_settings = 1;
3117 if (strncasecmp(optarg, "enable", 6) == 0)
3119 else if (strncasecmp(optarg, "disable", 7) == 0)
3122 warnx("-T argument \"%s\" is unknown", optarg);
3124 goto ratecontrol_bailout;
3126 change_settings = 1;
3132 bus_width = strtol(optarg, NULL, 0);
3133 if (bus_width < 0) {
3134 warnx("bus width %d is < 0", bus_width);
3136 goto ratecontrol_bailout;
3138 change_settings = 1;
3145 bzero(&(&ccb->ccb_h)[1],
3146 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
3149 * Grab path inquiry information, so we can determine whether
3150 * or not the initiator is capable of the things that the user
3153 ccb->ccb_h.func_code = XPT_PATH_INQ;
3155 if (cam_send_ccb(device, ccb) < 0) {
3156 perror("error sending XPT_PATH_INQ CCB");
3157 if (arglist & CAM_ARG_VERBOSE) {
3158 cam_error_print(device, ccb, CAM_ESF_ALL,
3159 CAM_EPF_ALL, stderr);
3162 goto ratecontrol_bailout;
3165 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3166 warnx("XPT_PATH_INQ CCB failed");
3167 if (arglist & CAM_ARG_VERBOSE) {
3168 cam_error_print(device, ccb, CAM_ESF_ALL,
3169 CAM_EPF_ALL, stderr);
3172 goto ratecontrol_bailout;
3175 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
3177 bzero(&(&ccb->ccb_h)[1],
3178 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
3181 fprintf(stdout, "Current Parameters:\n");
3183 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
3186 goto ratecontrol_bailout;
3188 if (arglist & CAM_ARG_VERBOSE)
3191 if (change_settings) {
3192 int didsettings = 0;
3193 struct ccb_trans_settings_spi *spi = NULL;
3194 struct ccb_trans_settings_scsi *scsi = NULL;
3196 if (ccb->cts.transport == XPORT_SPI) {
3197 spi = &ccb->cts.xport_specific.spi;
3200 if (ccb->cts.protocol == PROTO_SCSI) {
3201 scsi = &ccb->cts.proto_specific.scsi;
3204 if (spi && disc_enable != -1) {
3205 spi->valid |= CTS_SPI_VALID_DISC;
3206 if (disc_enable == 0)
3207 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
3209 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
3212 if (scsi && tag_enable != -1) {
3213 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
3214 warnx("HBA does not support tagged queueing, "
3215 "so you cannot modify tag settings");
3217 goto ratecontrol_bailout;
3220 scsi->valid |= CTS_SCSI_VALID_TQ;
3222 if (tag_enable == 0)
3223 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
3225 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
3229 if (spi && offset != -1) {
3230 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3231 warnx("HBA at %s%d is not cable of changing "
3232 "offset", cpi.dev_name,
3235 goto ratecontrol_bailout;
3237 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
3238 spi->sync_offset = offset;
3242 if (spi && syncrate != -1) {
3243 int prelim_sync_period;
3246 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
3247 warnx("HBA at %s%d is not cable of changing "
3248 "transfer rates", cpi.dev_name,
3251 goto ratecontrol_bailout;
3254 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
3257 * The sync rate the user gives us is in MHz.
3258 * We need to translate it into KHz for this
3264 * Next, we calculate a "preliminary" sync period
3265 * in tenths of a nanosecond.
3268 prelim_sync_period = 0;
3270 prelim_sync_period = 10000000 / syncrate;
3273 scsi_calc_syncparam(prelim_sync_period);
3275 freq = scsi_calc_syncsrate(spi->sync_period);
3280 * The bus_width argument goes like this:
3284 * Therefore, if you shift the number of bits given on the
3285 * command line right by 4, you should get the correct
3288 if (spi && bus_width != -1) {
3291 * We might as well validate things here with a
3292 * decipherable error message, rather than what
3293 * will probably be an indecipherable error message
3294 * by the time it gets back to us.
3296 if ((bus_width == 16)
3297 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
3298 warnx("HBA does not support 16 bit bus width");
3300 goto ratecontrol_bailout;
3301 } else if ((bus_width == 32)
3302 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
3303 warnx("HBA does not support 32 bit bus width");
3305 goto ratecontrol_bailout;
3306 } else if ((bus_width != 8)
3307 && (bus_width != 16)
3308 && (bus_width != 32)) {
3309 warnx("Invalid bus width %d", bus_width);
3311 goto ratecontrol_bailout;
3314 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
3315 spi->bus_width = bus_width >> 4;
3319 if (didsettings == 0) {
3320 goto ratecontrol_bailout;
3322 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
3324 if (cam_send_ccb(device, ccb) < 0) {
3325 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
3326 if (arglist & CAM_ARG_VERBOSE) {
3327 cam_error_print(device, ccb, CAM_ESF_ALL,
3328 CAM_EPF_ALL, stderr);
3331 goto ratecontrol_bailout;
3334 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3335 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
3336 if (arglist & CAM_ARG_VERBOSE) {
3337 cam_error_print(device, ccb, CAM_ESF_ALL,
3338 CAM_EPF_ALL, stderr);
3341 goto ratecontrol_bailout;
3346 retval = testunitready(device, retry_count, timeout,
3347 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
3350 * If the TUR didn't succeed, just bail.
3354 fprintf(stderr, "Test Unit Ready failed\n");
3355 goto ratecontrol_bailout;
3359 * If the user wants things quiet, there's no sense in
3360 * getting the transfer settings, if we're not going
3364 goto ratecontrol_bailout;
3366 fprintf(stdout, "New Parameters:\n");
3367 retval = get_print_cts(device, user_settings, 0, NULL);
3370 ratecontrol_bailout:
3377 scsiformat(struct cam_device *device, int argc, char **argv,
3378 char *combinedopt, int retry_count, int timeout)
3382 int ycount = 0, quiet = 0;
3383 int error = 0, response = 0, retval = 0;
3384 int use_timeout = 10800 * 1000;
3386 struct format_defect_list_header fh;
3387 u_int8_t *data_ptr = NULL;
3388 u_int32_t dxfer_len = 0;
3390 int num_warnings = 0;
3393 ccb = cam_getccb(device);
3396 warnx("scsiformat: error allocating ccb");
3400 bzero(&(&ccb->ccb_h)[1],
3401 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3403 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3424 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
3425 "following device:\n");
3427 error = scsidoinquiry(device, argc, argv, combinedopt,
3428 retry_count, timeout);
3431 warnx("scsiformat: error sending inquiry");
3432 goto scsiformat_bailout;
3441 fprintf(stdout, "Are you SURE you want to do "
3444 if (fgets(str, sizeof(str), stdin) != NULL) {
3446 if (strncasecmp(str, "yes", 3) == 0)
3448 else if (strncasecmp(str, "no", 2) == 0)
3451 fprintf(stdout, "Please answer"
3452 " \"yes\" or \"no\"\n");
3455 } while (response == 0);
3457 if (response == -1) {
3459 goto scsiformat_bailout;
3464 use_timeout = timeout;
3467 fprintf(stdout, "Current format timeout is %d seconds\n",
3468 use_timeout / 1000);
3472 * If the user hasn't disabled questions and didn't specify a
3473 * timeout on the command line, ask them if they want the current
3477 && (timeout == 0)) {
3479 int new_timeout = 0;
3481 fprintf(stdout, "Enter new timeout in seconds or press\n"
3482 "return to keep the current timeout [%d] ",
3483 use_timeout / 1000);
3485 if (fgets(str, sizeof(str), stdin) != NULL) {
3487 new_timeout = atoi(str);
3490 if (new_timeout != 0) {
3491 use_timeout = new_timeout * 1000;
3492 fprintf(stdout, "Using new timeout value %d\n",
3493 use_timeout / 1000);
3498 * Keep this outside the if block below to silence any unused
3499 * variable warnings.
3501 bzero(&fh, sizeof(fh));
3504 * If we're in immediate mode, we've got to include the format
3507 if (immediate != 0) {
3508 fh.byte2 = FU_DLH_IMMED;
3509 data_ptr = (u_int8_t *)&fh;
3510 dxfer_len = sizeof(fh);
3511 byte2 = FU_FMT_DATA;
3512 } else if (quiet == 0) {
3513 fprintf(stdout, "Formatting...");
3517 scsi_format_unit(&ccb->csio,
3518 /* retries */ retry_count,
3520 /* tag_action */ MSG_SIMPLE_Q_TAG,
3523 /* data_ptr */ data_ptr,
3524 /* dxfer_len */ dxfer_len,
3525 /* sense_len */ SSD_FULL_SIZE,
3526 /* timeout */ use_timeout);
3528 /* Disable freezing the device queue */
3529 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3531 if (arglist & CAM_ARG_ERR_RECOVER)
3532 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3534 if (((retval = cam_send_ccb(device, ccb)) < 0)
3535 || ((immediate == 0)
3536 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
3537 const char errstr[] = "error sending format command";
3544 if (arglist & CAM_ARG_VERBOSE) {
3545 cam_error_print(device, ccb, CAM_ESF_ALL,
3546 CAM_EPF_ALL, stderr);
3549 goto scsiformat_bailout;
3553 * If we ran in non-immediate mode, we already checked for errors
3554 * above and printed out any necessary information. If we're in
3555 * immediate mode, we need to loop through and get status
3556 * information periodically.
3558 if (immediate == 0) {
3560 fprintf(stdout, "Format Complete\n");
3562 goto scsiformat_bailout;
3569 bzero(&(&ccb->ccb_h)[1],
3570 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3573 * There's really no need to do error recovery or
3574 * retries here, since we're just going to sit in a
3575 * loop and wait for the device to finish formatting.
3577 scsi_test_unit_ready(&ccb->csio,
3580 /* tag_action */ MSG_SIMPLE_Q_TAG,
3581 /* sense_len */ SSD_FULL_SIZE,
3582 /* timeout */ 5000);
3584 /* Disable freezing the device queue */
3585 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3587 retval = cam_send_ccb(device, ccb);
3590 * If we get an error from the ioctl, bail out. SCSI
3591 * errors are expected.
3594 warn("error sending CAMIOCOMMAND ioctl");
3595 if (arglist & CAM_ARG_VERBOSE) {
3596 cam_error_print(device, ccb, CAM_ESF_ALL,
3597 CAM_EPF_ALL, stderr);
3600 goto scsiformat_bailout;
3603 status = ccb->ccb_h.status & CAM_STATUS_MASK;
3605 if ((status != CAM_REQ_CMP)
3606 && (status == CAM_SCSI_STATUS_ERROR)
3607 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3608 struct scsi_sense_data *sense;
3609 int error_code, sense_key, asc, ascq;
3611 sense = &ccb->csio.sense_data;
3612 scsi_extract_sense(sense, &error_code, &sense_key,
3616 * According to the SCSI-2 and SCSI-3 specs, a
3617 * drive that is in the middle of a format should
3618 * return NOT READY with an ASC of "logical unit
3619 * not ready, format in progress". The sense key
3620 * specific bytes will then be a progress indicator.
3622 if ((sense_key == SSD_KEY_NOT_READY)
3623 && (asc == 0x04) && (ascq == 0x04)) {
3624 if ((sense->extra_len >= 10)
3625 && ((sense->sense_key_spec[0] &
3626 SSD_SCS_VALID) != 0)
3629 u_int64_t percentage;
3632 &sense->sense_key_spec[1]);
3633 percentage = 10000 * val;
3636 "\rFormatting: %ju.%02u %% "
3638 (uintmax_t)(percentage /
3640 (unsigned)((percentage /
3644 } else if ((quiet == 0)
3645 && (++num_warnings <= 1)) {
3646 warnx("Unexpected SCSI Sense Key "
3647 "Specific value returned "
3649 scsi_sense_print(device, &ccb->csio,
3651 warnx("Unable to print status "
3652 "information, but format will "
3654 warnx("will exit when format is "
3659 warnx("Unexpected SCSI error during format");
3660 cam_error_print(device, ccb, CAM_ESF_ALL,
3661 CAM_EPF_ALL, stderr);
3663 goto scsiformat_bailout;
3666 } else if (status != CAM_REQ_CMP) {
3667 warnx("Unexpected CAM status %#x", status);
3668 if (arglist & CAM_ARG_VERBOSE)
3669 cam_error_print(device, ccb, CAM_ESF_ALL,
3670 CAM_EPF_ALL, stderr);
3672 goto scsiformat_bailout;
3675 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
3678 fprintf(stdout, "\nFormat Complete\n");
3688 scsireportluns(struct cam_device *device, int argc, char **argv,
3689 char *combinedopt, int retry_count, int timeout)
3692 int c, countonly, lunsonly;
3693 struct scsi_report_luns_data *lundata;
3695 uint8_t report_type;
3696 uint32_t list_len, i, j;
3701 report_type = RPL_REPORT_DEFAULT;
3702 ccb = cam_getccb(device);
3705 warnx("%s: error allocating ccb", __func__);
3709 bzero(&(&ccb->ccb_h)[1],
3710 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3715 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3724 if (strcasecmp(optarg, "default") == 0)
3725 report_type = RPL_REPORT_DEFAULT;
3726 else if (strcasecmp(optarg, "wellknown") == 0)
3727 report_type = RPL_REPORT_WELLKNOWN;
3728 else if (strcasecmp(optarg, "all") == 0)
3729 report_type = RPL_REPORT_ALL;
3731 warnx("%s: invalid report type \"%s\"",
3742 if ((countonly != 0)
3743 && (lunsonly != 0)) {
3744 warnx("%s: you can only specify one of -c or -l", __func__);
3749 * According to SPC-4, the allocation length must be at least 16
3750 * bytes -- enough for the header and one LUN.
3752 alloc_len = sizeof(*lundata) + 8;
3756 lundata = malloc(alloc_len);
3758 if (lundata == NULL) {
3759 warn("%s: error mallocing %d bytes", __func__, alloc_len);
3764 scsi_report_luns(&ccb->csio,
3765 /*retries*/ retry_count,
3767 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3768 /*select_report*/ report_type,
3769 /*rpl_buf*/ lundata,
3770 /*alloc_len*/ alloc_len,
3771 /*sense_len*/ SSD_FULL_SIZE,
3772 /*timeout*/ timeout ? timeout : 5000);
3774 /* Disable freezing the device queue */
3775 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3777 if (arglist & CAM_ARG_ERR_RECOVER)
3778 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3780 if (cam_send_ccb(device, ccb) < 0) {
3781 warn("error sending REPORT LUNS command");
3783 if (arglist & CAM_ARG_VERBOSE)
3784 cam_error_print(device, ccb, CAM_ESF_ALL,
3785 CAM_EPF_ALL, stderr);
3791 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3792 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
3798 list_len = scsi_4btoul(lundata->length);
3801 * If we need to list the LUNs, and our allocation
3802 * length was too short, reallocate and retry.
3804 if ((countonly == 0)
3805 && (list_len > (alloc_len - sizeof(*lundata)))) {
3806 alloc_len = list_len + sizeof(*lundata);
3812 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
3813 ((list_len / 8) > 1) ? "s" : "");
3818 for (i = 0; i < (list_len / 8); i++) {
3822 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
3824 fprintf(stdout, ",");
3825 switch (lundata->luns[i].lundata[j] &
3826 RPL_LUNDATA_ATYP_MASK) {
3827 case RPL_LUNDATA_ATYP_PERIPH:
3828 if ((lundata->luns[i].lundata[j] &
3829 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
3830 fprintf(stdout, "%d:",
3831 lundata->luns[i].lundata[j] &
3832 RPL_LUNDATA_PERIPH_BUS_MASK);
3834 && ((lundata->luns[i].lundata[j+2] &
3835 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
3838 fprintf(stdout, "%d",
3839 lundata->luns[i].lundata[j+1]);
3841 case RPL_LUNDATA_ATYP_FLAT: {
3843 tmplun[0] = lundata->luns[i].lundata[j] &
3844 RPL_LUNDATA_FLAT_LUN_MASK;
3845 tmplun[1] = lundata->luns[i].lundata[j+1];
3847 fprintf(stdout, "%d", scsi_2btoul(tmplun));
3851 case RPL_LUNDATA_ATYP_LUN:
3852 fprintf(stdout, "%d:%d:%d",
3853 (lundata->luns[i].lundata[j+1] &
3854 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
3855 lundata->luns[i].lundata[j] &
3856 RPL_LUNDATA_LUN_TARG_MASK,
3857 lundata->luns[i].lundata[j+1] &
3858 RPL_LUNDATA_LUN_LUN_MASK);
3860 case RPL_LUNDATA_ATYP_EXTLUN: {
3861 int field_len, field_len_code, eam_code;
3863 eam_code = lundata->luns[i].lundata[j] &
3864 RPL_LUNDATA_EXT_EAM_MASK;
3865 field_len_code = (lundata->luns[i].lundata[j] &
3866 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
3867 field_len = field_len_code * 2;
3869 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
3870 && (field_len_code == 0x00)) {
3871 fprintf(stdout, "%d",
3872 lundata->luns[i].lundata[j+1]);
3873 } else if ((eam_code ==
3874 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
3875 && (field_len_code == 0x03)) {
3879 * This format takes up all 8 bytes.
3880 * If we aren't starting at offset 0,
3884 fprintf(stdout, "Invalid "
3887 "specified format", j);
3891 bzero(tmp_lun, sizeof(tmp_lun));
3892 bcopy(&lundata->luns[i].lundata[j+1],
3893 &tmp_lun[1], sizeof(tmp_lun) - 1);
3894 fprintf(stdout, "%#jx",
3895 (intmax_t)scsi_8btou64(tmp_lun));
3898 fprintf(stderr, "Unknown Extended LUN"
3899 "Address method %#x, length "
3900 "code %#x", eam_code,
3907 fprintf(stderr, "Unknown LUN address method "
3908 "%#x\n", lundata->luns[i].lundata[0] &
3909 RPL_LUNDATA_ATYP_MASK);
3913 * For the flat addressing method, there are no
3914 * other levels after it.
3919 fprintf(stdout, "\n");
3932 scsireadcapacity(struct cam_device *device, int argc, char **argv,
3933 char *combinedopt, int retry_count, int timeout)
3936 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
3937 struct scsi_read_capacity_data rcap;
3938 struct scsi_read_capacity_data_long rcaplong;
3952 ccb = cam_getccb(device);
3955 warnx("%s: error allocating ccb", __func__);
3959 bzero(&(&ccb->ccb_h)[1],
3960 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3962 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3989 if ((blocksizeonly != 0)
3990 && (numblocks != 0)) {
3991 warnx("%s: you can only specify one of -b or -N", __func__);
3996 if ((blocksizeonly != 0)
3997 && (sizeonly != 0)) {
3998 warnx("%s: you can only specify one of -b or -s", __func__);
4005 warnx("%s: you can only specify one of -h/-H or -q", __func__);
4011 && (blocksizeonly != 0)) {
4012 warnx("%s: you can only specify one of -h/-H or -b", __func__);
4017 scsi_read_capacity(&ccb->csio,
4018 /*retries*/ retry_count,
4020 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4023 /*timeout*/ timeout ? timeout : 5000);
4025 /* Disable freezing the device queue */
4026 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4028 if (arglist & CAM_ARG_ERR_RECOVER)
4029 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4031 if (cam_send_ccb(device, ccb) < 0) {
4032 warn("error sending READ CAPACITY command");
4034 if (arglist & CAM_ARG_VERBOSE)
4035 cam_error_print(device, ccb, CAM_ESF_ALL,
4036 CAM_EPF_ALL, stderr);
4042 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4043 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4048 maxsector = scsi_4btoul(rcap.addr);
4049 block_len = scsi_4btoul(rcap.length);
4052 * A last block of 2^32-1 means that the true capacity is over 2TB,
4053 * and we need to issue the long READ CAPACITY to get the real
4054 * capacity. Otherwise, we're all set.
4056 if (maxsector != 0xffffffff)
4059 scsi_read_capacity_16(&ccb->csio,
4060 /*retries*/ retry_count,
4062 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4067 /*sense_len*/ SSD_FULL_SIZE,
4068 /*timeout*/ timeout ? timeout : 5000);
4070 /* Disable freezing the device queue */
4071 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4073 if (arglist & CAM_ARG_ERR_RECOVER)
4074 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4076 if (cam_send_ccb(device, ccb) < 0) {
4077 warn("error sending READ CAPACITY (16) command");
4079 if (arglist & CAM_ARG_VERBOSE)
4080 cam_error_print(device, ccb, CAM_ESF_ALL,
4081 CAM_EPF_ALL, stderr);
4087 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4088 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4093 maxsector = scsi_8btou64(rcaplong.addr);
4094 block_len = scsi_4btoul(rcaplong.length);
4097 if (blocksizeonly == 0) {
4099 * Humanize implies !quiet, and also implies numblocks.
4101 if (humanize != 0) {
4106 tmpbytes = (maxsector + 1) * block_len;
4107 ret = humanize_number(tmpstr, sizeof(tmpstr),
4108 tmpbytes, "", HN_AUTOSCALE,
4111 HN_DIVISOR_1000 : 0));
4113 warnx("%s: humanize_number failed!", __func__);
4117 fprintf(stdout, "Device Size: %s%s", tmpstr,
4118 (sizeonly == 0) ? ", " : "\n");
4119 } else if (numblocks != 0) {
4120 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
4121 "Blocks: " : "", (uintmax_t)maxsector + 1,
4122 (sizeonly == 0) ? ", " : "\n");
4124 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
4125 "Last Block: " : "", (uintmax_t)maxsector,
4126 (sizeonly == 0) ? ", " : "\n");
4130 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
4131 "Block Length: " : "", block_len, (quiet == 0) ?
4140 atapm(struct cam_device *device, int argc, char **argv,
4141 char *combinedopt, int retry_count, int timeout)
4149 ccb = cam_getccb(device);
4152 warnx("%s: error allocating ccb", __func__);
4156 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4165 if (strcmp(argv[1], "idle") == 0) {
4167 cmd = ATA_IDLE_IMMEDIATE;
4170 } else if (strcmp(argv[1], "standby") == 0) {
4172 cmd = ATA_STANDBY_IMMEDIATE;
4174 cmd = ATA_STANDBY_CMD;
4181 else if (t <= (240 * 5))
4183 else if (t <= (11 * 30 * 60))
4184 sc = t / (30 * 60) + 241;
4187 cam_fill_ataio(&ccb->ataio,
4190 /*flags*/CAM_DIR_NONE,
4194 timeout ? timeout : 30 * 1000);
4195 ata_28bit_cmd(&ccb->ataio, cmd, 0, 0, sc);
4197 /* Disable freezing the device queue */
4198 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4200 if (arglist & CAM_ARG_ERR_RECOVER)
4201 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4203 if (cam_send_ccb(device, ccb) < 0) {
4204 warn("error sending command");
4206 if (arglist & CAM_ARG_VERBOSE)
4207 cam_error_print(device, ccb, CAM_ESF_ALL,
4208 CAM_EPF_ALL, stderr);
4214 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4215 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4224 #endif /* MINIMALISTIC */
4229 fprintf(verbose ? stdout : stderr,
4230 "usage: camcontrol <command> [device id][generic args][command args]\n"
4231 " camcontrol devlist [-v]\n"
4232 #ifndef MINIMALISTIC
4233 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
4234 " camcontrol tur [dev_id][generic args]\n"
4235 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
4236 " camcontrol identify [dev_id][generic args]\n"
4237 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
4238 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
4240 " camcontrol start [dev_id][generic args]\n"
4241 " camcontrol stop [dev_id][generic args]\n"
4242 " camcontrol load [dev_id][generic args]\n"
4243 " camcontrol eject [dev_id][generic args]\n"
4244 #endif /* MINIMALISTIC */
4245 " camcontrol rescan <all | bus[:target:lun]>\n"
4246 " camcontrol reset <all | bus[:target:lun]>\n"
4247 #ifndef MINIMALISTIC
4248 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
4249 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
4250 " [-P pagectl][-e | -b][-d]\n"
4251 " camcontrol cmd [dev_id][generic args]\n"
4252 " <-a cmd [args] | -c cmd [args]>\n"
4253 " [-i len fmt|-o len fmt [args]] [-r fmt]\n"
4254 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
4255 " <all|bus[:target[:lun]]|off>\n"
4256 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
4257 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
4258 " [-D <enable|disable>][-O offset][-q]\n"
4259 " [-R syncrate][-v][-T <enable|disable>]\n"
4260 " [-U][-W bus_width]\n"
4261 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
4262 " camcontrol idle [dev_id][generic args][-t time]\n"
4263 " camcontrol standby [dev_id][generic args][-t time]\n"
4264 " camcontrol sleep [dev_id][generic args]\n"
4265 #endif /* MINIMALISTIC */
4266 " camcontrol help\n");
4269 #ifndef MINIMALISTIC
4271 "Specify one of the following options:\n"
4272 "devlist list all CAM devices\n"
4273 "periphlist list all CAM peripheral drivers attached to a device\n"
4274 "tur send a test unit ready to the named device\n"
4275 "inquiry send a SCSI inquiry command to the named device\n"
4276 "identify send a ATA identify command to the named device\n"
4277 "reportluns send a SCSI report luns command to the device\n"
4278 "readcap send a SCSI read capacity command to the device\n"
4279 "start send a Start Unit command to the device\n"
4280 "stop send a Stop Unit command to the device\n"
4281 "load send a Start Unit command to the device with the load bit set\n"
4282 "eject send a Stop Unit command to the device with the eject bit set\n"
4283 "rescan rescan all busses, the given bus, or bus:target:lun\n"
4284 "reset reset all busses, the given bus, or bus:target:lun\n"
4285 "defects read the defect list of the specified device\n"
4286 "modepage display or edit (-e) the given mode page\n"
4287 "cmd send the given scsi command, may need -i or -o as well\n"
4288 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
4289 "tags report or set the number of transaction slots for a device\n"
4290 "negotiate report or set device negotiation parameters\n"
4291 "format send the SCSI FORMAT UNIT command to the named device\n"
4292 "idle send the ATA IDLE command to the named device\n"
4293 "standby send the ATA STANDBY command to the named device\n"
4294 "sleep send the ATA SLEEP command to the named device\n"
4295 "help this message\n"
4296 "Device Identifiers:\n"
4297 "bus:target specify the bus and target, lun defaults to 0\n"
4298 "bus:target:lun specify the bus, target and lun\n"
4299 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
4300 "Generic arguments:\n"
4301 "-v be verbose, print out sense information\n"
4302 "-t timeout command timeout in seconds, overrides default timeout\n"
4303 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
4304 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
4305 "-E have the kernel attempt to perform SCSI error recovery\n"
4306 "-C count specify the SCSI command retry count (needs -E to work)\n"
4307 "modepage arguments:\n"
4308 "-l list all available mode pages\n"
4309 "-m page specify the mode page to view or edit\n"
4310 "-e edit the specified mode page\n"
4311 "-b force view to binary mode\n"
4312 "-d disable block descriptors for mode sense\n"
4313 "-P pgctl page control field 0-3\n"
4314 "defects arguments:\n"
4315 "-f format specify defect list format (block, bfi or phys)\n"
4316 "-G get the grown defect list\n"
4317 "-P get the permanant defect list\n"
4318 "inquiry arguments:\n"
4319 "-D get the standard inquiry data\n"
4320 "-S get the serial number\n"
4321 "-R get the transfer rate, etc.\n"
4322 "reportluns arguments:\n"
4323 "-c only report a count of available LUNs\n"
4324 "-l only print out luns, and not a count\n"
4325 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
4326 "readcap arguments\n"
4327 "-b only report the blocksize\n"
4328 "-h human readable device size, base 2\n"
4329 "-H human readable device size, base 10\n"
4330 "-N print the number of blocks instead of last block\n"
4331 "-q quiet, print numbers only\n"
4332 "-s only report the last block/device size\n"
4334 "-c cdb [args] specify the SCSI CDB\n"
4335 "-i len fmt specify input data and input data format\n"
4336 "-o len fmt [args] specify output data and output data fmt\n"
4337 "debug arguments:\n"
4338 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
4339 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
4340 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
4341 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
4343 "-N tags specify the number of tags to use for this device\n"
4344 "-q be quiet, don't report the number of tags\n"
4345 "-v report a number of tag-related parameters\n"
4346 "negotiate arguments:\n"
4347 "-a send a test unit ready after negotiation\n"
4348 "-c report/set current negotiation settings\n"
4349 "-D <arg> \"enable\" or \"disable\" disconnection\n"
4350 "-O offset set command delay offset\n"
4351 "-q be quiet, don't report anything\n"
4352 "-R syncrate synchronization rate in MHz\n"
4353 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
4354 "-U report/set user negotiation settings\n"
4355 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
4356 "-v also print a Path Inquiry CCB for the controller\n"
4357 "format arguments:\n"
4358 "-q be quiet, don't print status messages\n"
4359 "-r run in report only mode\n"
4360 "-w don't send immediate format command\n"
4361 "-y don't ask any questions\n"
4362 "idle/standby arguments:\n"
4363 "-t <arg> number of seconds before respective state.\n");
4364 #endif /* MINIMALISTIC */
4368 main(int argc, char **argv)
4371 char *device = NULL;
4373 struct cam_device *cam_dev = NULL;
4374 int timeout = 0, retry_count = 1;
4375 camcontrol_optret optreturn;
4377 const char *mainopt = "C:En:t:u:v";
4378 const char *subopt = NULL;
4379 char combinedopt[256];
4380 int error = 0, optstart = 2;
4382 #ifndef MINIMALISTIC
4383 int bus, target, lun;
4384 #endif /* MINIMALISTIC */
4386 cmdlist = CAM_CMD_NONE;
4387 arglist = CAM_ARG_NONE;
4395 * Get the base option.
4397 optreturn = getoption(argv[1], &cmdlist, &arglist, &subopt);
4399 if (optreturn == CC_OR_AMBIGUOUS) {
4400 warnx("ambiguous option %s", argv[1]);
4403 } else if (optreturn == CC_OR_NOT_FOUND) {
4404 warnx("option %s not found", argv[1]);
4410 * Ahh, getopt(3) is a pain.
4412 * This is a gross hack. There really aren't many other good
4413 * options (excuse the pun) for parsing options in a situation like
4414 * this. getopt is kinda braindead, so you end up having to run
4415 * through the options twice, and give each invocation of getopt
4416 * the option string for the other invocation.
4418 * You would think that you could just have two groups of options.
4419 * The first group would get parsed by the first invocation of
4420 * getopt, and the second group would get parsed by the second
4421 * invocation of getopt. It doesn't quite work out that way. When
4422 * the first invocation of getopt finishes, it leaves optind pointing
4423 * to the argument _after_ the first argument in the second group.
4424 * So when the second invocation of getopt comes around, it doesn't
4425 * recognize the first argument it gets and then bails out.
4427 * A nice alternative would be to have a flag for getopt that says
4428 * "just keep parsing arguments even when you encounter an unknown
4429 * argument", but there isn't one. So there's no real clean way to
4430 * easily parse two sets of arguments without having one invocation
4431 * of getopt know about the other.
4433 * Without this hack, the first invocation of getopt would work as
4434 * long as the generic arguments are first, but the second invocation
4435 * (in the subfunction) would fail in one of two ways. In the case
4436 * where you don't set optreset, it would fail because optind may be
4437 * pointing to the argument after the one it should be pointing at.
4438 * In the case where you do set optreset, and reset optind, it would
4439 * fail because getopt would run into the first set of options, which
4440 * it doesn't understand.
4442 * All of this would "sort of" work if you could somehow figure out
4443 * whether optind had been incremented one option too far. The
4444 * mechanics of that, however, are more daunting than just giving
4445 * both invocations all of the expect options for either invocation.
4447 * Needless to say, I wouldn't mind if someone invented a better
4448 * (non-GPL!) command line parsing interface than getopt. I
4449 * wouldn't mind if someone added more knobs to getopt to make it
4450 * work better. Who knows, I may talk myself into doing it someday,
4451 * if the standards weenies let me. As it is, it just leads to
4452 * hackery like this and causes people to avoid it in some cases.
4454 * KDM, September 8th, 1998
4457 sprintf(combinedopt, "%s%s", mainopt, subopt);
4459 sprintf(combinedopt, "%s", mainopt);
4462 * For these options we do not parse optional device arguments and
4463 * we do not open a passthrough device.
4465 if ((cmdlist == CAM_CMD_RESCAN)
4466 || (cmdlist == CAM_CMD_RESET)
4467 || (cmdlist == CAM_CMD_DEVTREE)
4468 || (cmdlist == CAM_CMD_USAGE)
4469 || (cmdlist == CAM_CMD_DEBUG))
4472 #ifndef MINIMALISTIC
4474 && (argc > 2 && argv[2][0] != '-')) {
4479 * First catch people who try to do things like:
4480 * camcontrol tur /dev/da0
4481 * camcontrol doesn't take device nodes as arguments.
4483 if (argv[2][0] == '/') {
4484 warnx("%s is not a valid device identifier", argv[2]);
4485 errx(1, "please read the camcontrol(8) man page");
4486 } else if (isdigit(argv[2][0])) {
4487 /* device specified as bus:target[:lun] */
4488 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
4490 errx(1, "numeric device specification must "
4491 "be either bus:target, or "
4493 /* default to 0 if lun was not specified */
4494 if ((arglist & CAM_ARG_LUN) == 0) {
4496 arglist |= CAM_ARG_LUN;
4500 if (cam_get_device(argv[2], name, sizeof name, &unit)
4502 errx(1, "%s", cam_errbuf);
4503 device = strdup(name);
4504 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
4508 #endif /* MINIMALISTIC */
4510 * Start getopt processing at argv[2/3], since we've already
4511 * accepted argv[1..2] as the command name, and as a possible
4517 * Now we run through the argument list looking for generic
4518 * options, and ignoring options that possibly belong to
4521 while ((c = getopt(argc, argv, combinedopt))!= -1){
4524 retry_count = strtol(optarg, NULL, 0);
4525 if (retry_count < 0)
4526 errx(1, "retry count %d is < 0",
4528 arglist |= CAM_ARG_RETRIES;
4531 arglist |= CAM_ARG_ERR_RECOVER;
4534 arglist |= CAM_ARG_DEVICE;
4536 while (isspace(*tstr) && (*tstr != '\0'))
4538 device = (char *)strdup(tstr);
4541 timeout = strtol(optarg, NULL, 0);
4543 errx(1, "invalid timeout %d", timeout);
4544 /* Convert the timeout from seconds to ms */
4546 arglist |= CAM_ARG_TIMEOUT;
4549 arglist |= CAM_ARG_UNIT;
4550 unit = strtol(optarg, NULL, 0);
4553 arglist |= CAM_ARG_VERBOSE;
4560 #ifndef MINIMALISTIC
4562 * For most commands we'll want to open the passthrough device
4563 * associated with the specified device. In the case of the rescan
4564 * commands, we don't use a passthrough device at all, just the
4565 * transport layer device.
4568 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
4569 && (((arglist & CAM_ARG_DEVICE) == 0)
4570 || ((arglist & CAM_ARG_UNIT) == 0))) {
4571 errx(1, "subcommand \"%s\" requires a valid device "
4572 "identifier", argv[1]);
4575 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
4576 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
4577 cam_open_spec_device(device,unit,O_RDWR,NULL)))
4579 errx(1,"%s", cam_errbuf);
4581 #endif /* MINIMALISTIC */
4584 * Reset optind to 2, and reset getopt, so these routines can parse
4585 * the arguments again.
4591 #ifndef MINIMALISTIC
4592 case CAM_CMD_DEVLIST:
4593 error = getdevlist(cam_dev);
4595 #endif /* MINIMALISTIC */
4596 case CAM_CMD_DEVTREE:
4597 error = getdevtree();
4599 #ifndef MINIMALISTIC
4601 error = testunitready(cam_dev, retry_count, timeout, 0);
4603 case CAM_CMD_INQUIRY:
4604 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
4605 retry_count, timeout);
4607 case CAM_CMD_IDENTIFY:
4608 error = ataidentify(cam_dev, retry_count, timeout);
4610 case CAM_CMD_STARTSTOP:
4611 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
4612 arglist & CAM_ARG_EJECT, retry_count,
4615 #endif /* MINIMALISTIC */
4616 case CAM_CMD_RESCAN:
4617 error = dorescan_or_reset(argc, argv, 1);
4620 error = dorescan_or_reset(argc, argv, 0);
4622 #ifndef MINIMALISTIC
4623 case CAM_CMD_READ_DEFECTS:
4624 error = readdefects(cam_dev, argc, argv, combinedopt,
4625 retry_count, timeout);
4627 case CAM_CMD_MODE_PAGE:
4628 modepage(cam_dev, argc, argv, combinedopt,
4629 retry_count, timeout);
4631 case CAM_CMD_SCSI_CMD:
4632 error = scsicmd(cam_dev, argc, argv, combinedopt,
4633 retry_count, timeout);
4636 error = camdebug(argc, argv, combinedopt);
4639 error = tagcontrol(cam_dev, argc, argv, combinedopt);
4642 error = ratecontrol(cam_dev, retry_count, timeout,
4643 argc, argv, combinedopt);
4645 case CAM_CMD_FORMAT:
4646 error = scsiformat(cam_dev, argc, argv,
4647 combinedopt, retry_count, timeout);
4649 case CAM_CMD_REPORTLUNS:
4650 error = scsireportluns(cam_dev, argc, argv,
4651 combinedopt, retry_count,
4654 case CAM_CMD_READCAP:
4655 error = scsireadcapacity(cam_dev, argc, argv,
4656 combinedopt, retry_count,
4660 case CAM_CMD_STANDBY:
4662 error = atapm(cam_dev, argc, argv,
4663 combinedopt, retry_count,
4666 #endif /* MINIMALISTIC */
4676 if (cam_dev != NULL)
4677 cam_close_device(cam_dev);