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,
81 CAM_CMD_SECURITY = 0x00000017
85 CAM_ARG_NONE = 0x00000000,
86 CAM_ARG_VERBOSE = 0x00000001,
87 CAM_ARG_DEVICE = 0x00000002,
88 CAM_ARG_BUS = 0x00000004,
89 CAM_ARG_TARGET = 0x00000008,
90 CAM_ARG_LUN = 0x00000010,
91 CAM_ARG_EJECT = 0x00000020,
92 CAM_ARG_UNIT = 0x00000040,
93 CAM_ARG_FORMAT_BLOCK = 0x00000080,
94 CAM_ARG_FORMAT_BFI = 0x00000100,
95 CAM_ARG_FORMAT_PHYS = 0x00000200,
96 CAM_ARG_PLIST = 0x00000400,
97 CAM_ARG_GLIST = 0x00000800,
98 CAM_ARG_GET_SERIAL = 0x00001000,
99 CAM_ARG_GET_STDINQ = 0x00002000,
100 CAM_ARG_GET_XFERRATE = 0x00004000,
101 CAM_ARG_INQ_MASK = 0x00007000,
102 CAM_ARG_MODE_EDIT = 0x00008000,
103 CAM_ARG_PAGE_CNTL = 0x00010000,
104 CAM_ARG_TIMEOUT = 0x00020000,
105 CAM_ARG_CMD_IN = 0x00040000,
106 CAM_ARG_CMD_OUT = 0x00080000,
107 CAM_ARG_DBD = 0x00100000,
108 CAM_ARG_ERR_RECOVER = 0x00200000,
109 CAM_ARG_RETRIES = 0x00400000,
110 CAM_ARG_START_UNIT = 0x00800000,
111 CAM_ARG_DEBUG_INFO = 0x01000000,
112 CAM_ARG_DEBUG_TRACE = 0x02000000,
113 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
114 CAM_ARG_DEBUG_CDB = 0x08000000,
115 CAM_ARG_DEBUG_XPT = 0x10000000,
116 CAM_ARG_DEBUG_PERIPH = 0x20000000,
117 CAM_ARG_DEBUG_PROBE = 0x40000000,
120 struct camcontrol_opts {
128 static const char scsicmd_opts[] = "a:c:dfi:o:r";
129 static const char readdefect_opts[] = "f:GP";
130 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
134 struct camcontrol_opts option_table[] = {
136 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
137 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
138 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
139 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
140 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
141 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
142 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
143 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
144 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
145 #endif /* MINIMALISTIC */
146 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
147 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
149 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
150 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
151 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
152 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
153 #endif /* MINIMALISTIC */
154 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, NULL},
156 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
157 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
158 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
159 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
160 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
161 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
162 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
163 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
164 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
165 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
166 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
167 #endif /* MINIMALISTIC */
168 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
169 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
170 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
184 camcontrol_optret getoption(char *arg, cam_cmdmask *cmdnum, cam_argmask *argnum,
185 const char **subopt);
187 static int getdevlist(struct cam_device *device);
188 #endif /* MINIMALISTIC */
189 static int getdevtree(void);
191 static int testunitready(struct cam_device *device, int retry_count,
192 int timeout, int quiet);
193 static int scsistart(struct cam_device *device, int startstop, int loadeject,
194 int retry_count, int timeout);
195 static int scsidoinquiry(struct cam_device *device, int argc, char **argv,
196 char *combinedopt, int retry_count, int timeout);
197 static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
198 static int scsiserial(struct cam_device *device, int retry_count, int timeout);
199 static int camxferrate(struct cam_device *device);
200 #endif /* MINIMALISTIC */
201 static int parse_btl(char *tstr, int *bus, int *target, int *lun,
202 cam_argmask *arglst);
203 static int dorescan_or_reset(int argc, char **argv, int rescan);
204 static int rescan_or_reset_bus(int bus, int rescan);
205 static int scanlun_or_reset_dev(int bus, int target, int lun, int scan);
207 static int readdefects(struct cam_device *device, int argc, char **argv,
208 char *combinedopt, int retry_count, int timeout);
209 static void modepage(struct cam_device *device, int argc, char **argv,
210 char *combinedopt, int retry_count, int timeout);
211 static int scsicmd(struct cam_device *device, int argc, char **argv,
212 char *combinedopt, int retry_count, int timeout);
213 static int tagcontrol(struct cam_device *device, int argc, char **argv,
215 static void cts_print(struct cam_device *device,
216 struct ccb_trans_settings *cts);
217 static void cpi_print(struct ccb_pathinq *cpi);
218 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
219 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
220 static int get_print_cts(struct cam_device *device, int user_settings,
221 int quiet, struct ccb_trans_settings *cts);
222 static int ratecontrol(struct cam_device *device, int retry_count,
223 int timeout, int argc, char **argv, char *combinedopt);
224 static int scsiformat(struct cam_device *device, int argc, char **argv,
225 char *combinedopt, int retry_count, int timeout);
226 static int scsireportluns(struct cam_device *device, int argc, char **argv,
227 char *combinedopt, int retry_count, int timeout);
228 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
229 char *combinedopt, int retry_count, int timeout);
230 static int atapm(struct cam_device *device, int argc, char **argv,
231 char *combinedopt, int retry_count, int timeout);
232 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
233 int argc, char **argv, char *combinedopt);
235 #endif /* MINIMALISTIC */
237 #define min(a,b) (((a)<(b))?(a):(b))
240 #define max(a,b) (((a)>(b))?(a):(b))
244 getoption(char *arg, cam_cmdmask *cmdnum, cam_argmask *argnum,
247 struct camcontrol_opts *opts;
250 for (opts = option_table; (opts != NULL) && (opts->optname != NULL);
252 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
253 *cmdnum = opts->cmdnum;
254 *argnum = opts->argnum;
255 *subopt = opts->subopt;
256 if (++num_matches > 1)
257 return(CC_OR_AMBIGUOUS);
264 return(CC_OR_NOT_FOUND);
269 getdevlist(struct cam_device *device)
275 ccb = cam_getccb(device);
277 ccb->ccb_h.func_code = XPT_GDEVLIST;
278 ccb->ccb_h.flags = CAM_DIR_NONE;
279 ccb->ccb_h.retry_count = 1;
281 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
282 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
283 if (cam_send_ccb(device, ccb) < 0) {
284 perror("error getting device list");
291 switch (ccb->cgdl.status) {
292 case CAM_GDEVLIST_MORE_DEVS:
293 strcpy(status, "MORE");
295 case CAM_GDEVLIST_LAST_DEVICE:
296 strcpy(status, "LAST");
298 case CAM_GDEVLIST_LIST_CHANGED:
299 strcpy(status, "CHANGED");
301 case CAM_GDEVLIST_ERROR:
302 strcpy(status, "ERROR");
307 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
308 ccb->cgdl.periph_name,
309 ccb->cgdl.unit_number,
310 ccb->cgdl.generation,
315 * If the list has changed, we need to start over from the
318 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
326 #endif /* MINIMALISTIC */
338 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
339 warn("couldn't open %s", XPT_DEVICE);
343 bzero(&ccb, sizeof(union ccb));
345 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
346 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
347 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
349 ccb.ccb_h.func_code = XPT_DEV_MATCH;
350 bufsize = sizeof(struct dev_match_result) * 100;
351 ccb.cdm.match_buf_len = bufsize;
352 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
353 if (ccb.cdm.matches == NULL) {
354 warnx("can't malloc memory for matches");
358 ccb.cdm.num_matches = 0;
361 * We fetch all nodes, since we display most of them in the default
362 * case, and all in the verbose case.
364 ccb.cdm.num_patterns = 0;
365 ccb.cdm.pattern_buf_len = 0;
368 * We do the ioctl multiple times if necessary, in case there are
369 * more than 100 nodes in the EDT.
372 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
373 warn("error sending CAMIOCOMMAND ioctl");
378 if ((ccb.ccb_h.status != CAM_REQ_CMP)
379 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
380 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
381 warnx("got CAM error %#x, CDM error %d\n",
382 ccb.ccb_h.status, ccb.cdm.status);
387 for (i = 0; i < ccb.cdm.num_matches; i++) {
388 switch (ccb.cdm.matches[i].type) {
389 case DEV_MATCH_BUS: {
390 struct bus_match_result *bus_result;
393 * Only print the bus information if the
394 * user turns on the verbose flag.
396 if ((arglist & CAM_ARG_VERBOSE) == 0)
400 &ccb.cdm.matches[i].result.bus_result;
403 fprintf(stdout, ")\n");
407 fprintf(stdout, "scbus%d on %s%d bus %d:\n",
409 bus_result->dev_name,
410 bus_result->unit_number,
414 case DEV_MATCH_DEVICE: {
415 struct device_match_result *dev_result;
416 char vendor[16], product[48], revision[16];
420 &ccb.cdm.matches[i].result.device_result;
422 if ((dev_result->flags
423 & DEV_RESULT_UNCONFIGURED)
424 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
430 if (dev_result->protocol == PROTO_SCSI) {
431 cam_strvis(vendor, dev_result->inq_data.vendor,
432 sizeof(dev_result->inq_data.vendor),
435 dev_result->inq_data.product,
436 sizeof(dev_result->inq_data.product),
439 dev_result->inq_data.revision,
440 sizeof(dev_result->inq_data.revision),
442 sprintf(tmpstr, "<%s %s %s>", vendor, product,
444 } else if (dev_result->protocol == PROTO_ATA ||
445 dev_result->protocol == PROTO_SATAPM) {
447 dev_result->ident_data.model,
448 sizeof(dev_result->ident_data.model),
451 dev_result->ident_data.revision,
452 sizeof(dev_result->ident_data.revision),
454 sprintf(tmpstr, "<%s %s>", product,
457 sprintf(tmpstr, "<>");
460 fprintf(stdout, ")\n");
464 fprintf(stdout, "%-33s at scbus%d "
465 "target %d lun %d (",
468 dev_result->target_id,
469 dev_result->target_lun);
475 case DEV_MATCH_PERIPH: {
476 struct periph_match_result *periph_result;
479 &ccb.cdm.matches[i].result.periph_result;
481 if (skip_device != 0)
485 fprintf(stdout, ",");
487 fprintf(stdout, "%s%d",
488 periph_result->periph_name,
489 periph_result->unit_number);
495 fprintf(stdout, "unknown match type\n");
500 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
501 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
504 fprintf(stdout, ")\n");
513 testunitready(struct cam_device *device, int retry_count, int timeout,
519 ccb = cam_getccb(device);
521 scsi_test_unit_ready(&ccb->csio,
522 /* retries */ retry_count,
524 /* tag_action */ MSG_SIMPLE_Q_TAG,
525 /* sense_len */ SSD_FULL_SIZE,
526 /* timeout */ timeout ? timeout : 5000);
528 /* Disable freezing the device queue */
529 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
531 if (arglist & CAM_ARG_ERR_RECOVER)
532 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
534 if (cam_send_ccb(device, ccb) < 0) {
536 perror("error sending test unit ready");
538 if (arglist & CAM_ARG_VERBOSE) {
539 cam_error_print(device, ccb, CAM_ESF_ALL,
540 CAM_EPF_ALL, stderr);
547 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
549 fprintf(stdout, "Unit is ready\n");
552 fprintf(stdout, "Unit is not ready\n");
555 if (arglist & CAM_ARG_VERBOSE) {
556 cam_error_print(device, ccb, CAM_ESF_ALL,
557 CAM_EPF_ALL, stderr);
567 scsistart(struct cam_device *device, int startstop, int loadeject,
568 int retry_count, int timeout)
573 ccb = cam_getccb(device);
576 * If we're stopping, send an ordered tag so the drive in question
577 * will finish any previously queued writes before stopping. If
578 * the device isn't capable of tagged queueing, or if tagged
579 * queueing is turned off, the tag action is a no-op.
581 scsi_start_stop(&ccb->csio,
582 /* retries */ retry_count,
584 /* tag_action */ startstop ? MSG_SIMPLE_Q_TAG :
586 /* start/stop */ startstop,
587 /* load_eject */ loadeject,
589 /* sense_len */ SSD_FULL_SIZE,
590 /* timeout */ timeout ? timeout : 120000);
592 /* Disable freezing the device queue */
593 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
595 if (arglist & CAM_ARG_ERR_RECOVER)
596 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
598 if (cam_send_ccb(device, ccb) < 0) {
599 perror("error sending start unit");
601 if (arglist & CAM_ARG_VERBOSE) {
602 cam_error_print(device, ccb, CAM_ESF_ALL,
603 CAM_EPF_ALL, stderr);
610 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
612 fprintf(stdout, "Unit started successfully");
614 fprintf(stdout,", Media loaded\n");
616 fprintf(stdout,"\n");
618 fprintf(stdout, "Unit stopped successfully");
620 fprintf(stdout, ", Media ejected\n");
622 fprintf(stdout, "\n");
628 "Error received from start unit command\n");
631 "Error received from stop unit command\n");
633 if (arglist & CAM_ARG_VERBOSE) {
634 cam_error_print(device, ccb, CAM_ESF_ALL,
635 CAM_EPF_ALL, stderr);
645 scsidoinquiry(struct cam_device *device, int argc, char **argv,
646 char *combinedopt, int retry_count, int timeout)
651 while ((c = getopt(argc, argv, combinedopt)) != -1) {
654 arglist |= CAM_ARG_GET_STDINQ;
657 arglist |= CAM_ARG_GET_XFERRATE;
660 arglist |= CAM_ARG_GET_SERIAL;
668 * If the user didn't specify any inquiry options, he wants all of
671 if ((arglist & CAM_ARG_INQ_MASK) == 0)
672 arglist |= CAM_ARG_INQ_MASK;
674 if (arglist & CAM_ARG_GET_STDINQ)
675 error = scsiinquiry(device, retry_count, timeout);
680 if (arglist & CAM_ARG_GET_SERIAL)
681 scsiserial(device, retry_count, timeout);
686 if (arglist & CAM_ARG_GET_XFERRATE)
687 error = camxferrate(device);
693 scsiinquiry(struct cam_device *device, int retry_count, int timeout)
696 struct scsi_inquiry_data *inq_buf;
699 ccb = cam_getccb(device);
702 warnx("couldn't allocate CCB");
706 /* cam_getccb cleans up the header, caller has to zero the payload */
707 bzero(&(&ccb->ccb_h)[1],
708 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
710 inq_buf = (struct scsi_inquiry_data *)malloc(
711 sizeof(struct scsi_inquiry_data));
713 if (inq_buf == NULL) {
715 warnx("can't malloc memory for inquiry\n");
718 bzero(inq_buf, sizeof(*inq_buf));
721 * Note that although the size of the inquiry buffer is the full
722 * 256 bytes specified in the SCSI spec, we only tell the device
723 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
724 * two reasons for this:
726 * - The SCSI spec says that when a length field is only 1 byte,
727 * a value of 0 will be interpreted as 256. Therefore
728 * scsi_inquiry() will convert an inq_len (which is passed in as
729 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
730 * to 0. Evidently, very few devices meet the spec in that
731 * regard. Some devices, like many Seagate disks, take the 0 as
732 * 0, and don't return any data. One Pioneer DVD-R drive
733 * returns more data than the command asked for.
735 * So, since there are numerous devices that just don't work
736 * right with the full inquiry size, we don't send the full size.
738 * - The second reason not to use the full inquiry data length is
739 * that we don't need it here. The only reason we issue a
740 * standard inquiry is to get the vendor name, device name,
741 * and revision so scsi_print_inquiry() can print them.
743 * If, at some point in the future, more inquiry data is needed for
744 * some reason, this code should use a procedure similar to the
745 * probe code. i.e., issue a short inquiry, and determine from
746 * the additional length passed back from the device how much
747 * inquiry data the device supports. Once the amount the device
748 * supports is determined, issue an inquiry for that amount and no
753 scsi_inquiry(&ccb->csio,
754 /* retries */ retry_count,
756 /* tag_action */ MSG_SIMPLE_Q_TAG,
757 /* inq_buf */ (u_int8_t *)inq_buf,
758 /* inq_len */ SHORT_INQUIRY_LENGTH,
761 /* sense_len */ SSD_FULL_SIZE,
762 /* timeout */ timeout ? timeout : 5000);
764 /* Disable freezing the device queue */
765 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
767 if (arglist & CAM_ARG_ERR_RECOVER)
768 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
770 if (cam_send_ccb(device, ccb) < 0) {
771 perror("error sending SCSI inquiry");
773 if (arglist & CAM_ARG_VERBOSE) {
774 cam_error_print(device, ccb, CAM_ESF_ALL,
775 CAM_EPF_ALL, stderr);
782 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
785 if (arglist & CAM_ARG_VERBOSE) {
786 cam_error_print(device, ccb, CAM_ESF_ALL,
787 CAM_EPF_ALL, stderr);
798 fprintf(stdout, "%s%d: ", device->device_name,
799 device->dev_unit_num);
800 scsi_print_inquiry(inq_buf);
808 scsiserial(struct cam_device *device, int retry_count, int timeout)
811 struct scsi_vpd_unit_serial_number *serial_buf;
812 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
815 ccb = cam_getccb(device);
818 warnx("couldn't allocate CCB");
822 /* cam_getccb cleans up the header, caller has to zero the payload */
823 bzero(&(&ccb->ccb_h)[1],
824 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
826 serial_buf = (struct scsi_vpd_unit_serial_number *)
827 malloc(sizeof(*serial_buf));
829 if (serial_buf == NULL) {
831 warnx("can't malloc memory for serial number");
835 scsi_inquiry(&ccb->csio,
836 /*retries*/ retry_count,
838 /* tag_action */ MSG_SIMPLE_Q_TAG,
839 /* inq_buf */ (u_int8_t *)serial_buf,
840 /* inq_len */ sizeof(*serial_buf),
842 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
843 /* sense_len */ SSD_FULL_SIZE,
844 /* timeout */ timeout ? timeout : 5000);
846 /* Disable freezing the device queue */
847 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
849 if (arglist & CAM_ARG_ERR_RECOVER)
850 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
852 if (cam_send_ccb(device, ccb) < 0) {
853 warn("error getting serial number");
855 if (arglist & CAM_ARG_VERBOSE) {
856 cam_error_print(device, ccb, CAM_ESF_ALL,
857 CAM_EPF_ALL, stderr);
865 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
868 if (arglist & CAM_ARG_VERBOSE) {
869 cam_error_print(device, ccb, CAM_ESF_ALL,
870 CAM_EPF_ALL, stderr);
881 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
882 serial_num[serial_buf->length] = '\0';
884 if ((arglist & CAM_ARG_GET_STDINQ)
885 || (arglist & CAM_ARG_GET_XFERRATE))
886 fprintf(stdout, "%s%d: Serial Number ",
887 device->device_name, device->dev_unit_num);
889 fprintf(stdout, "%.60s\n", serial_num);
897 camxferrate(struct cam_device *device)
899 struct ccb_pathinq cpi;
906 if ((retval = get_cpi(device, &cpi)) != 0)
909 ccb = cam_getccb(device);
912 warnx("couldn't allocate CCB");
916 bzero(&(&ccb->ccb_h)[1],
917 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
919 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
920 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
922 if (((retval = cam_send_ccb(device, ccb)) < 0)
923 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
924 const char error_string[] = "error getting transfer settings";
931 if (arglist & CAM_ARG_VERBOSE)
932 cam_error_print(device, ccb, CAM_ESF_ALL,
933 CAM_EPF_ALL, stderr);
937 goto xferrate_bailout;
941 speed = cpi.base_transfer_speed;
943 if (ccb->cts.transport == XPORT_SPI) {
944 struct ccb_trans_settings_spi *spi =
945 &ccb->cts.xport_specific.spi;
947 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
948 freq = scsi_calc_syncsrate(spi->sync_period);
951 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
952 speed *= (0x01 << spi->bus_width);
954 } else if (ccb->cts.transport == XPORT_FC) {
955 struct ccb_trans_settings_fc *fc =
956 &ccb->cts.xport_specific.fc;
958 if (fc->valid & CTS_FC_VALID_SPEED)
960 } else if (ccb->cts.transport == XPORT_SAS) {
961 struct ccb_trans_settings_sas *sas =
962 &ccb->cts.xport_specific.sas;
964 if (sas->valid & CTS_SAS_VALID_SPEED)
965 speed = sas->bitrate;
966 } else if (ccb->cts.transport == XPORT_ATA) {
967 struct ccb_trans_settings_pata *pata =
968 &ccb->cts.xport_specific.ata;
970 if (pata->valid & CTS_ATA_VALID_MODE)
971 speed = ata_mode2speed(pata->mode);
972 } else if (ccb->cts.transport == XPORT_SATA) {
973 struct ccb_trans_settings_sata *sata =
974 &ccb->cts.xport_specific.sata;
976 if (sata->valid & CTS_SATA_VALID_REVISION)
977 speed = ata_revision2speed(sata->revision);
982 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
983 device->device_name, device->dev_unit_num,
986 fprintf(stdout, "%s%d: %dKB/s transfers",
987 device->device_name, device->dev_unit_num,
991 if (ccb->cts.transport == XPORT_SPI) {
992 struct ccb_trans_settings_spi *spi =
993 &ccb->cts.xport_specific.spi;
995 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
996 && (spi->sync_offset != 0))
997 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
998 freq % 1000, spi->sync_offset);
1000 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1001 && (spi->bus_width > 0)) {
1002 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1003 && (spi->sync_offset != 0)) {
1004 fprintf(stdout, ", ");
1006 fprintf(stdout, " (");
1008 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1009 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1010 && (spi->sync_offset != 0)) {
1011 fprintf(stdout, ")");
1013 } else if (ccb->cts.transport == XPORT_ATA) {
1014 struct ccb_trans_settings_pata *pata =
1015 &ccb->cts.xport_specific.ata;
1018 if (pata->valid & CTS_ATA_VALID_MODE)
1019 printf("%s, ", ata_mode2string(pata->mode));
1020 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1021 printf("ATAPI %dbytes, ", pata->atapi);
1022 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1023 printf("PIO %dbytes", pata->bytecount);
1025 } else if (ccb->cts.transport == XPORT_SATA) {
1026 struct ccb_trans_settings_sata *sata =
1027 &ccb->cts.xport_specific.sata;
1030 if (sata->valid & CTS_SATA_VALID_REVISION)
1031 printf("SATA %d.x, ", sata->revision);
1034 if (sata->valid & CTS_SATA_VALID_MODE)
1035 printf("%s, ", ata_mode2string(sata->mode));
1036 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1037 printf("ATAPI %dbytes, ", sata->atapi);
1038 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1039 printf("PIO %dbytes", sata->bytecount);
1043 if (ccb->cts.protocol == PROTO_SCSI) {
1044 struct ccb_trans_settings_scsi *scsi =
1045 &ccb->cts.proto_specific.scsi;
1046 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1047 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1048 fprintf(stdout, ", Command Queueing Enabled");
1053 fprintf(stdout, "\n");
1063 atacapprint(struct ata_params *parm)
1065 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1066 ((u_int32_t)parm->lba_size_2 << 16);
1068 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1069 ((u_int64_t)parm->lba_size48_2 << 16) |
1070 ((u_int64_t)parm->lba_size48_3 << 32) |
1071 ((u_int64_t)parm->lba_size48_4 << 48);
1074 printf("protocol ");
1075 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1076 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1077 if (parm->satacapabilities & ATA_SATA_GEN3)
1078 printf(" SATA 3.x\n");
1079 else if (parm->satacapabilities & ATA_SATA_GEN2)
1080 printf(" SATA 2.x\n");
1081 else if (parm->satacapabilities & ATA_SATA_GEN1)
1082 printf(" SATA 1.x\n");
1088 printf("device model %.40s\n", parm->model);
1089 printf("firmware revision %.8s\n", parm->revision);
1090 printf("serial number %.20s\n", parm->serial);
1091 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1092 printf("WWN %04x%04x%04x%04x\n",
1093 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1095 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1096 printf("media serial number %.30s\n",
1097 parm->media_serial);
1100 printf("cylinders %d\n", parm->cylinders);
1101 printf("heads %d\n", parm->heads);
1102 printf("sectors/track %d\n", parm->sectors);
1103 printf("sector size logical %u, physical %lu, offset %lu\n",
1104 ata_logical_sector_size(parm),
1105 (unsigned long)ata_physical_sector_size(parm),
1106 (unsigned long)ata_logical_sector_offset(parm));
1108 if (parm->config == ATA_PROTO_CFA ||
1109 (parm->support.command2 & ATA_SUPPORT_CFA))
1110 printf("CFA supported\n");
1112 printf("LBA%ssupported ",
1113 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1115 printf("%d sectors\n", lbasize);
1119 printf("LBA48%ssupported ",
1120 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1122 printf("%ju sectors\n", (uintmax_t)lbasize48);
1126 printf("PIO supported PIO");
1127 switch (ata_max_pmode(parm)) {
1143 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1144 printf(" w/o IORDY");
1147 printf("DMA%ssupported ",
1148 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1149 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1150 if (parm->mwdmamodes & 0xff) {
1152 if (parm->mwdmamodes & 0x04)
1154 else if (parm->mwdmamodes & 0x02)
1156 else if (parm->mwdmamodes & 0x01)
1160 if ((parm->atavalid & ATA_FLAG_88) &&
1161 (parm->udmamodes & 0xff)) {
1163 if (parm->udmamodes & 0x40)
1165 else if (parm->udmamodes & 0x20)
1167 else if (parm->udmamodes & 0x10)
1169 else if (parm->udmamodes & 0x08)
1171 else if (parm->udmamodes & 0x04)
1173 else if (parm->udmamodes & 0x02)
1175 else if (parm->udmamodes & 0x01)
1182 if (parm->media_rotation_rate == 1) {
1183 printf("media RPM non-rotating\n");
1184 } else if (parm->media_rotation_rate >= 0x0401 &&
1185 parm->media_rotation_rate <= 0xFFFE) {
1186 printf("media RPM %d\n",
1187 parm->media_rotation_rate);
1191 "Support Enabled Value Vendor\n");
1192 printf("read ahead %s %s\n",
1193 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1194 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1195 printf("write cache %s %s\n",
1196 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1197 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1198 printf("flush cache %s %s\n",
1199 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1200 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1201 printf("overlap %s\n",
1202 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1203 printf("Tagged Command Queuing (TCQ) %s %s",
1204 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1205 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1206 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1207 printf(" %d tags\n",
1208 ATA_QUEUE_LEN(parm->queue) + 1);
1211 printf("Native Command Queuing (NCQ) ");
1212 if (parm->satacapabilities != 0xffff &&
1213 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1214 printf("yes %d tags\n",
1215 ATA_QUEUE_LEN(parm->queue) + 1);
1218 printf("SMART %s %s\n",
1219 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1220 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1221 printf("microcode download %s %s\n",
1222 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1223 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1224 printf("security %s %s\n",
1225 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1226 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1227 printf("power management %s %s\n",
1228 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1229 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1230 printf("advanced power management %s %s",
1231 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1232 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1233 if (parm->support.command2 & ATA_SUPPORT_APM) {
1234 printf(" %d/0x%02X\n",
1235 parm->apm_value, parm->apm_value);
1238 printf("automatic acoustic management %s %s",
1239 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1240 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1241 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1242 printf(" %d/0x%02X %d/0x%02X\n",
1243 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1244 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1245 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1246 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1249 printf("media status notification %s %s\n",
1250 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1251 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1252 printf("power-up in Standby %s %s\n",
1253 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1254 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1255 printf("write-read-verify %s %s",
1256 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1257 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1258 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1259 printf(" %d/0x%x\n",
1260 parm->wrv_mode, parm->wrv_mode);
1263 printf("unload %s %s\n",
1264 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1265 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1266 printf("free-fall %s %s\n",
1267 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1268 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1269 printf("Data Set Management (DSM/TRIM) ");
1270 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1272 printf("DSM - max 512byte blocks ");
1273 if (parm->max_dsm_blocks == 0x00)
1274 printf("yes not specified\n");
1277 parm->max_dsm_blocks);
1279 printf("DSM - deterministic read ");
1280 if (parm->support3 & ATA_SUPPORT_DRAT) {
1281 if (parm->support3 & ATA_SUPPORT_RZAT)
1282 printf("yes zeroed\n");
1284 printf("yes any value\n");
1294 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1296 struct ata_pass_16 *ata_pass_16;
1297 struct ata_cmd ata_cmd;
1299 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1300 ata_cmd.command = ata_pass_16->command;
1301 ata_cmd.control = ata_pass_16->control;
1302 ata_cmd.features = ata_pass_16->features;
1304 if (arglist & CAM_ARG_VERBOSE) {
1305 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1306 ata_op_string(&ata_cmd),
1307 ccb->csio.ccb_h.timeout);
1310 /* Disable freezing the device queue */
1311 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1313 if (arglist & CAM_ARG_ERR_RECOVER)
1314 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1316 if (cam_send_ccb(device, ccb) < 0) {
1317 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1318 warn("error sending ATA %s via pass_16",
1319 ata_op_string(&ata_cmd));
1322 if (arglist & CAM_ARG_VERBOSE) {
1323 cam_error_print(device, ccb, CAM_ESF_ALL,
1324 CAM_EPF_ALL, stderr);
1330 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1331 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1332 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1333 warnx("ATA %s via pass_16 failed",
1334 ata_op_string(&ata_cmd));
1336 if (arglist & CAM_ARG_VERBOSE) {
1337 cam_error_print(device, ccb, CAM_ESF_ALL,
1338 CAM_EPF_ALL, stderr);
1349 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1351 if (arglist & CAM_ARG_VERBOSE) {
1352 warnx("sending ATA %s with timeout of %u msecs",
1353 ata_op_string(&(ccb->ataio.cmd)),
1354 ccb->ataio.ccb_h.timeout);
1357 /* Disable freezing the device queue */
1358 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1360 if (arglist & CAM_ARG_ERR_RECOVER)
1361 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1363 if (cam_send_ccb(device, ccb) < 0) {
1364 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1365 warn("error sending ATA %s",
1366 ata_op_string(&(ccb->ataio.cmd)));
1369 if (arglist & CAM_ARG_VERBOSE) {
1370 cam_error_print(device, ccb, CAM_ESF_ALL,
1371 CAM_EPF_ALL, stderr);
1377 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1378 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1379 warnx("ATA %s failed: %d",
1380 ata_op_string(&(ccb->ataio.cmd)), quiet);
1383 if (arglist & CAM_ARG_VERBOSE) {
1384 cam_error_print(device, ccb, CAM_ESF_ALL,
1385 CAM_EPF_ALL, stderr);
1395 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1396 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1397 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1398 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1399 u_int16_t dxfer_len, int timeout, int quiet)
1401 if (data_ptr != NULL) {
1402 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1403 AP_FLAG_TLEN_SECT_CNT;
1404 if (flags & CAM_DIR_OUT)
1405 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1407 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1409 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1412 bzero(&(&ccb->ccb_h)[1],
1413 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1415 scsi_ata_pass_16(&ccb->csio,
1429 /*sense_len*/SSD_FULL_SIZE,
1432 return scsi_cam_pass_16_send(device, ccb, quiet);
1436 ata_try_pass_16(struct cam_device *device)
1438 struct ccb_pathinq cpi;
1440 if (get_cpi(device, &cpi) != 0) {
1441 warnx("couldn't get CPI");
1445 if (cpi.protocol == PROTO_SCSI) {
1446 /* possibly compatible with pass_16 */
1450 /* likely not compatible with pass_16 */
1455 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1456 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1457 u_int8_t command, u_int8_t features, u_int32_t lba,
1458 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1459 int timeout, int quiet)
1463 switch (ata_try_pass_16(device)) {
1467 /* Try using SCSI Passthrough */
1468 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1469 0, tag_action, command, features, lba,
1470 sector_count, data_ptr, dxfer_len,
1474 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1475 sizeof(struct ccb_hdr));
1476 cam_fill_ataio(&ccb->ataio,
1485 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1486 return ata_cam_send(device, ccb, quiet);
1490 dump_data(uint16_t *ptr, uint32_t len)
1494 for (i = 0; i < len / 2; i++) {
1496 printf(" %3d: ", i);
1497 printf("%04hx ", ptr[i]);
1506 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
1507 union ccb *ccb, struct ata_params** ident_bufp)
1509 struct ata_params *ident_buf;
1510 struct ccb_pathinq cpi;
1511 struct ccb_getdev cgd;
1514 u_int8_t command, retry_command;
1516 if (get_cpi(device, &cpi) != 0) {
1517 warnx("couldn't get CPI");
1521 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
1522 if (cpi.protocol == PROTO_ATA) {
1523 if (get_cgd(device, &cgd) != 0) {
1524 warnx("couldn't get CGD");
1528 command = (cgd.protocol == PROTO_ATA) ?
1529 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
1532 /* We don't know which for sure so try both */
1533 command = ATA_ATA_IDENTIFY;
1534 retry_command = ATA_ATAPI_IDENTIFY;
1537 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
1539 warnx("can't calloc memory for identify\n");
1543 error = ata_do_28bit_cmd(device,
1545 /*retries*/retry_count,
1546 /*flags*/CAM_DIR_IN,
1547 /*protocol*/AP_PROTO_PIO_IN,
1548 /*tag_action*/MSG_SIMPLE_Q_TAG,
1552 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
1553 /*data_ptr*/(u_int8_t *)ptr,
1554 /*dxfer_len*/sizeof(struct ata_params),
1555 /*timeout*/timeout ? timeout : 30 * 1000,
1559 if (retry_command == 0) {
1563 error = ata_do_28bit_cmd(device,
1565 /*retries*/retry_count,
1566 /*flags*/CAM_DIR_IN,
1567 /*protocol*/AP_PROTO_PIO_IN,
1568 /*tag_action*/MSG_SIMPLE_Q_TAG,
1569 /*command*/retry_command,
1572 /*sector_count*/(u_int8_t)
1573 sizeof(struct ata_params),
1574 /*data_ptr*/(u_int8_t *)ptr,
1575 /*dxfer_len*/sizeof(struct ata_params),
1576 /*timeout*/timeout ? timeout : 30 * 1000,
1586 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
1587 ptr[i] = le16toh(ptr[i]);
1592 if (arglist & CAM_ARG_VERBOSE) {
1593 fprintf(stdout, "%s%d: Raw identify data:\n",
1594 device->device_name, device->dev_unit_num);
1595 dump_data(ptr, sizeof(struct ata_params));
1598 /* check for invalid (all zero) response */
1600 warnx("Invalid identify response detected");
1605 ident_buf = (struct ata_params *)ptr;
1606 if (strncmp(ident_buf->model, "FX", 2) &&
1607 strncmp(ident_buf->model, "NEC", 3) &&
1608 strncmp(ident_buf->model, "Pioneer", 7) &&
1609 strncmp(ident_buf->model, "SHARP", 5)) {
1610 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
1611 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
1612 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
1613 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
1615 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
1616 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
1617 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
1618 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
1619 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
1620 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
1621 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
1622 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
1623 sizeof(ident_buf->media_serial));
1625 *ident_bufp = ident_buf;
1632 ataidentify(struct cam_device *device, int retry_count, int timeout)
1635 struct ata_params *ident_buf;
1637 if ((ccb = cam_getccb(device)) == NULL) {
1638 warnx("couldn't allocate CCB");
1642 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
1647 printf("%s%d: ", device->device_name, device->dev_unit_num);
1648 ata_print_ident(ident_buf);
1649 camxferrate(device);
1650 atacapprint(ident_buf);
1657 #endif /* MINIMALISTIC */
1660 #ifndef MINIMALISTIC
1662 ATA_SECURITY_ACTION_PRINT,
1663 ATA_SECURITY_ACTION_FREEZE,
1664 ATA_SECURITY_ACTION_UNLOCK,
1665 ATA_SECURITY_ACTION_DISABLE,
1666 ATA_SECURITY_ACTION_ERASE,
1667 ATA_SECURITY_ACTION_ERASE_ENHANCED,
1668 ATA_SECURITY_ACTION_SET_PASSWORD
1669 } atasecurity_action;
1672 atasecurity_print_time(u_int16_t tw)
1676 printf("unspecified");
1678 printf("> 508 min");
1680 printf("%i min", 2 * tw);
1684 atasecurity_erase_timeout_msecs(u_int16_t timeout)
1688 return 2 * 3600 * 1000; /* default: two hours */
1689 else if (timeout > 255)
1690 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
1692 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
1697 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
1701 bzero(&cmd, sizeof(cmd));
1702 cmd.command = command;
1703 printf("Issuing %s", ata_op_string(&cmd));
1706 char pass[sizeof(pwd->password)+1];
1708 /* pwd->password may not be null terminated */
1709 pass[sizeof(pwd->password)] = '\0';
1710 strncpy(pass, pwd->password, sizeof(pwd->password));
1711 printf(" password='%s', user='%s'",
1713 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
1716 if (command == ATA_SECURITY_SET_PASSWORD) {
1717 printf(", mode='%s'",
1718 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
1719 "maximum" : "high");
1727 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
1728 int retry_count, u_int32_t timeout, int quiet)
1732 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
1734 return ata_do_28bit_cmd(device,
1737 /*flags*/CAM_DIR_NONE,
1738 /*protocol*/AP_PROTO_NON_DATA,
1739 /*tag_action*/MSG_SIMPLE_Q_TAG,
1740 /*command*/ATA_SECURITY_FREEZE_LOCK,
1751 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
1752 int retry_count, u_int32_t timeout,
1753 struct ata_security_password *pwd, int quiet)
1757 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
1759 return ata_do_28bit_cmd(device,
1762 /*flags*/CAM_DIR_OUT,
1763 /*protocol*/AP_PROTO_PIO_OUT,
1764 /*tag_action*/MSG_SIMPLE_Q_TAG,
1765 /*command*/ATA_SECURITY_UNLOCK,
1769 /*data_ptr*/(u_int8_t *)pwd,
1770 /*dxfer_len*/sizeof(*pwd),
1776 atasecurity_disable(struct cam_device *device, union ccb *ccb,
1777 int retry_count, u_int32_t timeout,
1778 struct ata_security_password *pwd, int quiet)
1782 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
1783 return ata_do_28bit_cmd(device,
1786 /*flags*/CAM_DIR_OUT,
1787 /*protocol*/AP_PROTO_PIO_OUT,
1788 /*tag_action*/MSG_SIMPLE_Q_TAG,
1789 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
1793 /*data_ptr*/(u_int8_t *)pwd,
1794 /*dxfer_len*/sizeof(*pwd),
1801 atasecurity_erase_confirm(struct cam_device *device,
1802 struct ata_params* ident_buf)
1805 printf("\nYou are about to ERASE ALL DATA from the following"
1806 " device:\n%s%d,%s%d: ", device->device_name,
1807 device->dev_unit_num, device->given_dev_name,
1808 device->given_unit_number);
1809 ata_print_ident(ident_buf);
1813 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
1815 if (fgets(str, sizeof(str), stdin) != NULL) {
1816 if (strncasecmp(str, "yes", 3) == 0) {
1818 } else if (strncasecmp(str, "no", 2) == 0) {
1821 printf("Please answer \"yes\" or "
1832 atasecurity_erase(struct cam_device *device, union ccb *ccb,
1833 int retry_count, u_int32_t timeout,
1834 u_int32_t erase_timeout,
1835 struct ata_security_password *pwd, int quiet)
1840 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
1842 error = ata_do_28bit_cmd(device,
1845 /*flags*/CAM_DIR_NONE,
1846 /*protocol*/AP_PROTO_NON_DATA,
1847 /*tag_action*/MSG_SIMPLE_Q_TAG,
1848 /*command*/ATA_SECURITY_ERASE_PREPARE,
1861 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
1863 error = ata_do_28bit_cmd(device,
1866 /*flags*/CAM_DIR_OUT,
1867 /*protocol*/AP_PROTO_PIO_OUT,
1868 /*tag_action*/MSG_SIMPLE_Q_TAG,
1869 /*command*/ATA_SECURITY_ERASE_UNIT,
1873 /*data_ptr*/(u_int8_t *)pwd,
1874 /*dxfer_len*/sizeof(*pwd),
1875 /*timeout*/erase_timeout,
1878 if (error == 0 && quiet == 0)
1879 printf("\nErase Complete\n");
1885 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
1886 int retry_count, u_int32_t timeout,
1887 struct ata_security_password *pwd, int quiet)
1891 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
1893 return ata_do_28bit_cmd(device,
1896 /*flags*/CAM_DIR_OUT,
1897 /*protocol*/AP_PROTO_PIO_OUT,
1898 /*tag_action*/MSG_SIMPLE_Q_TAG,
1899 /*command*/ATA_SECURITY_SET_PASSWORD,
1903 /*data_ptr*/(u_int8_t *)pwd,
1904 /*dxfer_len*/sizeof(*pwd),
1910 atasecurity_print(struct ata_params *parm)
1913 printf("\nSecurity Option Value\n");
1914 if (arglist & CAM_ARG_VERBOSE) {
1915 printf("status %04x\n",
1916 parm->security_status);
1918 printf("supported %s\n",
1919 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
1920 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
1922 printf("enabled %s\n",
1923 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
1924 printf("drive locked %s\n",
1925 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
1926 printf("security config frozen %s\n",
1927 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
1928 printf("count expired %s\n",
1929 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
1930 printf("security level %s\n",
1931 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
1932 printf("enhanced erase supported %s\n",
1933 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
1934 printf("erase time ");
1935 atasecurity_print_time(parm->erase_time);
1937 printf("enhanced erase time ");
1938 atasecurity_print_time(parm->enhanced_erase_time);
1940 printf("master password rev %04x%s\n",
1941 parm->master_passwd_revision,
1942 parm->master_passwd_revision == 0x0000 ||
1943 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
1947 * Validates and copies the password in optarg to the passed buffer.
1948 * If the password in optarg is the same length as the buffer then
1949 * the data will still be copied but no null termination will occur.
1952 ata_getpwd(u_int8_t *passwd, int max, char opt)
1956 len = strlen(optarg);
1958 warnx("-%c password is too long", opt);
1960 } else if (len == 0) {
1961 warnx("-%c password is missing", opt);
1963 } else if (optarg[0] == '-'){
1964 warnx("-%c password starts with '-' (generic arg?)", opt);
1966 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
1967 warnx("-%c password conflicts with existing password from -%c",
1972 /* Callers pass in a buffer which does NOT need to be terminated */
1973 strncpy(passwd, optarg, max);
1980 atasecurity(struct cam_device *device, int retry_count, int timeout,
1981 int argc, char **argv, char *combinedopt)
1984 struct ata_params *ident_buf;
1985 int error, confirm, quiet, c, action, actions, setpwd;
1986 int security_enabled, erase_timeout, pwdsize;
1987 struct ata_security_password pwd;
1995 memset(&pwd, 0, sizeof(pwd));
1997 /* default action is to print security information */
1998 action = ATA_SECURITY_ACTION_PRINT;
2000 /* user is master by default as its safer that way */
2001 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2002 pwdsize = sizeof(pwd.password);
2004 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2007 action = ATA_SECURITY_ACTION_FREEZE;
2012 if (strcasecmp(optarg, "user") == 0) {
2013 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2014 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2015 } else if (strcasecmp(optarg, "master") != 0) {
2016 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2017 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2019 warnx("-U argument '%s' is invalid (must be "
2020 "'user' or 'master')", optarg);
2026 if (strcasecmp(optarg, "high") == 0) {
2027 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2028 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2029 } else if (strcasecmp(optarg, "maximum") == 0) {
2030 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2031 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2033 warnx("-l argument '%s' is unknown (must be "
2034 "'high' or 'maximum')", optarg);
2040 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2042 action = ATA_SECURITY_ACTION_UNLOCK;
2047 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2049 action = ATA_SECURITY_ACTION_DISABLE;
2054 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2056 action = ATA_SECURITY_ACTION_ERASE;
2061 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2063 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2064 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2069 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2072 if (action == ATA_SECURITY_ACTION_PRINT)
2073 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2075 * Don't increment action as this can be combined
2076 * with other actions.
2089 erase_timeout = atoi(optarg) * 1000;
2095 warnx("too many security actions specified");
2099 if ((ccb = cam_getccb(device)) == NULL) {
2100 warnx("couldn't allocate CCB");
2104 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2111 printf("%s%d: ", device->device_name, device->dev_unit_num);
2112 ata_print_ident(ident_buf);
2113 camxferrate(device);
2116 if (action == ATA_SECURITY_ACTION_PRINT) {
2117 atasecurity_print(ident_buf);
2123 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2124 warnx("Security not supported");
2130 /* default timeout 15 seconds the same as linux hdparm */
2131 timeout = timeout ? timeout : 15 * 1000;
2133 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2135 /* first set the password if requested */
2137 /* confirm we can erase before setting the password if erasing */
2139 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2140 action == ATA_SECURITY_ACTION_ERASE) &&
2141 atasecurity_erase_confirm(device, ident_buf) == 0) {
2147 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2148 pwd.revision = ident_buf->master_passwd_revision;
2149 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2150 --pwd.revision == 0) {
2151 pwd.revision = 0xfffe;
2154 error = atasecurity_set_password(device, ccb, retry_count,
2155 timeout, &pwd, quiet);
2161 security_enabled = 1;
2165 case ATA_SECURITY_ACTION_FREEZE:
2166 error = atasecurity_freeze(device, ccb, retry_count,
2170 case ATA_SECURITY_ACTION_UNLOCK:
2171 if (security_enabled) {
2172 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2173 error = atasecurity_unlock(device, ccb,
2174 retry_count, timeout, &pwd, quiet);
2176 warnx("Can't unlock, drive is not locked");
2180 warnx("Can't unlock, security is disabled");
2185 case ATA_SECURITY_ACTION_DISABLE:
2186 if (security_enabled) {
2187 /* First unlock the drive if its locked */
2188 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2189 error = atasecurity_unlock(device, ccb,
2197 error = atasecurity_disable(device,
2205 warnx("Can't disable security (already disabled)");
2210 case ATA_SECURITY_ACTION_ERASE:
2211 if (security_enabled) {
2212 if (erase_timeout == 0) {
2213 erase_timeout = atasecurity_erase_timeout_msecs(
2214 ident_buf->erase_time);
2217 error = atasecurity_erase(device, ccb, retry_count,
2218 timeout, erase_timeout, &pwd,
2221 warnx("Can't secure erase (security is disabled)");
2226 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
2227 if (security_enabled) {
2228 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
2229 if (erase_timeout == 0) {
2231 atasecurity_erase_timeout_msecs(
2232 ident_buf->enhanced_erase_time);
2235 error = atasecurity_erase(device, ccb,
2236 retry_count, timeout,
2237 erase_timeout, &pwd,
2240 warnx("Enhanced erase is not supported");
2244 warnx("Can't secure erase (enhanced), "
2245 "(security is disabled)");
2256 #endif /* MINIMALISTIC */
2259 * Parse out a bus, or a bus, target and lun in the following
2265 * Returns the number of parsed components, or 0.
2268 parse_btl(char *tstr, int *bus, int *target, int *lun, cam_argmask *arglst)
2273 while (isspace(*tstr) && (*tstr != '\0'))
2276 tmpstr = (char *)strtok(tstr, ":");
2277 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
2278 *bus = strtol(tmpstr, NULL, 0);
2279 *arglst |= CAM_ARG_BUS;
2281 tmpstr = (char *)strtok(NULL, ":");
2282 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
2283 *target = strtol(tmpstr, NULL, 0);
2284 *arglst |= CAM_ARG_TARGET;
2286 tmpstr = (char *)strtok(NULL, ":");
2287 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
2288 *lun = strtol(tmpstr, NULL, 0);
2289 *arglst |= CAM_ARG_LUN;
2299 dorescan_or_reset(int argc, char **argv, int rescan)
2301 static const char must[] =
2302 "you must specify \"all\", a bus, or a bus:target:lun to %s";
2304 int bus = -1, target = -1, lun = -1;
2308 warnx(must, rescan? "rescan" : "reset");
2312 tstr = argv[optind];
2313 while (isspace(*tstr) && (*tstr != '\0'))
2315 if (strncasecmp(tstr, "all", strlen("all")) == 0)
2316 arglist |= CAM_ARG_BUS;
2318 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
2319 if (rv != 1 && rv != 3) {
2320 warnx(must, rescan? "rescan" : "reset");
2325 if ((arglist & CAM_ARG_BUS)
2326 && (arglist & CAM_ARG_TARGET)
2327 && (arglist & CAM_ARG_LUN))
2328 error = scanlun_or_reset_dev(bus, target, lun, rescan);
2330 error = rescan_or_reset_bus(bus, rescan);
2336 rescan_or_reset_bus(int bus, int rescan)
2338 union ccb ccb, matchccb;
2344 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
2345 warnx("error opening transport layer device %s", XPT_DEVICE);
2346 warn("%s", XPT_DEVICE);
2351 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
2352 ccb.ccb_h.path_id = bus;
2353 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
2354 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
2355 ccb.crcn.flags = CAM_FLAG_NONE;
2357 /* run this at a low priority */
2358 ccb.ccb_h.pinfo.priority = 5;
2360 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
2361 warn("CAMIOCOMMAND ioctl failed");
2366 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
2367 fprintf(stdout, "%s of bus %d was successful\n",
2368 rescan ? "Re-scan" : "Reset", bus);
2370 fprintf(stdout, "%s of bus %d returned error %#x\n",
2371 rescan ? "Re-scan" : "Reset", bus,
2372 ccb.ccb_h.status & CAM_STATUS_MASK);
2383 * The right way to handle this is to modify the xpt so that it can
2384 * handle a wildcarded bus in a rescan or reset CCB. At the moment
2385 * that isn't implemented, so instead we enumerate the busses and
2386 * send the rescan or reset to those busses in the case where the
2387 * given bus is -1 (wildcard). We don't send a rescan or reset
2388 * to the xpt bus; sending a rescan to the xpt bus is effectively a
2389 * no-op, sending a rescan to the xpt bus would result in a status of
2392 bzero(&(&matchccb.ccb_h)[1],
2393 sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr));
2394 matchccb.ccb_h.func_code = XPT_DEV_MATCH;
2395 matchccb.ccb_h.path_id = CAM_BUS_WILDCARD;
2396 bufsize = sizeof(struct dev_match_result) * 20;
2397 matchccb.cdm.match_buf_len = bufsize;
2398 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
2399 if (matchccb.cdm.matches == NULL) {
2400 warnx("can't malloc memory for matches");
2404 matchccb.cdm.num_matches = 0;
2406 matchccb.cdm.num_patterns = 1;
2407 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
2409 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
2410 matchccb.cdm.pattern_buf_len);
2411 if (matchccb.cdm.patterns == NULL) {
2412 warnx("can't malloc memory for patterns");
2416 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
2417 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
2422 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
2423 warn("CAMIOCOMMAND ioctl failed");
2428 if ((matchccb.ccb_h.status != CAM_REQ_CMP)
2429 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
2430 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
2431 warnx("got CAM error %#x, CDM error %d\n",
2432 matchccb.ccb_h.status, matchccb.cdm.status);
2437 for (i = 0; i < matchccb.cdm.num_matches; i++) {
2438 struct bus_match_result *bus_result;
2440 /* This shouldn't happen. */
2441 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
2444 bus_result = &matchccb.cdm.matches[i].result.bus_result;
2447 * We don't want to rescan or reset the xpt bus.
2450 if ((int)bus_result->path_id == -1)
2453 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
2455 ccb.ccb_h.path_id = bus_result->path_id;
2456 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
2457 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
2458 ccb.crcn.flags = CAM_FLAG_NONE;
2460 /* run this at a low priority */
2461 ccb.ccb_h.pinfo.priority = 5;
2463 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
2464 warn("CAMIOCOMMAND ioctl failed");
2469 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
2470 fprintf(stdout, "%s of bus %d was successful\n",
2471 rescan? "Re-scan" : "Reset",
2472 bus_result->path_id);
2475 * Don't bail out just yet, maybe the other
2476 * rescan or reset commands will complete
2479 fprintf(stderr, "%s of bus %d returned error "
2480 "%#x\n", rescan? "Re-scan" : "Reset",
2481 bus_result->path_id,
2482 ccb.ccb_h.status & CAM_STATUS_MASK);
2486 } while ((matchccb.ccb_h.status == CAM_REQ_CMP)
2487 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
2494 if (matchccb.cdm.patterns != NULL)
2495 free(matchccb.cdm.patterns);
2496 if (matchccb.cdm.matches != NULL)
2497 free(matchccb.cdm.matches);
2503 scanlun_or_reset_dev(int bus, int target, int lun, int scan)
2506 struct cam_device *device;
2512 warnx("invalid bus number %d", bus);
2517 warnx("invalid target number %d", target);
2522 warnx("invalid lun number %d", lun);
2528 bzero(&ccb, sizeof(union ccb));
2531 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
2532 warnx("error opening transport layer device %s\n",
2534 warn("%s", XPT_DEVICE);
2538 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
2539 if (device == NULL) {
2540 warnx("%s", cam_errbuf);
2545 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
2546 ccb.ccb_h.path_id = bus;
2547 ccb.ccb_h.target_id = target;
2548 ccb.ccb_h.target_lun = lun;
2549 ccb.ccb_h.timeout = 5000;
2550 ccb.crcn.flags = CAM_FLAG_NONE;
2552 /* run this at a low priority */
2553 ccb.ccb_h.pinfo.priority = 5;
2556 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
2557 warn("CAMIOCOMMAND ioctl failed");
2562 if (cam_send_ccb(device, &ccb) < 0) {
2563 warn("error sending XPT_RESET_DEV CCB");
2564 cam_close_device(device);
2572 cam_close_device(device);
2575 * An error code of CAM_BDR_SENT is normal for a BDR request.
2577 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
2579 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
2580 fprintf(stdout, "%s of %d:%d:%d was successful\n",
2581 scan? "Re-scan" : "Reset", bus, target, lun);
2584 fprintf(stdout, "%s of %d:%d:%d returned error %#x\n",
2585 scan? "Re-scan" : "Reset", bus, target, lun,
2586 ccb.ccb_h.status & CAM_STATUS_MASK);
2591 #ifndef MINIMALISTIC
2593 readdefects(struct cam_device *device, int argc, char **argv,
2594 char *combinedopt, int retry_count, int timeout)
2596 union ccb *ccb = NULL;
2597 struct scsi_read_defect_data_10 *rdd_cdb;
2598 u_int8_t *defect_list = NULL;
2599 u_int32_t dlist_length = 65000;
2600 u_int32_t returned_length = 0;
2601 u_int32_t num_returned = 0;
2602 u_int8_t returned_format;
2605 int lists_specified = 0;
2607 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2613 while (isspace(*tstr) && (*tstr != '\0'))
2615 if (strcmp(tstr, "block") == 0)
2616 arglist |= CAM_ARG_FORMAT_BLOCK;
2617 else if (strcmp(tstr, "bfi") == 0)
2618 arglist |= CAM_ARG_FORMAT_BFI;
2619 else if (strcmp(tstr, "phys") == 0)
2620 arglist |= CAM_ARG_FORMAT_PHYS;
2623 warnx("invalid defect format %s", tstr);
2624 goto defect_bailout;
2629 arglist |= CAM_ARG_GLIST;
2632 arglist |= CAM_ARG_PLIST;
2639 ccb = cam_getccb(device);
2642 * Hopefully 65000 bytes is enough to hold the defect list. If it
2643 * isn't, the disk is probably dead already. We'd have to go with
2644 * 12 byte command (i.e. alloc_length is 32 bits instead of 16)
2647 defect_list = malloc(dlist_length);
2648 if (defect_list == NULL) {
2649 warnx("can't malloc memory for defect list");
2651 goto defect_bailout;
2654 rdd_cdb =(struct scsi_read_defect_data_10 *)&ccb->csio.cdb_io.cdb_bytes;
2657 * cam_getccb() zeros the CCB header only. So we need to zero the
2658 * payload portion of the ccb.
2660 bzero(&(&ccb->ccb_h)[1],
2661 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
2663 cam_fill_csio(&ccb->csio,
2664 /*retries*/ retry_count,
2666 /*flags*/ CAM_DIR_IN | ((arglist & CAM_ARG_ERR_RECOVER) ?
2667 CAM_PASS_ERR_RECOVER : 0),
2668 /*tag_action*/ MSG_SIMPLE_Q_TAG,
2669 /*data_ptr*/ defect_list,
2670 /*dxfer_len*/ dlist_length,
2671 /*sense_len*/ SSD_FULL_SIZE,
2672 /*cdb_len*/ sizeof(struct scsi_read_defect_data_10),
2673 /*timeout*/ timeout ? timeout : 5000);
2675 rdd_cdb->opcode = READ_DEFECT_DATA_10;
2676 if (arglist & CAM_ARG_FORMAT_BLOCK)
2677 rdd_cdb->format = SRDD10_BLOCK_FORMAT;
2678 else if (arglist & CAM_ARG_FORMAT_BFI)
2679 rdd_cdb->format = SRDD10_BYTES_FROM_INDEX_FORMAT;
2680 else if (arglist & CAM_ARG_FORMAT_PHYS)
2681 rdd_cdb->format = SRDD10_PHYSICAL_SECTOR_FORMAT;
2684 warnx("no defect list format specified");
2685 goto defect_bailout;
2687 if (arglist & CAM_ARG_PLIST) {
2688 rdd_cdb->format |= SRDD10_PLIST;
2692 if (arglist & CAM_ARG_GLIST) {
2693 rdd_cdb->format |= SRDD10_GLIST;
2697 scsi_ulto2b(dlist_length, rdd_cdb->alloc_length);
2699 /* Disable freezing the device queue */
2700 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
2702 if (cam_send_ccb(device, ccb) < 0) {
2703 perror("error reading defect list");
2705 if (arglist & CAM_ARG_VERBOSE) {
2706 cam_error_print(device, ccb, CAM_ESF_ALL,
2707 CAM_EPF_ALL, stderr);
2711 goto defect_bailout;
2714 returned_length = scsi_2btoul(((struct
2715 scsi_read_defect_data_hdr_10 *)defect_list)->length);
2717 returned_format = ((struct scsi_read_defect_data_hdr_10 *)
2718 defect_list)->format;
2720 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
2721 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
2722 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
2723 struct scsi_sense_data *sense;
2724 int error_code, sense_key, asc, ascq;
2726 sense = &ccb->csio.sense_data;
2727 scsi_extract_sense(sense, &error_code, &sense_key, &asc, &ascq);
2730 * According to the SCSI spec, if the disk doesn't support
2731 * the requested format, it will generally return a sense
2732 * key of RECOVERED ERROR, and an additional sense code
2733 * of "DEFECT LIST NOT FOUND". So, we check for that, and
2734 * also check to make sure that the returned length is
2735 * greater than 0, and then print out whatever format the
2738 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
2739 && (asc == 0x1c) && (ascq == 0x00)
2740 && (returned_length > 0)) {
2741 warnx("requested defect format not available");
2742 switch(returned_format & SRDDH10_DLIST_FORMAT_MASK) {
2743 case SRDD10_BLOCK_FORMAT:
2744 warnx("Device returned block format");
2746 case SRDD10_BYTES_FROM_INDEX_FORMAT:
2747 warnx("Device returned bytes from index"
2750 case SRDD10_PHYSICAL_SECTOR_FORMAT:
2751 warnx("Device returned physical sector format");
2755 warnx("Device returned unknown defect"
2756 " data format %#x", returned_format);
2757 goto defect_bailout;
2758 break; /* NOTREACHED */
2762 warnx("Error returned from read defect data command");
2763 if (arglist & CAM_ARG_VERBOSE)
2764 cam_error_print(device, ccb, CAM_ESF_ALL,
2765 CAM_EPF_ALL, stderr);
2766 goto defect_bailout;
2768 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2770 warnx("Error returned from read defect data command");
2771 if (arglist & CAM_ARG_VERBOSE)
2772 cam_error_print(device, ccb, CAM_ESF_ALL,
2773 CAM_EPF_ALL, stderr);
2774 goto defect_bailout;
2778 * XXX KDM I should probably clean up the printout format for the
2781 switch (returned_format & SRDDH10_DLIST_FORMAT_MASK){
2782 case SRDDH10_PHYSICAL_SECTOR_FORMAT:
2784 struct scsi_defect_desc_phys_sector *dlist;
2786 dlist = (struct scsi_defect_desc_phys_sector *)
2788 sizeof(struct scsi_read_defect_data_hdr_10));
2790 num_returned = returned_length /
2791 sizeof(struct scsi_defect_desc_phys_sector);
2793 fprintf(stderr, "Got %d defect", num_returned);
2795 if ((lists_specified == 0) || (num_returned == 0)) {
2796 fprintf(stderr, "s.\n");
2798 } else if (num_returned == 1)
2799 fprintf(stderr, ":\n");
2801 fprintf(stderr, "s:\n");
2803 for (i = 0; i < num_returned; i++) {
2804 fprintf(stdout, "%d:%d:%d\n",
2805 scsi_3btoul(dlist[i].cylinder),
2807 scsi_4btoul(dlist[i].sector));
2811 case SRDDH10_BYTES_FROM_INDEX_FORMAT:
2813 struct scsi_defect_desc_bytes_from_index *dlist;
2815 dlist = (struct scsi_defect_desc_bytes_from_index *)
2817 sizeof(struct scsi_read_defect_data_hdr_10));
2819 num_returned = returned_length /
2820 sizeof(struct scsi_defect_desc_bytes_from_index);
2822 fprintf(stderr, "Got %d defect", num_returned);
2824 if ((lists_specified == 0) || (num_returned == 0)) {
2825 fprintf(stderr, "s.\n");
2827 } else if (num_returned == 1)
2828 fprintf(stderr, ":\n");
2830 fprintf(stderr, "s:\n");
2832 for (i = 0; i < num_returned; i++) {
2833 fprintf(stdout, "%d:%d:%d\n",
2834 scsi_3btoul(dlist[i].cylinder),
2836 scsi_4btoul(dlist[i].bytes_from_index));
2840 case SRDDH10_BLOCK_FORMAT:
2842 struct scsi_defect_desc_block *dlist;
2844 dlist = (struct scsi_defect_desc_block *)(defect_list +
2845 sizeof(struct scsi_read_defect_data_hdr_10));
2847 num_returned = returned_length /
2848 sizeof(struct scsi_defect_desc_block);
2850 fprintf(stderr, "Got %d defect", num_returned);
2852 if ((lists_specified == 0) || (num_returned == 0)) {
2853 fprintf(stderr, "s.\n");
2855 } else if (num_returned == 1)
2856 fprintf(stderr, ":\n");
2858 fprintf(stderr, "s:\n");
2860 for (i = 0; i < num_returned; i++)
2861 fprintf(stdout, "%u\n",
2862 scsi_4btoul(dlist[i].address));
2866 fprintf(stderr, "Unknown defect format %d\n",
2867 returned_format & SRDDH10_DLIST_FORMAT_MASK);
2873 if (defect_list != NULL)
2881 #endif /* MINIMALISTIC */
2885 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
2889 ccb = cam_getccb(device);
2895 #ifndef MINIMALISTIC
2897 mode_sense(struct cam_device *device, int mode_page, int page_control,
2898 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
2903 ccb = cam_getccb(device);
2906 errx(1, "mode_sense: couldn't allocate CCB");
2908 bzero(&(&ccb->ccb_h)[1],
2909 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
2911 scsi_mode_sense(&ccb->csio,
2912 /* retries */ retry_count,
2914 /* tag_action */ MSG_SIMPLE_Q_TAG,
2916 /* page_code */ page_control << 6,
2917 /* page */ mode_page,
2918 /* param_buf */ data,
2919 /* param_len */ datalen,
2920 /* sense_len */ SSD_FULL_SIZE,
2921 /* timeout */ timeout ? timeout : 5000);
2923 if (arglist & CAM_ARG_ERR_RECOVER)
2924 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
2926 /* Disable freezing the device queue */
2927 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
2929 if (((retval = cam_send_ccb(device, ccb)) < 0)
2930 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
2931 if (arglist & CAM_ARG_VERBOSE) {
2932 cam_error_print(device, ccb, CAM_ESF_ALL,
2933 CAM_EPF_ALL, stderr);
2936 cam_close_device(device);
2938 err(1, "error sending mode sense command");
2940 errx(1, "error sending mode sense command");
2947 mode_select(struct cam_device *device, int save_pages, int retry_count,
2948 int timeout, u_int8_t *data, int datalen)
2953 ccb = cam_getccb(device);
2956 errx(1, "mode_select: couldn't allocate CCB");
2958 bzero(&(&ccb->ccb_h)[1],
2959 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
2961 scsi_mode_select(&ccb->csio,
2962 /* retries */ retry_count,
2964 /* tag_action */ MSG_SIMPLE_Q_TAG,
2965 /* scsi_page_fmt */ 1,
2966 /* save_pages */ save_pages,
2967 /* param_buf */ data,
2968 /* param_len */ datalen,
2969 /* sense_len */ SSD_FULL_SIZE,
2970 /* timeout */ timeout ? timeout : 5000);
2972 if (arglist & CAM_ARG_ERR_RECOVER)
2973 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
2975 /* Disable freezing the device queue */
2976 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
2978 if (((retval = cam_send_ccb(device, ccb)) < 0)
2979 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
2980 if (arglist & CAM_ARG_VERBOSE) {
2981 cam_error_print(device, ccb, CAM_ESF_ALL,
2982 CAM_EPF_ALL, stderr);
2985 cam_close_device(device);
2988 err(1, "error sending mode select command");
2990 errx(1, "error sending mode select command");
2998 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
2999 int retry_count, int timeout)
3001 int c, mode_page = -1, page_control = 0;
3002 int binary = 0, list = 0;
3004 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3010 arglist |= CAM_ARG_DBD;
3013 arglist |= CAM_ARG_MODE_EDIT;
3019 mode_page = strtol(optarg, NULL, 0);
3021 errx(1, "invalid mode page %d", mode_page);
3024 page_control = strtol(optarg, NULL, 0);
3025 if ((page_control < 0) || (page_control > 3))
3026 errx(1, "invalid page control field %d",
3028 arglist |= CAM_ARG_PAGE_CNTL;
3035 if (mode_page == -1 && list == 0)
3036 errx(1, "you must specify a mode page!");
3039 mode_list(device, page_control, arglist & CAM_ARG_DBD,
3040 retry_count, timeout);
3042 mode_edit(device, mode_page, page_control,
3043 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
3044 retry_count, timeout);
3049 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
3050 int retry_count, int timeout)
3053 u_int32_t flags = CAM_DIR_NONE;
3054 u_int8_t *data_ptr = NULL;
3056 u_int8_t atacmd[12];
3057 struct get_hook hook;
3058 int c, data_bytes = 0;
3064 char *datastr = NULL, *tstr, *resstr = NULL;
3066 int fd_data = 0, fd_res = 0;
3069 ccb = cam_getccb(device);
3072 warnx("scsicmd: error allocating ccb");
3076 bzero(&(&ccb->ccb_h)[1],
3077 sizeof(union ccb) - sizeof(struct ccb_hdr));
3079 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3083 while (isspace(*tstr) && (*tstr != '\0'))
3085 hook.argc = argc - optind;
3086 hook.argv = argv + optind;
3088 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
3091 * Increment optind by the number of arguments the
3092 * encoding routine processed. After each call to
3093 * getopt(3), optind points to the argument that
3094 * getopt should process _next_. In this case,
3095 * that means it points to the first command string
3096 * argument, if there is one. Once we increment
3097 * this, it should point to either the next command
3098 * line argument, or it should be past the end of
3105 while (isspace(*tstr) && (*tstr != '\0'))
3107 hook.argc = argc - optind;
3108 hook.argv = argv + optind;
3110 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
3113 * Increment optind by the number of arguments the
3114 * encoding routine processed. After each call to
3115 * getopt(3), optind points to the argument that
3116 * getopt should process _next_. In this case,
3117 * that means it points to the first command string
3118 * argument, if there is one. Once we increment
3119 * this, it should point to either the next command
3120 * line argument, or it should be past the end of
3132 if (arglist & CAM_ARG_CMD_OUT) {
3133 warnx("command must either be "
3134 "read or write, not both");
3136 goto scsicmd_bailout;
3138 arglist |= CAM_ARG_CMD_IN;
3140 data_bytes = strtol(optarg, NULL, 0);
3141 if (data_bytes <= 0) {
3142 warnx("invalid number of input bytes %d",
3145 goto scsicmd_bailout;
3147 hook.argc = argc - optind;
3148 hook.argv = argv + optind;
3151 datastr = cget(&hook, NULL);
3153 * If the user supplied "-" instead of a format, he
3154 * wants the data to be written to stdout.
3156 if ((datastr != NULL)
3157 && (datastr[0] == '-'))
3160 data_ptr = (u_int8_t *)malloc(data_bytes);
3161 if (data_ptr == NULL) {
3162 warnx("can't malloc memory for data_ptr");
3164 goto scsicmd_bailout;
3168 if (arglist & CAM_ARG_CMD_IN) {
3169 warnx("command must either be "
3170 "read or write, not both");
3172 goto scsicmd_bailout;
3174 arglist |= CAM_ARG_CMD_OUT;
3175 flags = CAM_DIR_OUT;
3176 data_bytes = strtol(optarg, NULL, 0);
3177 if (data_bytes <= 0) {
3178 warnx("invalid number of output bytes %d",
3181 goto scsicmd_bailout;
3183 hook.argc = argc - optind;
3184 hook.argv = argv + optind;
3186 datastr = cget(&hook, NULL);
3187 data_ptr = (u_int8_t *)malloc(data_bytes);
3188 if (data_ptr == NULL) {
3189 warnx("can't malloc memory for data_ptr");
3191 goto scsicmd_bailout;
3193 bzero(data_ptr, data_bytes);
3195 * If the user supplied "-" instead of a format, he
3196 * wants the data to be read from stdin.
3198 if ((datastr != NULL)
3199 && (datastr[0] == '-'))
3202 buff_encode_visit(data_ptr, data_bytes, datastr,
3208 hook.argc = argc - optind;
3209 hook.argv = argv + optind;
3211 resstr = cget(&hook, NULL);
3212 if ((resstr != NULL) && (resstr[0] == '-'))
3222 * If fd_data is set, and we're writing to the device, we need to
3223 * read the data the user wants written from stdin.
3225 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
3227 int amt_to_read = data_bytes;
3228 u_int8_t *buf_ptr = data_ptr;
3230 for (amt_read = 0; amt_to_read > 0;
3231 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
3232 if (amt_read == -1) {
3233 warn("error reading data from stdin");
3235 goto scsicmd_bailout;
3237 amt_to_read -= amt_read;
3238 buf_ptr += amt_read;
3242 if (arglist & CAM_ARG_ERR_RECOVER)
3243 flags |= CAM_PASS_ERR_RECOVER;
3245 /* Disable freezing the device queue */
3246 flags |= CAM_DEV_QFRZDIS;
3250 * This is taken from the SCSI-3 draft spec.
3251 * (T10/1157D revision 0.3)
3252 * The top 3 bits of an opcode are the group code.
3253 * The next 5 bits are the command code.
3254 * Group 0: six byte commands
3255 * Group 1: ten byte commands
3256 * Group 2: ten byte commands
3258 * Group 4: sixteen byte commands
3259 * Group 5: twelve byte commands
3260 * Group 6: vendor specific
3261 * Group 7: vendor specific
3263 switch((cdb[0] >> 5) & 0x7) {
3274 /* computed by buff_encode_visit */
3285 * We should probably use csio_build_visit or something like that
3286 * here, but it's easier to encode arguments as you go. The
3287 * alternative would be skipping the CDB argument and then encoding
3288 * it here, since we've got the data buffer argument by now.
3290 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
3292 cam_fill_csio(&ccb->csio,
3293 /*retries*/ retry_count,
3296 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3297 /*data_ptr*/ data_ptr,
3298 /*dxfer_len*/ data_bytes,
3299 /*sense_len*/ SSD_FULL_SIZE,
3300 /*cdb_len*/ cdb_len,
3301 /*timeout*/ timeout ? timeout : 5000);
3304 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
3306 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
3308 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
3310 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
3312 cam_fill_ataio(&ccb->ataio,
3313 /*retries*/ retry_count,
3317 /*data_ptr*/ data_ptr,
3318 /*dxfer_len*/ data_bytes,
3319 /*timeout*/ timeout ? timeout : 5000);
3322 if (((retval = cam_send_ccb(device, ccb)) < 0)
3323 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
3325 warn("error sending command");
3327 warnx("error sending command");
3329 if (arglist & CAM_ARG_VERBOSE) {
3330 cam_error_print(device, ccb, CAM_ESF_ALL,
3331 CAM_EPF_ALL, stderr);
3335 goto scsicmd_bailout;
3338 if (atacmd_len && need_res) {
3340 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
3342 fprintf(stdout, "\n");
3345 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
3346 ccb->ataio.res.status,
3347 ccb->ataio.res.error,
3348 ccb->ataio.res.lba_low,
3349 ccb->ataio.res.lba_mid,
3350 ccb->ataio.res.lba_high,
3351 ccb->ataio.res.device,
3352 ccb->ataio.res.lba_low_exp,
3353 ccb->ataio.res.lba_mid_exp,
3354 ccb->ataio.res.lba_high_exp,
3355 ccb->ataio.res.sector_count,
3356 ccb->ataio.res.sector_count_exp);
3361 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3362 && (arglist & CAM_ARG_CMD_IN)
3363 && (data_bytes > 0)) {
3365 buff_decode_visit(data_ptr, data_bytes, datastr,
3367 fprintf(stdout, "\n");
3369 ssize_t amt_written;
3370 int amt_to_write = data_bytes;
3371 u_int8_t *buf_ptr = data_ptr;
3373 for (amt_written = 0; (amt_to_write > 0) &&
3374 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
3375 amt_to_write -= amt_written;
3376 buf_ptr += amt_written;
3378 if (amt_written == -1) {
3379 warn("error writing data to stdout");
3381 goto scsicmd_bailout;
3382 } else if ((amt_written == 0)
3383 && (amt_to_write > 0)) {
3384 warnx("only wrote %u bytes out of %u",
3385 data_bytes - amt_to_write, data_bytes);
3392 if ((data_bytes > 0) && (data_ptr != NULL))
3401 camdebug(int argc, char **argv, char *combinedopt)
3404 int bus = -1, target = -1, lun = -1;
3405 char *tstr, *tmpstr = NULL;
3409 bzero(&ccb, sizeof(union ccb));
3411 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3414 arglist |= CAM_ARG_DEBUG_INFO;
3415 ccb.cdbg.flags |= CAM_DEBUG_INFO;
3418 arglist |= CAM_ARG_DEBUG_PERIPH;
3419 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
3422 arglist |= CAM_ARG_DEBUG_SUBTRACE;
3423 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
3426 arglist |= CAM_ARG_DEBUG_TRACE;
3427 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
3430 arglist |= CAM_ARG_DEBUG_XPT;
3431 ccb.cdbg.flags |= CAM_DEBUG_XPT;
3434 arglist |= CAM_ARG_DEBUG_CDB;
3435 ccb.cdbg.flags |= CAM_DEBUG_CDB;
3438 arglist |= CAM_ARG_DEBUG_PROBE;
3439 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
3446 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3447 warnx("error opening transport layer device %s", XPT_DEVICE);
3448 warn("%s", XPT_DEVICE);
3455 warnx("you must specify \"off\", \"all\" or a bus,");
3456 warnx("bus:target, or bus:target:lun");
3463 while (isspace(*tstr) && (*tstr != '\0'))
3466 if (strncmp(tstr, "off", 3) == 0) {
3467 ccb.cdbg.flags = CAM_DEBUG_NONE;
3468 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
3469 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
3470 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
3471 } else if (strncmp(tstr, "all", 3) != 0) {
3472 tmpstr = (char *)strtok(tstr, ":");
3473 if ((tmpstr != NULL) && (*tmpstr != '\0')){
3474 bus = strtol(tmpstr, NULL, 0);
3475 arglist |= CAM_ARG_BUS;
3476 tmpstr = (char *)strtok(NULL, ":");
3477 if ((tmpstr != NULL) && (*tmpstr != '\0')){
3478 target = strtol(tmpstr, NULL, 0);
3479 arglist |= CAM_ARG_TARGET;
3480 tmpstr = (char *)strtok(NULL, ":");
3481 if ((tmpstr != NULL) && (*tmpstr != '\0')){
3482 lun = strtol(tmpstr, NULL, 0);
3483 arglist |= CAM_ARG_LUN;
3488 warnx("you must specify \"all\", \"off\", or a bus,");
3489 warnx("bus:target, or bus:target:lun to debug");
3495 ccb.ccb_h.func_code = XPT_DEBUG;
3496 ccb.ccb_h.path_id = bus;
3497 ccb.ccb_h.target_id = target;
3498 ccb.ccb_h.target_lun = lun;
3500 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3501 warn("CAMIOCOMMAND ioctl failed");
3506 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
3507 CAM_FUNC_NOTAVAIL) {
3508 warnx("CAM debugging not available");
3509 warnx("you need to put options CAMDEBUG in"
3510 " your kernel config file!");
3512 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
3514 warnx("XPT_DEBUG CCB failed with status %#x",
3518 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
3520 "Debugging turned off\n");
3523 "Debugging enabled for "
3536 tagcontrol(struct cam_device *device, int argc, char **argv,
3546 ccb = cam_getccb(device);
3549 warnx("tagcontrol: error allocating ccb");
3553 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3556 numtags = strtol(optarg, NULL, 0);
3558 warnx("tag count %d is < 0", numtags);
3560 goto tagcontrol_bailout;
3571 cam_path_string(device, pathstr, sizeof(pathstr));
3574 bzero(&(&ccb->ccb_h)[1],
3575 sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
3576 ccb->ccb_h.func_code = XPT_REL_SIMQ;
3577 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
3578 ccb->crs.openings = numtags;
3581 if (cam_send_ccb(device, ccb) < 0) {
3582 perror("error sending XPT_REL_SIMQ CCB");
3584 goto tagcontrol_bailout;
3587 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3588 warnx("XPT_REL_SIMQ CCB failed");
3589 cam_error_print(device, ccb, CAM_ESF_ALL,
3590 CAM_EPF_ALL, stderr);
3592 goto tagcontrol_bailout;
3597 fprintf(stdout, "%stagged openings now %d\n",
3598 pathstr, ccb->crs.openings);
3601 bzero(&(&ccb->ccb_h)[1],
3602 sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr));
3604 ccb->ccb_h.func_code = XPT_GDEV_STATS;
3606 if (cam_send_ccb(device, ccb) < 0) {
3607 perror("error sending XPT_GDEV_STATS CCB");
3609 goto tagcontrol_bailout;
3612 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3613 warnx("XPT_GDEV_STATS CCB failed");
3614 cam_error_print(device, ccb, CAM_ESF_ALL,
3615 CAM_EPF_ALL, stderr);
3617 goto tagcontrol_bailout;
3620 if (arglist & CAM_ARG_VERBOSE) {
3621 fprintf(stdout, "%s", pathstr);
3622 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
3623 fprintf(stdout, "%s", pathstr);
3624 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
3625 fprintf(stdout, "%s", pathstr);
3626 fprintf(stdout, "devq_openings %d\n", ccb->cgds.devq_openings);
3627 fprintf(stdout, "%s", pathstr);
3628 fprintf(stdout, "devq_queued %d\n", ccb->cgds.devq_queued);
3629 fprintf(stdout, "%s", pathstr);
3630 fprintf(stdout, "held %d\n", ccb->cgds.held);
3631 fprintf(stdout, "%s", pathstr);
3632 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
3633 fprintf(stdout, "%s", pathstr);
3634 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
3637 fprintf(stdout, "%s", pathstr);
3638 fprintf(stdout, "device openings: ");
3640 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
3641 ccb->cgds.dev_active);
3651 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
3655 cam_path_string(device, pathstr, sizeof(pathstr));
3657 if (cts->transport == XPORT_SPI) {
3658 struct ccb_trans_settings_spi *spi =
3659 &cts->xport_specific.spi;
3661 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
3663 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
3666 if (spi->sync_offset != 0) {
3669 freq = scsi_calc_syncsrate(spi->sync_period);
3670 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
3671 pathstr, freq / 1000, freq % 1000);
3675 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
3676 fprintf(stdout, "%soffset: %d\n", pathstr,
3680 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
3681 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
3682 (0x01 << spi->bus_width) * 8);
3685 if (spi->valid & CTS_SPI_VALID_DISC) {
3686 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
3687 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
3688 "enabled" : "disabled");
3691 if (cts->transport == XPORT_FC) {
3692 struct ccb_trans_settings_fc *fc =
3693 &cts->xport_specific.fc;
3695 if (fc->valid & CTS_FC_VALID_WWNN)
3696 fprintf(stdout, "%sWWNN: 0x%llx", pathstr,
3697 (long long) fc->wwnn);
3698 if (fc->valid & CTS_FC_VALID_WWPN)
3699 fprintf(stdout, "%sWWPN: 0x%llx", pathstr,
3700 (long long) fc->wwpn);
3701 if (fc->valid & CTS_FC_VALID_PORT)
3702 fprintf(stdout, "%sPortID: 0x%x", pathstr, fc->port);
3703 if (fc->valid & CTS_FC_VALID_SPEED)
3704 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
3705 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
3707 if (cts->transport == XPORT_SAS) {
3708 struct ccb_trans_settings_sas *sas =
3709 &cts->xport_specific.sas;
3711 if (sas->valid & CTS_SAS_VALID_SPEED)
3712 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
3713 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
3715 if (cts->transport == XPORT_ATA) {
3716 struct ccb_trans_settings_pata *pata =
3717 &cts->xport_specific.ata;
3719 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
3720 fprintf(stdout, "%sATA mode: %s\n", pathstr,
3721 ata_mode2string(pata->mode));
3723 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
3724 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
3727 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
3728 fprintf(stdout, "%sPIO transaction length: %d\n",
3729 pathstr, pata->bytecount);
3732 if (cts->transport == XPORT_SATA) {
3733 struct ccb_trans_settings_sata *sata =
3734 &cts->xport_specific.sata;
3736 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
3737 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
3740 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
3741 fprintf(stdout, "%sATA mode: %s\n", pathstr,
3742 ata_mode2string(sata->mode));
3744 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
3745 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
3748 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
3749 fprintf(stdout, "%sPIO transaction length: %d\n",
3750 pathstr, sata->bytecount);
3752 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
3753 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
3756 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
3757 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
3760 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
3761 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
3765 if (cts->protocol == PROTO_ATA) {
3766 struct ccb_trans_settings_ata *ata=
3767 &cts->proto_specific.ata;
3769 if (ata->valid & CTS_ATA_VALID_TQ) {
3770 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
3771 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
3772 "enabled" : "disabled");
3775 if (cts->protocol == PROTO_SCSI) {
3776 struct ccb_trans_settings_scsi *scsi=
3777 &cts->proto_specific.scsi;
3779 if (scsi->valid & CTS_SCSI_VALID_TQ) {
3780 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
3781 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
3782 "enabled" : "disabled");
3789 * Get a path inquiry CCB for the specified device.
3792 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
3797 ccb = cam_getccb(device);
3799 warnx("get_cpi: couldn't allocate CCB");
3802 bzero(&(&ccb->ccb_h)[1],
3803 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
3804 ccb->ccb_h.func_code = XPT_PATH_INQ;
3805 if (cam_send_ccb(device, ccb) < 0) {
3806 warn("get_cpi: error sending Path Inquiry CCB");
3807 if (arglist & CAM_ARG_VERBOSE)
3808 cam_error_print(device, ccb, CAM_ESF_ALL,
3809 CAM_EPF_ALL, stderr);
3811 goto get_cpi_bailout;
3813 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3814 if (arglist & CAM_ARG_VERBOSE)
3815 cam_error_print(device, ccb, CAM_ESF_ALL,
3816 CAM_EPF_ALL, stderr);
3818 goto get_cpi_bailout;
3820 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
3828 * Get a get device CCB for the specified device.
3831 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
3836 ccb = cam_getccb(device);
3838 warnx("get_cgd: couldn't allocate CCB");
3841 bzero(&(&ccb->ccb_h)[1],
3842 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
3843 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
3844 if (cam_send_ccb(device, ccb) < 0) {
3845 warn("get_cgd: error sending Path Inquiry CCB");
3846 if (arglist & CAM_ARG_VERBOSE)
3847 cam_error_print(device, ccb, CAM_ESF_ALL,
3848 CAM_EPF_ALL, stderr);
3850 goto get_cgd_bailout;
3852 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3853 if (arglist & CAM_ARG_VERBOSE)
3854 cam_error_print(device, ccb, CAM_ESF_ALL,
3855 CAM_EPF_ALL, stderr);
3857 goto get_cgd_bailout;
3859 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
3867 cpi_print(struct ccb_pathinq *cpi)
3869 char adapter_str[1024];
3872 snprintf(adapter_str, sizeof(adapter_str),
3873 "%s%d:", cpi->dev_name, cpi->unit_number);
3875 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
3878 for (i = 1; i < 0xff; i = i << 1) {
3881 if ((i & cpi->hba_inquiry) == 0)
3884 fprintf(stdout, "%s supports ", adapter_str);
3888 str = "MDP message";
3891 str = "32 bit wide SCSI";
3894 str = "16 bit wide SCSI";
3897 str = "SDTR message";
3900 str = "linked CDBs";
3903 str = "tag queue messages";
3906 str = "soft reset alternative";
3909 str = "SATA Port Multiplier";
3912 str = "unknown PI bit set";
3915 fprintf(stdout, "%s\n", str);
3918 for (i = 1; i < 0xff; i = i << 1) {
3921 if ((i & cpi->hba_misc) == 0)
3924 fprintf(stdout, "%s ", adapter_str);
3928 str = "bus scans from high ID to low ID";
3931 str = "removable devices not included in scan";
3933 case PIM_NOINITIATOR:
3934 str = "initiator role not supported";
3936 case PIM_NOBUSRESET:
3937 str = "user has disabled initial BUS RESET or"
3938 " controller is in target/mixed mode";
3941 str = "do not send 6-byte commands";
3944 str = "scan bus sequentially";
3947 str = "unknown PIM bit set";
3950 fprintf(stdout, "%s\n", str);
3953 for (i = 1; i < 0xff; i = i << 1) {
3956 if ((i & cpi->target_sprt) == 0)
3959 fprintf(stdout, "%s supports ", adapter_str);
3962 str = "target mode processor mode";
3965 str = "target mode phase cog. mode";
3967 case PIT_DISCONNECT:
3968 str = "disconnects in target mode";
3971 str = "terminate I/O message in target mode";
3974 str = "group 6 commands in target mode";
3977 str = "group 7 commands in target mode";
3980 str = "unknown PIT bit set";
3984 fprintf(stdout, "%s\n", str);
3986 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
3988 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
3990 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
3992 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
3993 adapter_str, cpi->hpath_id);
3994 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
3996 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
3997 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
3998 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
3999 fprintf(stdout, "%s base transfer speed: ", adapter_str);
4000 if (cpi->base_transfer_speed > 1000)
4001 fprintf(stdout, "%d.%03dMB/sec\n",
4002 cpi->base_transfer_speed / 1000,
4003 cpi->base_transfer_speed % 1000);
4005 fprintf(stdout, "%dKB/sec\n",
4006 (cpi->base_transfer_speed % 1000) * 1000);
4010 get_print_cts(struct cam_device *device, int user_settings, int quiet,
4011 struct ccb_trans_settings *cts)
4017 ccb = cam_getccb(device);
4020 warnx("get_print_cts: error allocating ccb");
4024 bzero(&(&ccb->ccb_h)[1],
4025 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
4027 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
4029 if (user_settings == 0)
4030 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
4032 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
4034 if (cam_send_ccb(device, ccb) < 0) {
4035 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
4036 if (arglist & CAM_ARG_VERBOSE)
4037 cam_error_print(device, ccb, CAM_ESF_ALL,
4038 CAM_EPF_ALL, stderr);
4040 goto get_print_cts_bailout;
4043 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4044 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
4045 if (arglist & CAM_ARG_VERBOSE)
4046 cam_error_print(device, ccb, CAM_ESF_ALL,
4047 CAM_EPF_ALL, stderr);
4049 goto get_print_cts_bailout;
4053 cts_print(device, &ccb->cts);
4056 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
4058 get_print_cts_bailout:
4066 ratecontrol(struct cam_device *device, int retry_count, int timeout,
4067 int argc, char **argv, char *combinedopt)
4071 int user_settings = 0;
4073 int disc_enable = -1, tag_enable = -1;
4076 double syncrate = -1;
4079 int change_settings = 0, send_tur = 0;
4080 struct ccb_pathinq cpi;
4082 ccb = cam_getccb(device);
4084 warnx("ratecontrol: error allocating ccb");
4087 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4096 if (strncasecmp(optarg, "enable", 6) == 0)
4098 else if (strncasecmp(optarg, "disable", 7) == 0)
4101 warnx("-D argument \"%s\" is unknown", optarg);
4103 goto ratecontrol_bailout;
4105 change_settings = 1;
4108 mode = ata_string2mode(optarg);
4110 warnx("unknown mode '%s'", optarg);
4112 goto ratecontrol_bailout;
4114 change_settings = 1;
4117 offset = strtol(optarg, NULL, 0);
4119 warnx("offset value %d is < 0", offset);
4121 goto ratecontrol_bailout;
4123 change_settings = 1;
4129 syncrate = atof(optarg);
4131 warnx("sync rate %f is < 0", syncrate);
4133 goto ratecontrol_bailout;
4135 change_settings = 1;
4138 if (strncasecmp(optarg, "enable", 6) == 0)
4140 else if (strncasecmp(optarg, "disable", 7) == 0)
4143 warnx("-T argument \"%s\" is unknown", optarg);
4145 goto ratecontrol_bailout;
4147 change_settings = 1;
4153 bus_width = strtol(optarg, NULL, 0);
4154 if (bus_width < 0) {
4155 warnx("bus width %d is < 0", bus_width);
4157 goto ratecontrol_bailout;
4159 change_settings = 1;
4165 bzero(&(&ccb->ccb_h)[1],
4166 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4168 * Grab path inquiry information, so we can determine whether
4169 * or not the initiator is capable of the things that the user
4172 ccb->ccb_h.func_code = XPT_PATH_INQ;
4173 if (cam_send_ccb(device, ccb) < 0) {
4174 perror("error sending XPT_PATH_INQ CCB");
4175 if (arglist & CAM_ARG_VERBOSE) {
4176 cam_error_print(device, ccb, CAM_ESF_ALL,
4177 CAM_EPF_ALL, stderr);
4180 goto ratecontrol_bailout;
4182 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4183 warnx("XPT_PATH_INQ CCB failed");
4184 if (arglist & CAM_ARG_VERBOSE) {
4185 cam_error_print(device, ccb, CAM_ESF_ALL,
4186 CAM_EPF_ALL, stderr);
4189 goto ratecontrol_bailout;
4191 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
4192 bzero(&(&ccb->ccb_h)[1],
4193 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
4195 fprintf(stdout, "%s parameters:\n",
4196 user_settings ? "User" : "Current");
4198 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
4200 goto ratecontrol_bailout;
4202 if (arglist & CAM_ARG_VERBOSE)
4205 if (change_settings) {
4206 int didsettings = 0;
4207 struct ccb_trans_settings_spi *spi = NULL;
4208 struct ccb_trans_settings_pata *pata = NULL;
4209 struct ccb_trans_settings_sata *sata = NULL;
4210 struct ccb_trans_settings_ata *ata = NULL;
4211 struct ccb_trans_settings_scsi *scsi = NULL;
4213 if (ccb->cts.transport == XPORT_SPI)
4214 spi = &ccb->cts.xport_specific.spi;
4215 if (ccb->cts.transport == XPORT_ATA)
4216 pata = &ccb->cts.xport_specific.ata;
4217 if (ccb->cts.transport == XPORT_SATA)
4218 sata = &ccb->cts.xport_specific.sata;
4219 if (ccb->cts.protocol == PROTO_ATA)
4220 ata = &ccb->cts.proto_specific.ata;
4221 if (ccb->cts.protocol == PROTO_SCSI)
4222 scsi = &ccb->cts.proto_specific.scsi;
4223 ccb->cts.xport_specific.valid = 0;
4224 ccb->cts.proto_specific.valid = 0;
4225 if (spi && disc_enable != -1) {
4226 spi->valid |= CTS_SPI_VALID_DISC;
4227 if (disc_enable == 0)
4228 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
4230 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
4233 if (tag_enable != -1) {
4234 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
4235 warnx("HBA does not support tagged queueing, "
4236 "so you cannot modify tag settings");
4238 goto ratecontrol_bailout;
4241 ata->valid |= CTS_SCSI_VALID_TQ;
4242 if (tag_enable == 0)
4243 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
4245 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
4248 scsi->valid |= CTS_SCSI_VALID_TQ;
4249 if (tag_enable == 0)
4250 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
4252 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
4256 if (spi && offset != -1) {
4257 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
4258 warnx("HBA is not capable of changing offset");
4260 goto ratecontrol_bailout;
4262 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
4263 spi->sync_offset = offset;
4266 if (spi && syncrate != -1) {
4267 int prelim_sync_period;
4270 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
4271 warnx("HBA is not capable of changing "
4274 goto ratecontrol_bailout;
4276 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
4278 * The sync rate the user gives us is in MHz.
4279 * We need to translate it into KHz for this
4284 * Next, we calculate a "preliminary" sync period
4285 * in tenths of a nanosecond.
4288 prelim_sync_period = 0;
4290 prelim_sync_period = 10000000 / syncrate;
4292 scsi_calc_syncparam(prelim_sync_period);
4293 freq = scsi_calc_syncsrate(spi->sync_period);
4296 if (sata && syncrate != -1) {
4297 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
4298 warnx("HBA is not capable of changing "
4301 goto ratecontrol_bailout;
4303 if (!user_settings) {
4304 warnx("You can modify only user rate "
4305 "settings for SATA");
4307 goto ratecontrol_bailout;
4309 sata->revision = ata_speed2revision(syncrate * 100);
4310 if (sata->revision < 0) {
4311 warnx("Invalid rate %f", syncrate);
4313 goto ratecontrol_bailout;
4315 sata->valid |= CTS_SATA_VALID_REVISION;
4318 if ((pata || sata) && mode != -1) {
4319 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
4320 warnx("HBA is not capable of changing "
4323 goto ratecontrol_bailout;
4325 if (!user_settings) {
4326 warnx("You can modify only user mode "
4327 "settings for ATA/SATA");
4329 goto ratecontrol_bailout;
4333 pata->valid |= CTS_ATA_VALID_MODE;
4336 sata->valid |= CTS_SATA_VALID_MODE;
4341 * The bus_width argument goes like this:
4345 * Therefore, if you shift the number of bits given on the
4346 * command line right by 4, you should get the correct
4349 if (spi && bus_width != -1) {
4351 * We might as well validate things here with a
4352 * decipherable error message, rather than what
4353 * will probably be an indecipherable error message
4354 * by the time it gets back to us.
4356 if ((bus_width == 16)
4357 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
4358 warnx("HBA does not support 16 bit bus width");
4360 goto ratecontrol_bailout;
4361 } else if ((bus_width == 32)
4362 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
4363 warnx("HBA does not support 32 bit bus width");
4365 goto ratecontrol_bailout;
4366 } else if ((bus_width != 8)
4367 && (bus_width != 16)
4368 && (bus_width != 32)) {
4369 warnx("Invalid bus width %d", bus_width);
4371 goto ratecontrol_bailout;
4373 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
4374 spi->bus_width = bus_width >> 4;
4377 if (didsettings == 0) {
4378 goto ratecontrol_bailout;
4380 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
4381 if (cam_send_ccb(device, ccb) < 0) {
4382 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
4383 if (arglist & CAM_ARG_VERBOSE) {
4384 cam_error_print(device, ccb, CAM_ESF_ALL,
4385 CAM_EPF_ALL, stderr);
4388 goto ratecontrol_bailout;
4390 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4391 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
4392 if (arglist & CAM_ARG_VERBOSE) {
4393 cam_error_print(device, ccb, CAM_ESF_ALL,
4394 CAM_EPF_ALL, stderr);
4397 goto ratecontrol_bailout;
4401 retval = testunitready(device, retry_count, timeout,
4402 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
4404 * If the TUR didn't succeed, just bail.
4408 fprintf(stderr, "Test Unit Ready failed\n");
4409 goto ratecontrol_bailout;
4412 if ((change_settings || send_tur) && !quiet &&
4413 (ccb->cts.transport == XPORT_ATA ||
4414 ccb->cts.transport == XPORT_SATA || send_tur)) {
4415 fprintf(stdout, "New parameters:\n");
4416 retval = get_print_cts(device, user_settings, 0, NULL);
4419 ratecontrol_bailout:
4425 scsiformat(struct cam_device *device, int argc, char **argv,
4426 char *combinedopt, int retry_count, int timeout)
4430 int ycount = 0, quiet = 0;
4431 int error = 0, response = 0, retval = 0;
4432 int use_timeout = 10800 * 1000;
4434 struct format_defect_list_header fh;
4435 u_int8_t *data_ptr = NULL;
4436 u_int32_t dxfer_len = 0;
4438 int num_warnings = 0;
4441 ccb = cam_getccb(device);
4444 warnx("scsiformat: error allocating ccb");
4448 bzero(&(&ccb->ccb_h)[1],
4449 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
4451 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4472 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
4473 "following device:\n");
4475 error = scsidoinquiry(device, argc, argv, combinedopt,
4476 retry_count, timeout);
4479 warnx("scsiformat: error sending inquiry");
4480 goto scsiformat_bailout;
4489 fprintf(stdout, "Are you SURE you want to do "
4492 if (fgets(str, sizeof(str), stdin) != NULL) {
4494 if (strncasecmp(str, "yes", 3) == 0)
4496 else if (strncasecmp(str, "no", 2) == 0)
4499 fprintf(stdout, "Please answer"
4500 " \"yes\" or \"no\"\n");
4503 } while (response == 0);
4505 if (response == -1) {
4507 goto scsiformat_bailout;
4512 use_timeout = timeout;
4515 fprintf(stdout, "Current format timeout is %d seconds\n",
4516 use_timeout / 1000);
4520 * If the user hasn't disabled questions and didn't specify a
4521 * timeout on the command line, ask them if they want the current
4525 && (timeout == 0)) {
4527 int new_timeout = 0;
4529 fprintf(stdout, "Enter new timeout in seconds or press\n"
4530 "return to keep the current timeout [%d] ",
4531 use_timeout / 1000);
4533 if (fgets(str, sizeof(str), stdin) != NULL) {
4535 new_timeout = atoi(str);
4538 if (new_timeout != 0) {
4539 use_timeout = new_timeout * 1000;
4540 fprintf(stdout, "Using new timeout value %d\n",
4541 use_timeout / 1000);
4546 * Keep this outside the if block below to silence any unused
4547 * variable warnings.
4549 bzero(&fh, sizeof(fh));
4552 * If we're in immediate mode, we've got to include the format
4555 if (immediate != 0) {
4556 fh.byte2 = FU_DLH_IMMED;
4557 data_ptr = (u_int8_t *)&fh;
4558 dxfer_len = sizeof(fh);
4559 byte2 = FU_FMT_DATA;
4560 } else if (quiet == 0) {
4561 fprintf(stdout, "Formatting...");
4565 scsi_format_unit(&ccb->csio,
4566 /* retries */ retry_count,
4568 /* tag_action */ MSG_SIMPLE_Q_TAG,
4571 /* data_ptr */ data_ptr,
4572 /* dxfer_len */ dxfer_len,
4573 /* sense_len */ SSD_FULL_SIZE,
4574 /* timeout */ use_timeout);
4576 /* Disable freezing the device queue */
4577 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4579 if (arglist & CAM_ARG_ERR_RECOVER)
4580 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4582 if (((retval = cam_send_ccb(device, ccb)) < 0)
4583 || ((immediate == 0)
4584 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
4585 const char errstr[] = "error sending format command";
4592 if (arglist & CAM_ARG_VERBOSE) {
4593 cam_error_print(device, ccb, CAM_ESF_ALL,
4594 CAM_EPF_ALL, stderr);
4597 goto scsiformat_bailout;
4601 * If we ran in non-immediate mode, we already checked for errors
4602 * above and printed out any necessary information. If we're in
4603 * immediate mode, we need to loop through and get status
4604 * information periodically.
4606 if (immediate == 0) {
4608 fprintf(stdout, "Format Complete\n");
4610 goto scsiformat_bailout;
4617 bzero(&(&ccb->ccb_h)[1],
4618 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
4621 * There's really no need to do error recovery or
4622 * retries here, since we're just going to sit in a
4623 * loop and wait for the device to finish formatting.
4625 scsi_test_unit_ready(&ccb->csio,
4628 /* tag_action */ MSG_SIMPLE_Q_TAG,
4629 /* sense_len */ SSD_FULL_SIZE,
4630 /* timeout */ 5000);
4632 /* Disable freezing the device queue */
4633 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4635 retval = cam_send_ccb(device, ccb);
4638 * If we get an error from the ioctl, bail out. SCSI
4639 * errors are expected.
4642 warn("error sending CAMIOCOMMAND ioctl");
4643 if (arglist & CAM_ARG_VERBOSE) {
4644 cam_error_print(device, ccb, CAM_ESF_ALL,
4645 CAM_EPF_ALL, stderr);
4648 goto scsiformat_bailout;
4651 status = ccb->ccb_h.status & CAM_STATUS_MASK;
4653 if ((status != CAM_REQ_CMP)
4654 && (status == CAM_SCSI_STATUS_ERROR)
4655 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4656 struct scsi_sense_data *sense;
4657 int error_code, sense_key, asc, ascq;
4659 sense = &ccb->csio.sense_data;
4660 scsi_extract_sense(sense, &error_code, &sense_key,
4664 * According to the SCSI-2 and SCSI-3 specs, a
4665 * drive that is in the middle of a format should
4666 * return NOT READY with an ASC of "logical unit
4667 * not ready, format in progress". The sense key
4668 * specific bytes will then be a progress indicator.
4670 if ((sense_key == SSD_KEY_NOT_READY)
4671 && (asc == 0x04) && (ascq == 0x04)) {
4672 if ((sense->extra_len >= 10)
4673 && ((sense->sense_key_spec[0] &
4674 SSD_SCS_VALID) != 0)
4677 u_int64_t percentage;
4680 &sense->sense_key_spec[1]);
4681 percentage = 10000 * val;
4684 "\rFormatting: %ju.%02u %% "
4686 (uintmax_t)(percentage /
4688 (unsigned)((percentage /
4692 } else if ((quiet == 0)
4693 && (++num_warnings <= 1)) {
4694 warnx("Unexpected SCSI Sense Key "
4695 "Specific value returned "
4697 scsi_sense_print(device, &ccb->csio,
4699 warnx("Unable to print status "
4700 "information, but format will "
4702 warnx("will exit when format is "
4707 warnx("Unexpected SCSI error during format");
4708 cam_error_print(device, ccb, CAM_ESF_ALL,
4709 CAM_EPF_ALL, stderr);
4711 goto scsiformat_bailout;
4714 } else if (status != CAM_REQ_CMP) {
4715 warnx("Unexpected CAM status %#x", status);
4716 if (arglist & CAM_ARG_VERBOSE)
4717 cam_error_print(device, ccb, CAM_ESF_ALL,
4718 CAM_EPF_ALL, stderr);
4720 goto scsiformat_bailout;
4723 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
4726 fprintf(stdout, "\nFormat Complete\n");
4736 scsireportluns(struct cam_device *device, int argc, char **argv,
4737 char *combinedopt, int retry_count, int timeout)
4740 int c, countonly, lunsonly;
4741 struct scsi_report_luns_data *lundata;
4743 uint8_t report_type;
4744 uint32_t list_len, i, j;
4749 report_type = RPL_REPORT_DEFAULT;
4750 ccb = cam_getccb(device);
4753 warnx("%s: error allocating ccb", __func__);
4757 bzero(&(&ccb->ccb_h)[1],
4758 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
4763 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4772 if (strcasecmp(optarg, "default") == 0)
4773 report_type = RPL_REPORT_DEFAULT;
4774 else if (strcasecmp(optarg, "wellknown") == 0)
4775 report_type = RPL_REPORT_WELLKNOWN;
4776 else if (strcasecmp(optarg, "all") == 0)
4777 report_type = RPL_REPORT_ALL;
4779 warnx("%s: invalid report type \"%s\"",
4790 if ((countonly != 0)
4791 && (lunsonly != 0)) {
4792 warnx("%s: you can only specify one of -c or -l", __func__);
4797 * According to SPC-4, the allocation length must be at least 16
4798 * bytes -- enough for the header and one LUN.
4800 alloc_len = sizeof(*lundata) + 8;
4804 lundata = malloc(alloc_len);
4806 if (lundata == NULL) {
4807 warn("%s: error mallocing %d bytes", __func__, alloc_len);
4812 scsi_report_luns(&ccb->csio,
4813 /*retries*/ retry_count,
4815 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4816 /*select_report*/ report_type,
4817 /*rpl_buf*/ lundata,
4818 /*alloc_len*/ alloc_len,
4819 /*sense_len*/ SSD_FULL_SIZE,
4820 /*timeout*/ timeout ? timeout : 5000);
4822 /* Disable freezing the device queue */
4823 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4825 if (arglist & CAM_ARG_ERR_RECOVER)
4826 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4828 if (cam_send_ccb(device, ccb) < 0) {
4829 warn("error sending REPORT LUNS command");
4831 if (arglist & CAM_ARG_VERBOSE)
4832 cam_error_print(device, ccb, CAM_ESF_ALL,
4833 CAM_EPF_ALL, stderr);
4839 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4840 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4846 list_len = scsi_4btoul(lundata->length);
4849 * If we need to list the LUNs, and our allocation
4850 * length was too short, reallocate and retry.
4852 if ((countonly == 0)
4853 && (list_len > (alloc_len - sizeof(*lundata)))) {
4854 alloc_len = list_len + sizeof(*lundata);
4860 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
4861 ((list_len / 8) > 1) ? "s" : "");
4866 for (i = 0; i < (list_len / 8); i++) {
4870 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
4872 fprintf(stdout, ",");
4873 switch (lundata->luns[i].lundata[j] &
4874 RPL_LUNDATA_ATYP_MASK) {
4875 case RPL_LUNDATA_ATYP_PERIPH:
4876 if ((lundata->luns[i].lundata[j] &
4877 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
4878 fprintf(stdout, "%d:",
4879 lundata->luns[i].lundata[j] &
4880 RPL_LUNDATA_PERIPH_BUS_MASK);
4882 && ((lundata->luns[i].lundata[j+2] &
4883 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
4886 fprintf(stdout, "%d",
4887 lundata->luns[i].lundata[j+1]);
4889 case RPL_LUNDATA_ATYP_FLAT: {
4891 tmplun[0] = lundata->luns[i].lundata[j] &
4892 RPL_LUNDATA_FLAT_LUN_MASK;
4893 tmplun[1] = lundata->luns[i].lundata[j+1];
4895 fprintf(stdout, "%d", scsi_2btoul(tmplun));
4899 case RPL_LUNDATA_ATYP_LUN:
4900 fprintf(stdout, "%d:%d:%d",
4901 (lundata->luns[i].lundata[j+1] &
4902 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
4903 lundata->luns[i].lundata[j] &
4904 RPL_LUNDATA_LUN_TARG_MASK,
4905 lundata->luns[i].lundata[j+1] &
4906 RPL_LUNDATA_LUN_LUN_MASK);
4908 case RPL_LUNDATA_ATYP_EXTLUN: {
4909 int field_len, field_len_code, eam_code;
4911 eam_code = lundata->luns[i].lundata[j] &
4912 RPL_LUNDATA_EXT_EAM_MASK;
4913 field_len_code = (lundata->luns[i].lundata[j] &
4914 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
4915 field_len = field_len_code * 2;
4917 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
4918 && (field_len_code == 0x00)) {
4919 fprintf(stdout, "%d",
4920 lundata->luns[i].lundata[j+1]);
4921 } else if ((eam_code ==
4922 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
4923 && (field_len_code == 0x03)) {
4927 * This format takes up all 8 bytes.
4928 * If we aren't starting at offset 0,
4932 fprintf(stdout, "Invalid "
4935 "specified format", j);
4939 bzero(tmp_lun, sizeof(tmp_lun));
4940 bcopy(&lundata->luns[i].lundata[j+1],
4941 &tmp_lun[1], sizeof(tmp_lun) - 1);
4942 fprintf(stdout, "%#jx",
4943 (intmax_t)scsi_8btou64(tmp_lun));
4946 fprintf(stderr, "Unknown Extended LUN"
4947 "Address method %#x, length "
4948 "code %#x", eam_code,
4955 fprintf(stderr, "Unknown LUN address method "
4956 "%#x\n", lundata->luns[i].lundata[0] &
4957 RPL_LUNDATA_ATYP_MASK);
4961 * For the flat addressing method, there are no
4962 * other levels after it.
4967 fprintf(stdout, "\n");
4980 scsireadcapacity(struct cam_device *device, int argc, char **argv,
4981 char *combinedopt, int retry_count, int timeout)
4984 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
4985 struct scsi_read_capacity_data rcap;
4986 struct scsi_read_capacity_data_long rcaplong;
5000 ccb = cam_getccb(device);
5003 warnx("%s: error allocating ccb", __func__);
5007 bzero(&(&ccb->ccb_h)[1],
5008 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5010 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5037 if ((blocksizeonly != 0)
5038 && (numblocks != 0)) {
5039 warnx("%s: you can only specify one of -b or -N", __func__);
5044 if ((blocksizeonly != 0)
5045 && (sizeonly != 0)) {
5046 warnx("%s: you can only specify one of -b or -s", __func__);
5053 warnx("%s: you can only specify one of -h/-H or -q", __func__);
5059 && (blocksizeonly != 0)) {
5060 warnx("%s: you can only specify one of -h/-H or -b", __func__);
5065 scsi_read_capacity(&ccb->csio,
5066 /*retries*/ retry_count,
5068 /*tag_action*/ MSG_SIMPLE_Q_TAG,
5071 /*timeout*/ timeout ? timeout : 5000);
5073 /* Disable freezing the device queue */
5074 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5076 if (arglist & CAM_ARG_ERR_RECOVER)
5077 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5079 if (cam_send_ccb(device, ccb) < 0) {
5080 warn("error sending READ CAPACITY command");
5082 if (arglist & CAM_ARG_VERBOSE)
5083 cam_error_print(device, ccb, CAM_ESF_ALL,
5084 CAM_EPF_ALL, stderr);
5090 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5091 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
5096 maxsector = scsi_4btoul(rcap.addr);
5097 block_len = scsi_4btoul(rcap.length);
5100 * A last block of 2^32-1 means that the true capacity is over 2TB,
5101 * and we need to issue the long READ CAPACITY to get the real
5102 * capacity. Otherwise, we're all set.
5104 if (maxsector != 0xffffffff)
5107 scsi_read_capacity_16(&ccb->csio,
5108 /*retries*/ retry_count,
5110 /*tag_action*/ MSG_SIMPLE_Q_TAG,
5115 /*sense_len*/ SSD_FULL_SIZE,
5116 /*timeout*/ timeout ? timeout : 5000);
5118 /* Disable freezing the device queue */
5119 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5121 if (arglist & CAM_ARG_ERR_RECOVER)
5122 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5124 if (cam_send_ccb(device, ccb) < 0) {
5125 warn("error sending READ CAPACITY (16) command");
5127 if (arglist & CAM_ARG_VERBOSE)
5128 cam_error_print(device, ccb, CAM_ESF_ALL,
5129 CAM_EPF_ALL, stderr);
5135 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5136 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
5141 maxsector = scsi_8btou64(rcaplong.addr);
5142 block_len = scsi_4btoul(rcaplong.length);
5145 if (blocksizeonly == 0) {
5147 * Humanize implies !quiet, and also implies numblocks.
5149 if (humanize != 0) {
5154 tmpbytes = (maxsector + 1) * block_len;
5155 ret = humanize_number(tmpstr, sizeof(tmpstr),
5156 tmpbytes, "", HN_AUTOSCALE,
5159 HN_DIVISOR_1000 : 0));
5161 warnx("%s: humanize_number failed!", __func__);
5165 fprintf(stdout, "Device Size: %s%s", tmpstr,
5166 (sizeonly == 0) ? ", " : "\n");
5167 } else if (numblocks != 0) {
5168 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
5169 "Blocks: " : "", (uintmax_t)maxsector + 1,
5170 (sizeonly == 0) ? ", " : "\n");
5172 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
5173 "Last Block: " : "", (uintmax_t)maxsector,
5174 (sizeonly == 0) ? ", " : "\n");
5178 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
5179 "Block Length: " : "", block_len, (quiet == 0) ?
5188 atapm(struct cam_device *device, int argc, char **argv,
5189 char *combinedopt, int retry_count, int timeout)
5197 ccb = cam_getccb(device);
5200 warnx("%s: error allocating ccb", __func__);
5204 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5213 if (strcmp(argv[1], "idle") == 0) {
5215 cmd = ATA_IDLE_IMMEDIATE;
5218 } else if (strcmp(argv[1], "standby") == 0) {
5220 cmd = ATA_STANDBY_IMMEDIATE;
5222 cmd = ATA_STANDBY_CMD;
5230 else if (t <= (240 * 5))
5232 else if (t <= (252 * 5))
5233 /* special encoding for 21 minutes */
5235 else if (t <= (11 * 30 * 60))
5236 sc = (t - 1) / (30 * 60) + 241;
5240 cam_fill_ataio(&ccb->ataio,
5243 /*flags*/CAM_DIR_NONE,
5247 timeout ? timeout : 30 * 1000);
5248 ata_28bit_cmd(&ccb->ataio, cmd, 0, 0, sc);
5250 /* Disable freezing the device queue */
5251 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5253 if (arglist & CAM_ARG_ERR_RECOVER)
5254 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5256 if (cam_send_ccb(device, ccb) < 0) {
5257 warn("error sending command");
5259 if (arglist & CAM_ARG_VERBOSE)
5260 cam_error_print(device, ccb, CAM_ESF_ALL,
5261 CAM_EPF_ALL, stderr);
5267 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5268 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
5277 #endif /* MINIMALISTIC */
5282 fprintf(verbose ? stdout : stderr,
5283 "usage: camcontrol <command> [device id][generic args][command args]\n"
5284 " camcontrol devlist [-v]\n"
5285 #ifndef MINIMALISTIC
5286 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
5287 " camcontrol tur [dev_id][generic args]\n"
5288 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
5289 " camcontrol identify [dev_id][generic args] [-v]\n"
5290 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
5291 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
5293 " camcontrol start [dev_id][generic args]\n"
5294 " camcontrol stop [dev_id][generic args]\n"
5295 " camcontrol load [dev_id][generic args]\n"
5296 " camcontrol eject [dev_id][generic args]\n"
5297 #endif /* MINIMALISTIC */
5298 " camcontrol rescan <all | bus[:target:lun]>\n"
5299 " camcontrol reset <all | bus[:target:lun]>\n"
5300 #ifndef MINIMALISTIC
5301 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
5302 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
5303 " [-P pagectl][-e | -b][-d]\n"
5304 " camcontrol cmd [dev_id][generic args]\n"
5305 " <-a cmd [args] | -c cmd [args]>\n"
5306 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
5307 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
5308 " <all|bus[:target[:lun]]|off>\n"
5309 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
5310 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
5311 " [-D <enable|disable>][-M mode][-O offset]\n"
5312 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
5313 " [-U][-W bus_width]\n"
5314 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
5315 " camcontrol idle [dev_id][generic args][-t time]\n"
5316 " camcontrol standby [dev_id][generic args][-t time]\n"
5317 " camcontrol sleep [dev_id][generic args]\n"
5318 " camcontrol security [dev_id][generic args]\n"
5319 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
5320 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
5321 " [-U <user|master>] [-y]\n"
5322 #endif /* MINIMALISTIC */
5323 " camcontrol help\n");
5326 #ifndef MINIMALISTIC
5328 "Specify one of the following options:\n"
5329 "devlist list all CAM devices\n"
5330 "periphlist list all CAM peripheral drivers attached to a device\n"
5331 "tur send a test unit ready to the named device\n"
5332 "inquiry send a SCSI inquiry command to the named device\n"
5333 "identify send a ATA identify command to the named device\n"
5334 "reportluns send a SCSI report luns command to the device\n"
5335 "readcap send a SCSI read capacity command to the device\n"
5336 "start send a Start Unit command to the device\n"
5337 "stop send a Stop Unit command to the device\n"
5338 "load send a Start Unit command to the device with the load bit set\n"
5339 "eject send a Stop Unit command to the device with the eject bit set\n"
5340 "rescan rescan all busses, the given bus, or bus:target:lun\n"
5341 "reset reset all busses, the given bus, or bus:target:lun\n"
5342 "defects read the defect list of the specified device\n"
5343 "modepage display or edit (-e) the given mode page\n"
5344 "cmd send the given scsi command, may need -i or -o as well\n"
5345 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
5346 "tags report or set the number of transaction slots for a device\n"
5347 "negotiate report or set device negotiation parameters\n"
5348 "format send the SCSI FORMAT UNIT command to the named device\n"
5349 "idle send the ATA IDLE command to the named device\n"
5350 "standby send the ATA STANDBY command to the named device\n"
5351 "sleep send the ATA SLEEP command to the named device\n"
5352 "security report or send ATA security commands to the named device\n"
5353 "help this message\n"
5354 "Device Identifiers:\n"
5355 "bus:target specify the bus and target, lun defaults to 0\n"
5356 "bus:target:lun specify the bus, target and lun\n"
5357 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
5358 "Generic arguments:\n"
5359 "-v be verbose, print out sense information\n"
5360 "-t timeout command timeout in seconds, overrides default timeout\n"
5361 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
5362 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
5363 "-E have the kernel attempt to perform SCSI error recovery\n"
5364 "-C count specify the SCSI command retry count (needs -E to work)\n"
5365 "modepage arguments:\n"
5366 "-l list all available mode pages\n"
5367 "-m page specify the mode page to view or edit\n"
5368 "-e edit the specified mode page\n"
5369 "-b force view to binary mode\n"
5370 "-d disable block descriptors for mode sense\n"
5371 "-P pgctl page control field 0-3\n"
5372 "defects arguments:\n"
5373 "-f format specify defect list format (block, bfi or phys)\n"
5374 "-G get the grown defect list\n"
5375 "-P get the permanant defect list\n"
5376 "inquiry arguments:\n"
5377 "-D get the standard inquiry data\n"
5378 "-S get the serial number\n"
5379 "-R get the transfer rate, etc.\n"
5380 "reportluns arguments:\n"
5381 "-c only report a count of available LUNs\n"
5382 "-l only print out luns, and not a count\n"
5383 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
5384 "readcap arguments\n"
5385 "-b only report the blocksize\n"
5386 "-h human readable device size, base 2\n"
5387 "-H human readable device size, base 10\n"
5388 "-N print the number of blocks instead of last block\n"
5389 "-q quiet, print numbers only\n"
5390 "-s only report the last block/device size\n"
5392 "-c cdb [args] specify the SCSI CDB\n"
5393 "-i len fmt specify input data and input data format\n"
5394 "-o len fmt [args] specify output data and output data fmt\n"
5395 "debug arguments:\n"
5396 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
5397 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
5398 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
5399 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
5401 "-N tags specify the number of tags to use for this device\n"
5402 "-q be quiet, don't report the number of tags\n"
5403 "-v report a number of tag-related parameters\n"
5404 "negotiate arguments:\n"
5405 "-a send a test unit ready after negotiation\n"
5406 "-c report/set current negotiation settings\n"
5407 "-D <arg> \"enable\" or \"disable\" disconnection\n"
5408 "-M mode set ATA mode\n"
5409 "-O offset set command delay offset\n"
5410 "-q be quiet, don't report anything\n"
5411 "-R syncrate synchronization rate in MHz\n"
5412 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
5413 "-U report/set user negotiation settings\n"
5414 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
5415 "-v also print a Path Inquiry CCB for the controller\n"
5416 "format arguments:\n"
5417 "-q be quiet, don't print status messages\n"
5418 "-r run in report only mode\n"
5419 "-w don't send immediate format command\n"
5420 "-y don't ask any questions\n"
5421 "idle/standby arguments:\n"
5422 "-t <arg> number of seconds before respective state.\n"
5423 "security arguments:\n"
5424 "-d pwd disable security using the given password for the selected\n"
5426 "-e pwd erase the device using the given pwd for the selected user\n"
5427 "-f freeze the security configuration of the specified device\n"
5428 "-h pwd enhanced erase the device using the given pwd for the\n"
5430 "-k pwd unlock the device using the given pwd for the selected\n"
5432 "-l <high|maximum> specifies which security level to set: high or maximum\n"
5433 "-q be quiet, do not print any status messages\n"
5434 "-s pwd password the device (enable security) using the given\n"
5435 " pwd for the selected user\n"
5436 "-T timeout overrides the timeout (seconds) used for erase operation\n"
5437 "-U <user|master> specifies which user to set: user or master\n"
5438 "-y don't ask any questions\n"
5440 #endif /* MINIMALISTIC */
5444 main(int argc, char **argv)
5447 char *device = NULL;
5449 struct cam_device *cam_dev = NULL;
5450 int timeout = 0, retry_count = 1;
5451 camcontrol_optret optreturn;
5453 const char *mainopt = "C:En:t:u:v";
5454 const char *subopt = NULL;
5455 char combinedopt[256];
5456 int error = 0, optstart = 2;
5458 #ifndef MINIMALISTIC
5459 int bus, target, lun;
5460 #endif /* MINIMALISTIC */
5462 cmdlist = CAM_CMD_NONE;
5463 arglist = CAM_ARG_NONE;
5471 * Get the base option.
5473 optreturn = getoption(argv[1], &cmdlist, &arglist, &subopt);
5475 if (optreturn == CC_OR_AMBIGUOUS) {
5476 warnx("ambiguous option %s", argv[1]);
5479 } else if (optreturn == CC_OR_NOT_FOUND) {
5480 warnx("option %s not found", argv[1]);
5486 * Ahh, getopt(3) is a pain.
5488 * This is a gross hack. There really aren't many other good
5489 * options (excuse the pun) for parsing options in a situation like
5490 * this. getopt is kinda braindead, so you end up having to run
5491 * through the options twice, and give each invocation of getopt
5492 * the option string for the other invocation.
5494 * You would think that you could just have two groups of options.
5495 * The first group would get parsed by the first invocation of
5496 * getopt, and the second group would get parsed by the second
5497 * invocation of getopt. It doesn't quite work out that way. When
5498 * the first invocation of getopt finishes, it leaves optind pointing
5499 * to the argument _after_ the first argument in the second group.
5500 * So when the second invocation of getopt comes around, it doesn't
5501 * recognize the first argument it gets and then bails out.
5503 * A nice alternative would be to have a flag for getopt that says
5504 * "just keep parsing arguments even when you encounter an unknown
5505 * argument", but there isn't one. So there's no real clean way to
5506 * easily parse two sets of arguments without having one invocation
5507 * of getopt know about the other.
5509 * Without this hack, the first invocation of getopt would work as
5510 * long as the generic arguments are first, but the second invocation
5511 * (in the subfunction) would fail in one of two ways. In the case
5512 * where you don't set optreset, it would fail because optind may be
5513 * pointing to the argument after the one it should be pointing at.
5514 * In the case where you do set optreset, and reset optind, it would
5515 * fail because getopt would run into the first set of options, which
5516 * it doesn't understand.
5518 * All of this would "sort of" work if you could somehow figure out
5519 * whether optind had been incremented one option too far. The
5520 * mechanics of that, however, are more daunting than just giving
5521 * both invocations all of the expect options for either invocation.
5523 * Needless to say, I wouldn't mind if someone invented a better
5524 * (non-GPL!) command line parsing interface than getopt. I
5525 * wouldn't mind if someone added more knobs to getopt to make it
5526 * work better. Who knows, I may talk myself into doing it someday,
5527 * if the standards weenies let me. As it is, it just leads to
5528 * hackery like this and causes people to avoid it in some cases.
5530 * KDM, September 8th, 1998
5533 sprintf(combinedopt, "%s%s", mainopt, subopt);
5535 sprintf(combinedopt, "%s", mainopt);
5538 * For these options we do not parse optional device arguments and
5539 * we do not open a passthrough device.
5541 if ((cmdlist == CAM_CMD_RESCAN)
5542 || (cmdlist == CAM_CMD_RESET)
5543 || (cmdlist == CAM_CMD_DEVTREE)
5544 || (cmdlist == CAM_CMD_USAGE)
5545 || (cmdlist == CAM_CMD_DEBUG))
5548 #ifndef MINIMALISTIC
5550 && (argc > 2 && argv[2][0] != '-')) {
5554 if (isdigit(argv[2][0])) {
5555 /* device specified as bus:target[:lun] */
5556 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
5558 errx(1, "numeric device specification must "
5559 "be either bus:target, or "
5561 /* default to 0 if lun was not specified */
5562 if ((arglist & CAM_ARG_LUN) == 0) {
5564 arglist |= CAM_ARG_LUN;
5568 if (cam_get_device(argv[2], name, sizeof name, &unit)
5570 errx(1, "%s", cam_errbuf);
5571 device = strdup(name);
5572 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
5576 #endif /* MINIMALISTIC */
5578 * Start getopt processing at argv[2/3], since we've already
5579 * accepted argv[1..2] as the command name, and as a possible
5585 * Now we run through the argument list looking for generic
5586 * options, and ignoring options that possibly belong to
5589 while ((c = getopt(argc, argv, combinedopt))!= -1){
5592 retry_count = strtol(optarg, NULL, 0);
5593 if (retry_count < 0)
5594 errx(1, "retry count %d is < 0",
5596 arglist |= CAM_ARG_RETRIES;
5599 arglist |= CAM_ARG_ERR_RECOVER;
5602 arglist |= CAM_ARG_DEVICE;
5604 while (isspace(*tstr) && (*tstr != '\0'))
5606 device = (char *)strdup(tstr);
5609 timeout = strtol(optarg, NULL, 0);
5611 errx(1, "invalid timeout %d", timeout);
5612 /* Convert the timeout from seconds to ms */
5614 arglist |= CAM_ARG_TIMEOUT;
5617 arglist |= CAM_ARG_UNIT;
5618 unit = strtol(optarg, NULL, 0);
5621 arglist |= CAM_ARG_VERBOSE;
5628 #ifndef MINIMALISTIC
5630 * For most commands we'll want to open the passthrough device
5631 * associated with the specified device. In the case of the rescan
5632 * commands, we don't use a passthrough device at all, just the
5633 * transport layer device.
5636 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
5637 && (((arglist & CAM_ARG_DEVICE) == 0)
5638 || ((arglist & CAM_ARG_UNIT) == 0))) {
5639 errx(1, "subcommand \"%s\" requires a valid device "
5640 "identifier", argv[1]);
5643 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
5644 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
5645 cam_open_spec_device(device,unit,O_RDWR,NULL)))
5647 errx(1,"%s", cam_errbuf);
5649 #endif /* MINIMALISTIC */
5652 * Reset optind to 2, and reset getopt, so these routines can parse
5653 * the arguments again.
5659 #ifndef MINIMALISTIC
5660 case CAM_CMD_DEVLIST:
5661 error = getdevlist(cam_dev);
5663 #endif /* MINIMALISTIC */
5664 case CAM_CMD_DEVTREE:
5665 error = getdevtree();
5667 #ifndef MINIMALISTIC
5669 error = testunitready(cam_dev, retry_count, timeout, 0);
5671 case CAM_CMD_INQUIRY:
5672 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
5673 retry_count, timeout);
5675 case CAM_CMD_IDENTIFY:
5676 error = ataidentify(cam_dev, retry_count, timeout);
5678 case CAM_CMD_STARTSTOP:
5679 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
5680 arglist & CAM_ARG_EJECT, retry_count,
5683 #endif /* MINIMALISTIC */
5684 case CAM_CMD_RESCAN:
5685 error = dorescan_or_reset(argc, argv, 1);
5688 error = dorescan_or_reset(argc, argv, 0);
5690 #ifndef MINIMALISTIC
5691 case CAM_CMD_READ_DEFECTS:
5692 error = readdefects(cam_dev, argc, argv, combinedopt,
5693 retry_count, timeout);
5695 case CAM_CMD_MODE_PAGE:
5696 modepage(cam_dev, argc, argv, combinedopt,
5697 retry_count, timeout);
5699 case CAM_CMD_SCSI_CMD:
5700 error = scsicmd(cam_dev, argc, argv, combinedopt,
5701 retry_count, timeout);
5704 error = camdebug(argc, argv, combinedopt);
5707 error = tagcontrol(cam_dev, argc, argv, combinedopt);
5710 error = ratecontrol(cam_dev, retry_count, timeout,
5711 argc, argv, combinedopt);
5713 case CAM_CMD_FORMAT:
5714 error = scsiformat(cam_dev, argc, argv,
5715 combinedopt, retry_count, timeout);
5717 case CAM_CMD_REPORTLUNS:
5718 error = scsireportluns(cam_dev, argc, argv,
5719 combinedopt, retry_count,
5722 case CAM_CMD_READCAP:
5723 error = scsireadcapacity(cam_dev, argc, argv,
5724 combinedopt, retry_count,
5728 case CAM_CMD_STANDBY:
5730 error = atapm(cam_dev, argc, argv,
5731 combinedopt, retry_count, timeout);
5733 case CAM_CMD_SECURITY:
5734 error = atasecurity(cam_dev, retry_count, timeout,
5735 argc, argv, combinedopt);
5737 #endif /* MINIMALISTIC */
5747 if (cam_dev != NULL)
5748 cam_close_device(cam_dev);