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>
50 #include <cam/cam_debug.h>
51 #include <cam/cam_ccb.h>
52 #include <cam/scsi/scsi_all.h>
53 #include <cam/scsi/scsi_da.h>
54 #include <cam/scsi/scsi_pass.h>
55 #include <cam/scsi/scsi_message.h>
56 #include <cam/scsi/smp_all.h>
57 #include <cam/ata/ata_all.h>
59 #include "camcontrol.h"
62 CAM_CMD_NONE = 0x00000000,
63 CAM_CMD_DEVLIST = 0x00000001,
64 CAM_CMD_TUR = 0x00000002,
65 CAM_CMD_INQUIRY = 0x00000003,
66 CAM_CMD_STARTSTOP = 0x00000004,
67 CAM_CMD_RESCAN = 0x00000005,
68 CAM_CMD_READ_DEFECTS = 0x00000006,
69 CAM_CMD_MODE_PAGE = 0x00000007,
70 CAM_CMD_SCSI_CMD = 0x00000008,
71 CAM_CMD_DEVTREE = 0x00000009,
72 CAM_CMD_USAGE = 0x0000000a,
73 CAM_CMD_DEBUG = 0x0000000b,
74 CAM_CMD_RESET = 0x0000000c,
75 CAM_CMD_FORMAT = 0x0000000d,
76 CAM_CMD_TAG = 0x0000000e,
77 CAM_CMD_RATE = 0x0000000f,
78 CAM_CMD_DETACH = 0x00000010,
79 CAM_CMD_REPORTLUNS = 0x00000011,
80 CAM_CMD_READCAP = 0x00000012,
81 CAM_CMD_IDENTIFY = 0x00000013,
82 CAM_CMD_IDLE = 0x00000014,
83 CAM_CMD_STANDBY = 0x00000015,
84 CAM_CMD_SLEEP = 0x00000016,
85 CAM_CMD_SMP_CMD = 0x00000017,
86 CAM_CMD_SMP_RG = 0x00000018,
87 CAM_CMD_SMP_PC = 0x00000019,
88 CAM_CMD_SMP_PHYLIST = 0x0000001a,
89 CAM_CMD_SMP_MANINFO = 0x0000001b,
90 CAM_CMD_DOWNLOAD_FW = 0x0000001c,
91 CAM_CMD_SECURITY = 0x0000001d
95 CAM_ARG_NONE = 0x00000000,
96 CAM_ARG_VERBOSE = 0x00000001,
97 CAM_ARG_DEVICE = 0x00000002,
98 CAM_ARG_BUS = 0x00000004,
99 CAM_ARG_TARGET = 0x00000008,
100 CAM_ARG_LUN = 0x00000010,
101 CAM_ARG_EJECT = 0x00000020,
102 CAM_ARG_UNIT = 0x00000040,
103 CAM_ARG_FORMAT_BLOCK = 0x00000080,
104 CAM_ARG_FORMAT_BFI = 0x00000100,
105 CAM_ARG_FORMAT_PHYS = 0x00000200,
106 CAM_ARG_PLIST = 0x00000400,
107 CAM_ARG_GLIST = 0x00000800,
108 CAM_ARG_GET_SERIAL = 0x00001000,
109 CAM_ARG_GET_STDINQ = 0x00002000,
110 CAM_ARG_GET_XFERRATE = 0x00004000,
111 CAM_ARG_INQ_MASK = 0x00007000,
112 CAM_ARG_MODE_EDIT = 0x00008000,
113 CAM_ARG_PAGE_CNTL = 0x00010000,
114 CAM_ARG_TIMEOUT = 0x00020000,
115 CAM_ARG_CMD_IN = 0x00040000,
116 CAM_ARG_CMD_OUT = 0x00080000,
117 CAM_ARG_DBD = 0x00100000,
118 CAM_ARG_ERR_RECOVER = 0x00200000,
119 CAM_ARG_RETRIES = 0x00400000,
120 CAM_ARG_START_UNIT = 0x00800000,
121 CAM_ARG_DEBUG_INFO = 0x01000000,
122 CAM_ARG_DEBUG_TRACE = 0x02000000,
123 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
124 CAM_ARG_DEBUG_CDB = 0x08000000,
125 CAM_ARG_DEBUG_XPT = 0x10000000,
126 CAM_ARG_DEBUG_PERIPH = 0x20000000,
127 CAM_ARG_DEBUG_PROBE = 0x40000000,
130 struct camcontrol_opts {
138 static const char scsicmd_opts[] = "a:c:dfi:o:r";
139 static const char readdefect_opts[] = "f:GP";
140 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
141 static const char smprg_opts[] = "l";
142 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
143 static const char smpphylist_opts[] = "lq";
147 static struct camcontrol_opts option_table[] = {
149 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
150 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
151 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
152 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
153 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
154 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
155 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
156 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
157 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
158 #endif /* MINIMALISTIC */
159 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
160 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
162 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
163 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
164 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
165 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
166 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
167 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
168 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
169 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
170 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
171 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
172 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
173 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
174 #endif /* MINIMALISTIC */
175 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, NULL},
177 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
178 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
179 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
180 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
181 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
182 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
183 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
184 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
185 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
186 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
187 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:ys"},
188 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
189 #endif /* MINIMALISTIC */
190 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
191 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
192 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
203 struct device_match_result dev_match;
205 struct periph_match_result *periph_matches;
206 struct scsi_vpd_device_id *device_id;
208 STAILQ_ENTRY(cam_devitem) links;
212 STAILQ_HEAD(, cam_devitem) dev_queue;
216 static cam_cmdmask cmdlist;
217 static cam_argmask arglist;
219 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
220 uint32_t *cmdnum, cam_argmask *argnum,
221 const char **subopt);
223 static int getdevlist(struct cam_device *device);
224 #endif /* MINIMALISTIC */
225 static int getdevtree(void);
227 static int testunitready(struct cam_device *device, int retry_count,
228 int timeout, int quiet);
229 static int scsistart(struct cam_device *device, int startstop, int loadeject,
230 int retry_count, int timeout);
231 static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
232 static int scsiserial(struct cam_device *device, int retry_count, int timeout);
233 static int camxferrate(struct cam_device *device);
234 #endif /* MINIMALISTIC */
235 static int parse_btl(char *tstr, int *bus, int *target, int *lun,
236 cam_argmask *arglst);
237 static int dorescan_or_reset(int argc, char **argv, int rescan);
238 static int rescan_or_reset_bus(int bus, int rescan);
239 static int scanlun_or_reset_dev(int bus, int target, int lun, int scan);
241 static int readdefects(struct cam_device *device, int argc, char **argv,
242 char *combinedopt, int retry_count, int timeout);
243 static void modepage(struct cam_device *device, int argc, char **argv,
244 char *combinedopt, int retry_count, int timeout);
245 static int scsicmd(struct cam_device *device, int argc, char **argv,
246 char *combinedopt, int retry_count, int timeout);
247 static int smpcmd(struct cam_device *device, int argc, char **argv,
248 char *combinedopt, int retry_count, int timeout);
249 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
250 char *combinedopt, int retry_count, int timeout);
251 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
252 char *combinedopt, int retry_count, int timeout);
253 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
254 char *combinedopt, int retry_count, int timeout);
255 static int getdevid(struct cam_devitem *item);
256 static int buildbusdevlist(struct cam_devlist *devlist);
257 static void freebusdevlist(struct cam_devlist *devlist);
258 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
260 static int smpphylist(struct cam_device *device, int argc, char **argv,
261 char *combinedopt, int retry_count, int timeout);
262 static int tagcontrol(struct cam_device *device, int argc, char **argv,
264 static void cts_print(struct cam_device *device,
265 struct ccb_trans_settings *cts);
266 static void cpi_print(struct ccb_pathinq *cpi);
267 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
268 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
269 static int get_print_cts(struct cam_device *device, int user_settings,
270 int quiet, struct ccb_trans_settings *cts);
271 static int ratecontrol(struct cam_device *device, int retry_count,
272 int timeout, int argc, char **argv, char *combinedopt);
273 static int scsiformat(struct cam_device *device, int argc, char **argv,
274 char *combinedopt, int retry_count, int timeout);
275 static int scsireportluns(struct cam_device *device, int argc, char **argv,
276 char *combinedopt, int retry_count, int timeout);
277 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
278 char *combinedopt, int retry_count, int timeout);
279 static int atapm(struct cam_device *device, int argc, char **argv,
280 char *combinedopt, int retry_count, int timeout);
281 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
282 int argc, char **argv, char *combinedopt);
284 #endif /* MINIMALISTIC */
286 #define min(a,b) (((a)<(b))?(a):(b))
289 #define max(a,b) (((a)>(b))?(a):(b))
293 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
294 cam_argmask *argnum, const char **subopt)
296 struct camcontrol_opts *opts;
299 for (opts = table; (opts != NULL) && (opts->optname != NULL);
301 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
302 *cmdnum = opts->cmdnum;
303 *argnum = opts->argnum;
304 *subopt = opts->subopt;
305 if (++num_matches > 1)
306 return(CC_OR_AMBIGUOUS);
313 return(CC_OR_NOT_FOUND);
318 getdevlist(struct cam_device *device)
324 ccb = cam_getccb(device);
326 ccb->ccb_h.func_code = XPT_GDEVLIST;
327 ccb->ccb_h.flags = CAM_DIR_NONE;
328 ccb->ccb_h.retry_count = 1;
330 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
331 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
332 if (cam_send_ccb(device, ccb) < 0) {
333 perror("error getting device list");
340 switch (ccb->cgdl.status) {
341 case CAM_GDEVLIST_MORE_DEVS:
342 strcpy(status, "MORE");
344 case CAM_GDEVLIST_LAST_DEVICE:
345 strcpy(status, "LAST");
347 case CAM_GDEVLIST_LIST_CHANGED:
348 strcpy(status, "CHANGED");
350 case CAM_GDEVLIST_ERROR:
351 strcpy(status, "ERROR");
356 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
357 ccb->cgdl.periph_name,
358 ccb->cgdl.unit_number,
359 ccb->cgdl.generation,
364 * If the list has changed, we need to start over from the
367 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
375 #endif /* MINIMALISTIC */
387 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
388 warn("couldn't open %s", XPT_DEVICE);
392 bzero(&ccb, sizeof(union ccb));
394 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
395 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
396 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
398 ccb.ccb_h.func_code = XPT_DEV_MATCH;
399 bufsize = sizeof(struct dev_match_result) * 100;
400 ccb.cdm.match_buf_len = bufsize;
401 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
402 if (ccb.cdm.matches == NULL) {
403 warnx("can't malloc memory for matches");
407 ccb.cdm.num_matches = 0;
410 * We fetch all nodes, since we display most of them in the default
411 * case, and all in the verbose case.
413 ccb.cdm.num_patterns = 0;
414 ccb.cdm.pattern_buf_len = 0;
417 * We do the ioctl multiple times if necessary, in case there are
418 * more than 100 nodes in the EDT.
421 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
422 warn("error sending CAMIOCOMMAND ioctl");
427 if ((ccb.ccb_h.status != CAM_REQ_CMP)
428 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
429 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
430 warnx("got CAM error %#x, CDM error %d\n",
431 ccb.ccb_h.status, ccb.cdm.status);
436 for (i = 0; i < ccb.cdm.num_matches; i++) {
437 switch (ccb.cdm.matches[i].type) {
438 case DEV_MATCH_BUS: {
439 struct bus_match_result *bus_result;
442 * Only print the bus information if the
443 * user turns on the verbose flag.
445 if ((arglist & CAM_ARG_VERBOSE) == 0)
449 &ccb.cdm.matches[i].result.bus_result;
452 fprintf(stdout, ")\n");
456 fprintf(stdout, "scbus%d on %s%d bus %d:\n",
458 bus_result->dev_name,
459 bus_result->unit_number,
463 case DEV_MATCH_DEVICE: {
464 struct device_match_result *dev_result;
465 char vendor[16], product[48], revision[16];
466 char fw[5], tmpstr[256];
469 &ccb.cdm.matches[i].result.device_result;
471 if ((dev_result->flags
472 & DEV_RESULT_UNCONFIGURED)
473 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
479 if (dev_result->protocol == PROTO_SCSI) {
480 cam_strvis(vendor, dev_result->inq_data.vendor,
481 sizeof(dev_result->inq_data.vendor),
484 dev_result->inq_data.product,
485 sizeof(dev_result->inq_data.product),
488 dev_result->inq_data.revision,
489 sizeof(dev_result->inq_data.revision),
491 sprintf(tmpstr, "<%s %s %s>", vendor, product,
493 } else if (dev_result->protocol == PROTO_ATA ||
494 dev_result->protocol == PROTO_SATAPM) {
496 dev_result->ident_data.model,
497 sizeof(dev_result->ident_data.model),
500 dev_result->ident_data.revision,
501 sizeof(dev_result->ident_data.revision),
503 sprintf(tmpstr, "<%s %s>", product,
505 } else if (dev_result->protocol == PROTO_SEMB) {
506 struct sep_identify_data *sid;
508 sid = (struct sep_identify_data *)
509 &dev_result->ident_data;
510 cam_strvis(vendor, sid->vendor_id,
511 sizeof(sid->vendor_id),
513 cam_strvis(product, sid->product_id,
514 sizeof(sid->product_id),
516 cam_strvis(revision, sid->product_rev,
517 sizeof(sid->product_rev),
519 cam_strvis(fw, sid->firmware_rev,
520 sizeof(sid->firmware_rev),
522 sprintf(tmpstr, "<%s %s %s %s>",
523 vendor, product, revision, fw);
525 sprintf(tmpstr, "<>");
528 fprintf(stdout, ")\n");
532 fprintf(stdout, "%-33s at scbus%d "
533 "target %d lun %d (",
536 dev_result->target_id,
537 dev_result->target_lun);
543 case DEV_MATCH_PERIPH: {
544 struct periph_match_result *periph_result;
547 &ccb.cdm.matches[i].result.periph_result;
549 if (skip_device != 0)
553 fprintf(stdout, ",");
555 fprintf(stdout, "%s%d",
556 periph_result->periph_name,
557 periph_result->unit_number);
563 fprintf(stdout, "unknown match type\n");
568 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
569 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
572 fprintf(stdout, ")\n");
581 testunitready(struct cam_device *device, int retry_count, int timeout,
587 ccb = cam_getccb(device);
589 scsi_test_unit_ready(&ccb->csio,
590 /* retries */ retry_count,
592 /* tag_action */ MSG_SIMPLE_Q_TAG,
593 /* sense_len */ SSD_FULL_SIZE,
594 /* timeout */ timeout ? timeout : 5000);
596 /* Disable freezing the device queue */
597 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
599 if (arglist & CAM_ARG_ERR_RECOVER)
600 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
602 if (cam_send_ccb(device, ccb) < 0) {
604 perror("error sending test unit ready");
606 if (arglist & CAM_ARG_VERBOSE) {
607 cam_error_print(device, ccb, CAM_ESF_ALL,
608 CAM_EPF_ALL, stderr);
615 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
617 fprintf(stdout, "Unit is ready\n");
620 fprintf(stdout, "Unit is not ready\n");
623 if (arglist & CAM_ARG_VERBOSE) {
624 cam_error_print(device, ccb, CAM_ESF_ALL,
625 CAM_EPF_ALL, stderr);
635 scsistart(struct cam_device *device, int startstop, int loadeject,
636 int retry_count, int timeout)
641 ccb = cam_getccb(device);
644 * If we're stopping, send an ordered tag so the drive in question
645 * will finish any previously queued writes before stopping. If
646 * the device isn't capable of tagged queueing, or if tagged
647 * queueing is turned off, the tag action is a no-op.
649 scsi_start_stop(&ccb->csio,
650 /* retries */ retry_count,
652 /* tag_action */ startstop ? MSG_SIMPLE_Q_TAG :
654 /* start/stop */ startstop,
655 /* load_eject */ loadeject,
657 /* sense_len */ SSD_FULL_SIZE,
658 /* timeout */ timeout ? timeout : 120000);
660 /* Disable freezing the device queue */
661 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
663 if (arglist & CAM_ARG_ERR_RECOVER)
664 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
666 if (cam_send_ccb(device, ccb) < 0) {
667 perror("error sending start unit");
669 if (arglist & CAM_ARG_VERBOSE) {
670 cam_error_print(device, ccb, CAM_ESF_ALL,
671 CAM_EPF_ALL, stderr);
678 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
680 fprintf(stdout, "Unit started successfully");
682 fprintf(stdout,", Media loaded\n");
684 fprintf(stdout,"\n");
686 fprintf(stdout, "Unit stopped successfully");
688 fprintf(stdout, ", Media ejected\n");
690 fprintf(stdout, "\n");
696 "Error received from start unit command\n");
699 "Error received from stop unit command\n");
701 if (arglist & CAM_ARG_VERBOSE) {
702 cam_error_print(device, ccb, CAM_ESF_ALL,
703 CAM_EPF_ALL, stderr);
713 scsidoinquiry(struct cam_device *device, int argc, char **argv,
714 char *combinedopt, int retry_count, int timeout)
719 while ((c = getopt(argc, argv, combinedopt)) != -1) {
722 arglist |= CAM_ARG_GET_STDINQ;
725 arglist |= CAM_ARG_GET_XFERRATE;
728 arglist |= CAM_ARG_GET_SERIAL;
736 * If the user didn't specify any inquiry options, he wants all of
739 if ((arglist & CAM_ARG_INQ_MASK) == 0)
740 arglist |= CAM_ARG_INQ_MASK;
742 if (arglist & CAM_ARG_GET_STDINQ)
743 error = scsiinquiry(device, retry_count, timeout);
748 if (arglist & CAM_ARG_GET_SERIAL)
749 scsiserial(device, retry_count, timeout);
754 if (arglist & CAM_ARG_GET_XFERRATE)
755 error = camxferrate(device);
761 scsiinquiry(struct cam_device *device, int retry_count, int timeout)
764 struct scsi_inquiry_data *inq_buf;
767 ccb = cam_getccb(device);
770 warnx("couldn't allocate CCB");
774 /* cam_getccb cleans up the header, caller has to zero the payload */
775 bzero(&(&ccb->ccb_h)[1],
776 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
778 inq_buf = (struct scsi_inquiry_data *)malloc(
779 sizeof(struct scsi_inquiry_data));
781 if (inq_buf == NULL) {
783 warnx("can't malloc memory for inquiry\n");
786 bzero(inq_buf, sizeof(*inq_buf));
789 * Note that although the size of the inquiry buffer is the full
790 * 256 bytes specified in the SCSI spec, we only tell the device
791 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
792 * two reasons for this:
794 * - The SCSI spec says that when a length field is only 1 byte,
795 * a value of 0 will be interpreted as 256. Therefore
796 * scsi_inquiry() will convert an inq_len (which is passed in as
797 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
798 * to 0. Evidently, very few devices meet the spec in that
799 * regard. Some devices, like many Seagate disks, take the 0 as
800 * 0, and don't return any data. One Pioneer DVD-R drive
801 * returns more data than the command asked for.
803 * So, since there are numerous devices that just don't work
804 * right with the full inquiry size, we don't send the full size.
806 * - The second reason not to use the full inquiry data length is
807 * that we don't need it here. The only reason we issue a
808 * standard inquiry is to get the vendor name, device name,
809 * and revision so scsi_print_inquiry() can print them.
811 * If, at some point in the future, more inquiry data is needed for
812 * some reason, this code should use a procedure similar to the
813 * probe code. i.e., issue a short inquiry, and determine from
814 * the additional length passed back from the device how much
815 * inquiry data the device supports. Once the amount the device
816 * supports is determined, issue an inquiry for that amount and no
821 scsi_inquiry(&ccb->csio,
822 /* retries */ retry_count,
824 /* tag_action */ MSG_SIMPLE_Q_TAG,
825 /* inq_buf */ (u_int8_t *)inq_buf,
826 /* inq_len */ SHORT_INQUIRY_LENGTH,
829 /* sense_len */ SSD_FULL_SIZE,
830 /* timeout */ timeout ? timeout : 5000);
832 /* Disable freezing the device queue */
833 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
835 if (arglist & CAM_ARG_ERR_RECOVER)
836 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
838 if (cam_send_ccb(device, ccb) < 0) {
839 perror("error sending SCSI inquiry");
841 if (arglist & CAM_ARG_VERBOSE) {
842 cam_error_print(device, ccb, CAM_ESF_ALL,
843 CAM_EPF_ALL, stderr);
850 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
853 if (arglist & CAM_ARG_VERBOSE) {
854 cam_error_print(device, ccb, CAM_ESF_ALL,
855 CAM_EPF_ALL, stderr);
866 fprintf(stdout, "%s%d: ", device->device_name,
867 device->dev_unit_num);
868 scsi_print_inquiry(inq_buf);
876 scsiserial(struct cam_device *device, int retry_count, int timeout)
879 struct scsi_vpd_unit_serial_number *serial_buf;
880 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
883 ccb = cam_getccb(device);
886 warnx("couldn't allocate CCB");
890 /* cam_getccb cleans up the header, caller has to zero the payload */
891 bzero(&(&ccb->ccb_h)[1],
892 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
894 serial_buf = (struct scsi_vpd_unit_serial_number *)
895 malloc(sizeof(*serial_buf));
897 if (serial_buf == NULL) {
899 warnx("can't malloc memory for serial number");
903 scsi_inquiry(&ccb->csio,
904 /*retries*/ retry_count,
906 /* tag_action */ MSG_SIMPLE_Q_TAG,
907 /* inq_buf */ (u_int8_t *)serial_buf,
908 /* inq_len */ sizeof(*serial_buf),
910 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
911 /* sense_len */ SSD_FULL_SIZE,
912 /* timeout */ timeout ? timeout : 5000);
914 /* Disable freezing the device queue */
915 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
917 if (arglist & CAM_ARG_ERR_RECOVER)
918 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
920 if (cam_send_ccb(device, ccb) < 0) {
921 warn("error getting serial number");
923 if (arglist & CAM_ARG_VERBOSE) {
924 cam_error_print(device, ccb, CAM_ESF_ALL,
925 CAM_EPF_ALL, stderr);
933 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
936 if (arglist & CAM_ARG_VERBOSE) {
937 cam_error_print(device, ccb, CAM_ESF_ALL,
938 CAM_EPF_ALL, stderr);
949 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
950 serial_num[serial_buf->length] = '\0';
952 if ((arglist & CAM_ARG_GET_STDINQ)
953 || (arglist & CAM_ARG_GET_XFERRATE))
954 fprintf(stdout, "%s%d: Serial Number ",
955 device->device_name, device->dev_unit_num);
957 fprintf(stdout, "%.60s\n", serial_num);
965 camxferrate(struct cam_device *device)
967 struct ccb_pathinq cpi;
974 if ((retval = get_cpi(device, &cpi)) != 0)
977 ccb = cam_getccb(device);
980 warnx("couldn't allocate CCB");
984 bzero(&(&ccb->ccb_h)[1],
985 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
987 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
988 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
990 if (((retval = cam_send_ccb(device, ccb)) < 0)
991 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
992 const char error_string[] = "error getting transfer settings";
999 if (arglist & CAM_ARG_VERBOSE)
1000 cam_error_print(device, ccb, CAM_ESF_ALL,
1001 CAM_EPF_ALL, stderr);
1005 goto xferrate_bailout;
1009 speed = cpi.base_transfer_speed;
1011 if (ccb->cts.transport == XPORT_SPI) {
1012 struct ccb_trans_settings_spi *spi =
1013 &ccb->cts.xport_specific.spi;
1015 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1016 freq = scsi_calc_syncsrate(spi->sync_period);
1019 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1020 speed *= (0x01 << spi->bus_width);
1022 } else if (ccb->cts.transport == XPORT_FC) {
1023 struct ccb_trans_settings_fc *fc =
1024 &ccb->cts.xport_specific.fc;
1026 if (fc->valid & CTS_FC_VALID_SPEED)
1027 speed = fc->bitrate;
1028 } else if (ccb->cts.transport == XPORT_SAS) {
1029 struct ccb_trans_settings_sas *sas =
1030 &ccb->cts.xport_specific.sas;
1032 if (sas->valid & CTS_SAS_VALID_SPEED)
1033 speed = sas->bitrate;
1034 } else if (ccb->cts.transport == XPORT_ATA) {
1035 struct ccb_trans_settings_pata *pata =
1036 &ccb->cts.xport_specific.ata;
1038 if (pata->valid & CTS_ATA_VALID_MODE)
1039 speed = ata_mode2speed(pata->mode);
1040 } else if (ccb->cts.transport == XPORT_SATA) {
1041 struct ccb_trans_settings_sata *sata =
1042 &ccb->cts.xport_specific.sata;
1044 if (sata->valid & CTS_SATA_VALID_REVISION)
1045 speed = ata_revision2speed(sata->revision);
1050 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1051 device->device_name, device->dev_unit_num,
1054 fprintf(stdout, "%s%d: %dKB/s transfers",
1055 device->device_name, device->dev_unit_num,
1059 if (ccb->cts.transport == XPORT_SPI) {
1060 struct ccb_trans_settings_spi *spi =
1061 &ccb->cts.xport_specific.spi;
1063 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1064 && (spi->sync_offset != 0))
1065 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1066 freq % 1000, spi->sync_offset);
1068 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1069 && (spi->bus_width > 0)) {
1070 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1071 && (spi->sync_offset != 0)) {
1072 fprintf(stdout, ", ");
1074 fprintf(stdout, " (");
1076 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1077 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1078 && (spi->sync_offset != 0)) {
1079 fprintf(stdout, ")");
1081 } else if (ccb->cts.transport == XPORT_ATA) {
1082 struct ccb_trans_settings_pata *pata =
1083 &ccb->cts.xport_specific.ata;
1086 if (pata->valid & CTS_ATA_VALID_MODE)
1087 printf("%s, ", ata_mode2string(pata->mode));
1088 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1089 printf("ATAPI %dbytes, ", pata->atapi);
1090 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1091 printf("PIO %dbytes", pata->bytecount);
1093 } else if (ccb->cts.transport == XPORT_SATA) {
1094 struct ccb_trans_settings_sata *sata =
1095 &ccb->cts.xport_specific.sata;
1098 if (sata->valid & CTS_SATA_VALID_REVISION)
1099 printf("SATA %d.x, ", sata->revision);
1102 if (sata->valid & CTS_SATA_VALID_MODE)
1103 printf("%s, ", ata_mode2string(sata->mode));
1104 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1105 printf("ATAPI %dbytes, ", sata->atapi);
1106 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1107 printf("PIO %dbytes", sata->bytecount);
1111 if (ccb->cts.protocol == PROTO_SCSI) {
1112 struct ccb_trans_settings_scsi *scsi =
1113 &ccb->cts.proto_specific.scsi;
1114 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1115 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1116 fprintf(stdout, ", Command Queueing Enabled");
1121 fprintf(stdout, "\n");
1131 atacapprint(struct ata_params *parm)
1133 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1134 ((u_int32_t)parm->lba_size_2 << 16);
1136 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1137 ((u_int64_t)parm->lba_size48_2 << 16) |
1138 ((u_int64_t)parm->lba_size48_3 << 32) |
1139 ((u_int64_t)parm->lba_size48_4 << 48);
1142 printf("protocol ");
1143 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1144 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1145 if (parm->satacapabilities & ATA_SATA_GEN3)
1146 printf(" SATA 3.x\n");
1147 else if (parm->satacapabilities & ATA_SATA_GEN2)
1148 printf(" SATA 2.x\n");
1149 else if (parm->satacapabilities & ATA_SATA_GEN1)
1150 printf(" SATA 1.x\n");
1156 printf("device model %.40s\n", parm->model);
1157 printf("firmware revision %.8s\n", parm->revision);
1158 printf("serial number %.20s\n", parm->serial);
1159 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1160 printf("WWN %04x%04x%04x%04x\n",
1161 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1163 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1164 printf("media serial number %.30s\n",
1165 parm->media_serial);
1168 printf("cylinders %d\n", parm->cylinders);
1169 printf("heads %d\n", parm->heads);
1170 printf("sectors/track %d\n", parm->sectors);
1171 printf("sector size logical %u, physical %lu, offset %lu\n",
1172 ata_logical_sector_size(parm),
1173 (unsigned long)ata_physical_sector_size(parm),
1174 (unsigned long)ata_logical_sector_offset(parm));
1176 if (parm->config == ATA_PROTO_CFA ||
1177 (parm->support.command2 & ATA_SUPPORT_CFA))
1178 printf("CFA supported\n");
1180 printf("LBA%ssupported ",
1181 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1183 printf("%d sectors\n", lbasize);
1187 printf("LBA48%ssupported ",
1188 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1190 printf("%ju sectors\n", (uintmax_t)lbasize48);
1194 printf("PIO supported PIO");
1195 switch (ata_max_pmode(parm)) {
1211 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1212 printf(" w/o IORDY");
1215 printf("DMA%ssupported ",
1216 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1217 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1218 if (parm->mwdmamodes & 0xff) {
1220 if (parm->mwdmamodes & 0x04)
1222 else if (parm->mwdmamodes & 0x02)
1224 else if (parm->mwdmamodes & 0x01)
1228 if ((parm->atavalid & ATA_FLAG_88) &&
1229 (parm->udmamodes & 0xff)) {
1231 if (parm->udmamodes & 0x40)
1233 else if (parm->udmamodes & 0x20)
1235 else if (parm->udmamodes & 0x10)
1237 else if (parm->udmamodes & 0x08)
1239 else if (parm->udmamodes & 0x04)
1241 else if (parm->udmamodes & 0x02)
1243 else if (parm->udmamodes & 0x01)
1250 if (parm->media_rotation_rate == 1) {
1251 printf("media RPM non-rotating\n");
1252 } else if (parm->media_rotation_rate >= 0x0401 &&
1253 parm->media_rotation_rate <= 0xFFFE) {
1254 printf("media RPM %d\n",
1255 parm->media_rotation_rate);
1259 "Support Enabled Value Vendor\n");
1260 printf("read ahead %s %s\n",
1261 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1262 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1263 printf("write cache %s %s\n",
1264 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1265 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1266 printf("flush cache %s %s\n",
1267 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1268 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1269 printf("overlap %s\n",
1270 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1271 printf("Tagged Command Queuing (TCQ) %s %s",
1272 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1273 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1274 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1275 printf(" %d tags\n",
1276 ATA_QUEUE_LEN(parm->queue) + 1);
1279 printf("Native Command Queuing (NCQ) ");
1280 if (parm->satacapabilities != 0xffff &&
1281 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1282 printf("yes %d tags\n",
1283 ATA_QUEUE_LEN(parm->queue) + 1);
1286 printf("SMART %s %s\n",
1287 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1288 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1289 printf("microcode download %s %s\n",
1290 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1291 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1292 printf("security %s %s\n",
1293 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1294 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1295 printf("power management %s %s\n",
1296 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1297 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1298 printf("advanced power management %s %s",
1299 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1300 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1301 if (parm->support.command2 & ATA_SUPPORT_APM) {
1302 printf(" %d/0x%02X\n",
1303 parm->apm_value, parm->apm_value);
1306 printf("automatic acoustic management %s %s",
1307 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1308 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1309 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1310 printf(" %d/0x%02X %d/0x%02X\n",
1311 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1312 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1313 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1314 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1317 printf("media status notification %s %s\n",
1318 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1319 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1320 printf("power-up in Standby %s %s\n",
1321 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1322 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1323 printf("write-read-verify %s %s",
1324 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1325 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1326 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1327 printf(" %d/0x%x\n",
1328 parm->wrv_mode, parm->wrv_mode);
1331 printf("unload %s %s\n",
1332 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1333 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1334 printf("free-fall %s %s\n",
1335 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1336 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1337 printf("Data Set Management (DSM/TRIM) ");
1338 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1340 printf("DSM - max 512byte blocks ");
1341 if (parm->max_dsm_blocks == 0x00)
1342 printf("yes not specified\n");
1345 parm->max_dsm_blocks);
1347 printf("DSM - deterministic read ");
1348 if (parm->support3 & ATA_SUPPORT_DRAT) {
1349 if (parm->support3 & ATA_SUPPORT_RZAT)
1350 printf("yes zeroed\n");
1352 printf("yes any value\n");
1362 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1364 struct ata_pass_16 *ata_pass_16;
1365 struct ata_cmd ata_cmd;
1367 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1368 ata_cmd.command = ata_pass_16->command;
1369 ata_cmd.control = ata_pass_16->control;
1370 ata_cmd.features = ata_pass_16->features;
1372 if (arglist & CAM_ARG_VERBOSE) {
1373 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1374 ata_op_string(&ata_cmd),
1375 ccb->csio.ccb_h.timeout);
1378 /* Disable freezing the device queue */
1379 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1381 if (arglist & CAM_ARG_ERR_RECOVER)
1382 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1384 if (cam_send_ccb(device, ccb) < 0) {
1385 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1386 warn("error sending ATA %s via pass_16",
1387 ata_op_string(&ata_cmd));
1390 if (arglist & CAM_ARG_VERBOSE) {
1391 cam_error_print(device, ccb, CAM_ESF_ALL,
1392 CAM_EPF_ALL, stderr);
1398 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1399 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1400 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1401 warnx("ATA %s via pass_16 failed",
1402 ata_op_string(&ata_cmd));
1404 if (arglist & CAM_ARG_VERBOSE) {
1405 cam_error_print(device, ccb, CAM_ESF_ALL,
1406 CAM_EPF_ALL, stderr);
1417 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1419 if (arglist & CAM_ARG_VERBOSE) {
1420 warnx("sending ATA %s with timeout of %u msecs",
1421 ata_op_string(&(ccb->ataio.cmd)),
1422 ccb->ataio.ccb_h.timeout);
1425 /* Disable freezing the device queue */
1426 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1428 if (arglist & CAM_ARG_ERR_RECOVER)
1429 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1431 if (cam_send_ccb(device, ccb) < 0) {
1432 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1433 warn("error sending ATA %s",
1434 ata_op_string(&(ccb->ataio.cmd)));
1437 if (arglist & CAM_ARG_VERBOSE) {
1438 cam_error_print(device, ccb, CAM_ESF_ALL,
1439 CAM_EPF_ALL, stderr);
1445 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1446 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1447 warnx("ATA %s failed: %d",
1448 ata_op_string(&(ccb->ataio.cmd)), quiet);
1451 if (arglist & CAM_ARG_VERBOSE) {
1452 cam_error_print(device, ccb, CAM_ESF_ALL,
1453 CAM_EPF_ALL, stderr);
1463 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1464 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1465 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1466 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1467 u_int16_t dxfer_len, int timeout, int quiet)
1469 if (data_ptr != NULL) {
1470 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1471 AP_FLAG_TLEN_SECT_CNT;
1472 if (flags & CAM_DIR_OUT)
1473 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1475 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1477 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1480 bzero(&(&ccb->ccb_h)[1],
1481 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1483 scsi_ata_pass_16(&ccb->csio,
1497 /*sense_len*/SSD_FULL_SIZE,
1500 return scsi_cam_pass_16_send(device, ccb, quiet);
1504 ata_try_pass_16(struct cam_device *device)
1506 struct ccb_pathinq cpi;
1508 if (get_cpi(device, &cpi) != 0) {
1509 warnx("couldn't get CPI");
1513 if (cpi.protocol == PROTO_SCSI) {
1514 /* possibly compatible with pass_16 */
1518 /* likely not compatible with pass_16 */
1523 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1524 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1525 u_int8_t command, u_int8_t features, u_int32_t lba,
1526 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1527 int timeout, int quiet)
1531 switch (ata_try_pass_16(device)) {
1535 /* Try using SCSI Passthrough */
1536 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1537 0, tag_action, command, features, lba,
1538 sector_count, data_ptr, dxfer_len,
1542 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1543 sizeof(struct ccb_hdr));
1544 cam_fill_ataio(&ccb->ataio,
1553 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1554 return ata_cam_send(device, ccb, quiet);
1558 dump_data(uint16_t *ptr, uint32_t len)
1562 for (i = 0; i < len / 2; i++) {
1564 printf(" %3d: ", i);
1565 printf("%04hx ", ptr[i]);
1574 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
1575 union ccb *ccb, struct ata_params** ident_bufp)
1577 struct ata_params *ident_buf;
1578 struct ccb_pathinq cpi;
1579 struct ccb_getdev cgd;
1582 u_int8_t command, retry_command;
1584 if (get_cpi(device, &cpi) != 0) {
1585 warnx("couldn't get CPI");
1589 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
1590 if (cpi.protocol == PROTO_ATA) {
1591 if (get_cgd(device, &cgd) != 0) {
1592 warnx("couldn't get CGD");
1596 command = (cgd.protocol == PROTO_ATA) ?
1597 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
1600 /* We don't know which for sure so try both */
1601 command = ATA_ATA_IDENTIFY;
1602 retry_command = ATA_ATAPI_IDENTIFY;
1605 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
1607 warnx("can't calloc memory for identify\n");
1611 error = ata_do_28bit_cmd(device,
1613 /*retries*/retry_count,
1614 /*flags*/CAM_DIR_IN,
1615 /*protocol*/AP_PROTO_PIO_IN,
1616 /*tag_action*/MSG_SIMPLE_Q_TAG,
1620 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
1621 /*data_ptr*/(u_int8_t *)ptr,
1622 /*dxfer_len*/sizeof(struct ata_params),
1623 /*timeout*/timeout ? timeout : 30 * 1000,
1627 if (retry_command == 0) {
1631 error = ata_do_28bit_cmd(device,
1633 /*retries*/retry_count,
1634 /*flags*/CAM_DIR_IN,
1635 /*protocol*/AP_PROTO_PIO_IN,
1636 /*tag_action*/MSG_SIMPLE_Q_TAG,
1637 /*command*/retry_command,
1640 /*sector_count*/(u_int8_t)
1641 sizeof(struct ata_params),
1642 /*data_ptr*/(u_int8_t *)ptr,
1643 /*dxfer_len*/sizeof(struct ata_params),
1644 /*timeout*/timeout ? timeout : 30 * 1000,
1654 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
1655 ptr[i] = le16toh(ptr[i]);
1660 if (arglist & CAM_ARG_VERBOSE) {
1661 fprintf(stdout, "%s%d: Raw identify data:\n",
1662 device->device_name, device->dev_unit_num);
1663 dump_data(ptr, sizeof(struct ata_params));
1666 /* check for invalid (all zero) response */
1668 warnx("Invalid identify response detected");
1673 ident_buf = (struct ata_params *)ptr;
1674 if (strncmp(ident_buf->model, "FX", 2) &&
1675 strncmp(ident_buf->model, "NEC", 3) &&
1676 strncmp(ident_buf->model, "Pioneer", 7) &&
1677 strncmp(ident_buf->model, "SHARP", 5)) {
1678 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
1679 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
1680 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
1681 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
1683 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
1684 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
1685 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
1686 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
1687 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
1688 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
1689 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
1690 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
1691 sizeof(ident_buf->media_serial));
1693 *ident_bufp = ident_buf;
1700 ataidentify(struct cam_device *device, int retry_count, int timeout)
1703 struct ata_params *ident_buf;
1705 if ((ccb = cam_getccb(device)) == NULL) {
1706 warnx("couldn't allocate CCB");
1710 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
1715 printf("%s%d: ", device->device_name, device->dev_unit_num);
1716 ata_print_ident(ident_buf);
1717 camxferrate(device);
1718 atacapprint(ident_buf);
1725 #endif /* MINIMALISTIC */
1728 #ifndef MINIMALISTIC
1730 ATA_SECURITY_ACTION_PRINT,
1731 ATA_SECURITY_ACTION_FREEZE,
1732 ATA_SECURITY_ACTION_UNLOCK,
1733 ATA_SECURITY_ACTION_DISABLE,
1734 ATA_SECURITY_ACTION_ERASE,
1735 ATA_SECURITY_ACTION_ERASE_ENHANCED,
1736 ATA_SECURITY_ACTION_SET_PASSWORD
1737 } atasecurity_action;
1740 atasecurity_print_time(u_int16_t tw)
1744 printf("unspecified");
1746 printf("> 508 min");
1748 printf("%i min", 2 * tw);
1752 atasecurity_erase_timeout_msecs(u_int16_t timeout)
1756 return 2 * 3600 * 1000; /* default: two hours */
1757 else if (timeout > 255)
1758 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
1760 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
1765 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
1769 bzero(&cmd, sizeof(cmd));
1770 cmd.command = command;
1771 printf("Issuing %s", ata_op_string(&cmd));
1774 char pass[sizeof(pwd->password)+1];
1776 /* pwd->password may not be null terminated */
1777 pass[sizeof(pwd->password)] = '\0';
1778 strncpy(pass, pwd->password, sizeof(pwd->password));
1779 printf(" password='%s', user='%s'",
1781 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
1784 if (command == ATA_SECURITY_SET_PASSWORD) {
1785 printf(", mode='%s'",
1786 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
1787 "maximum" : "high");
1795 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
1796 int retry_count, u_int32_t timeout, int quiet)
1800 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
1802 return ata_do_28bit_cmd(device,
1805 /*flags*/CAM_DIR_NONE,
1806 /*protocol*/AP_PROTO_NON_DATA,
1807 /*tag_action*/MSG_SIMPLE_Q_TAG,
1808 /*command*/ATA_SECURITY_FREEZE_LOCK,
1819 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
1820 int retry_count, u_int32_t timeout,
1821 struct ata_security_password *pwd, int quiet)
1825 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
1827 return ata_do_28bit_cmd(device,
1830 /*flags*/CAM_DIR_OUT,
1831 /*protocol*/AP_PROTO_PIO_OUT,
1832 /*tag_action*/MSG_SIMPLE_Q_TAG,
1833 /*command*/ATA_SECURITY_UNLOCK,
1837 /*data_ptr*/(u_int8_t *)pwd,
1838 /*dxfer_len*/sizeof(*pwd),
1844 atasecurity_disable(struct cam_device *device, union ccb *ccb,
1845 int retry_count, u_int32_t timeout,
1846 struct ata_security_password *pwd, int quiet)
1850 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
1851 return ata_do_28bit_cmd(device,
1854 /*flags*/CAM_DIR_OUT,
1855 /*protocol*/AP_PROTO_PIO_OUT,
1856 /*tag_action*/MSG_SIMPLE_Q_TAG,
1857 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
1861 /*data_ptr*/(u_int8_t *)pwd,
1862 /*dxfer_len*/sizeof(*pwd),
1869 atasecurity_erase_confirm(struct cam_device *device,
1870 struct ata_params* ident_buf)
1873 printf("\nYou are about to ERASE ALL DATA from the following"
1874 " device:\n%s%d,%s%d: ", device->device_name,
1875 device->dev_unit_num, device->given_dev_name,
1876 device->given_unit_number);
1877 ata_print_ident(ident_buf);
1881 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
1883 if (fgets(str, sizeof(str), stdin) != NULL) {
1884 if (strncasecmp(str, "yes", 3) == 0) {
1886 } else if (strncasecmp(str, "no", 2) == 0) {
1889 printf("Please answer \"yes\" or "
1900 atasecurity_erase(struct cam_device *device, union ccb *ccb,
1901 int retry_count, u_int32_t timeout,
1902 u_int32_t erase_timeout,
1903 struct ata_security_password *pwd, int quiet)
1908 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
1910 error = ata_do_28bit_cmd(device,
1913 /*flags*/CAM_DIR_NONE,
1914 /*protocol*/AP_PROTO_NON_DATA,
1915 /*tag_action*/MSG_SIMPLE_Q_TAG,
1916 /*command*/ATA_SECURITY_ERASE_PREPARE,
1929 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
1931 error = ata_do_28bit_cmd(device,
1934 /*flags*/CAM_DIR_OUT,
1935 /*protocol*/AP_PROTO_PIO_OUT,
1936 /*tag_action*/MSG_SIMPLE_Q_TAG,
1937 /*command*/ATA_SECURITY_ERASE_UNIT,
1941 /*data_ptr*/(u_int8_t *)pwd,
1942 /*dxfer_len*/sizeof(*pwd),
1943 /*timeout*/erase_timeout,
1946 if (error == 0 && quiet == 0)
1947 printf("\nErase Complete\n");
1953 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
1954 int retry_count, u_int32_t timeout,
1955 struct ata_security_password *pwd, int quiet)
1959 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
1961 return ata_do_28bit_cmd(device,
1964 /*flags*/CAM_DIR_OUT,
1965 /*protocol*/AP_PROTO_PIO_OUT,
1966 /*tag_action*/MSG_SIMPLE_Q_TAG,
1967 /*command*/ATA_SECURITY_SET_PASSWORD,
1971 /*data_ptr*/(u_int8_t *)pwd,
1972 /*dxfer_len*/sizeof(*pwd),
1978 atasecurity_print(struct ata_params *parm)
1981 printf("\nSecurity Option Value\n");
1982 if (arglist & CAM_ARG_VERBOSE) {
1983 printf("status %04x\n",
1984 parm->security_status);
1986 printf("supported %s\n",
1987 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
1988 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
1990 printf("enabled %s\n",
1991 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
1992 printf("drive locked %s\n",
1993 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
1994 printf("security config frozen %s\n",
1995 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
1996 printf("count expired %s\n",
1997 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
1998 printf("security level %s\n",
1999 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2000 printf("enhanced erase supported %s\n",
2001 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2002 printf("erase time ");
2003 atasecurity_print_time(parm->erase_time);
2005 printf("enhanced erase time ");
2006 atasecurity_print_time(parm->enhanced_erase_time);
2008 printf("master password rev %04x%s\n",
2009 parm->master_passwd_revision,
2010 parm->master_passwd_revision == 0x0000 ||
2011 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2015 * Validates and copies the password in optarg to the passed buffer.
2016 * If the password in optarg is the same length as the buffer then
2017 * the data will still be copied but no null termination will occur.
2020 ata_getpwd(u_int8_t *passwd, int max, char opt)
2024 len = strlen(optarg);
2026 warnx("-%c password is too long", opt);
2028 } else if (len == 0) {
2029 warnx("-%c password is missing", opt);
2031 } else if (optarg[0] == '-'){
2032 warnx("-%c password starts with '-' (generic arg?)", opt);
2034 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2035 warnx("-%c password conflicts with existing password from -%c",
2040 /* Callers pass in a buffer which does NOT need to be terminated */
2041 strncpy(passwd, optarg, max);
2048 atasecurity(struct cam_device *device, int retry_count, int timeout,
2049 int argc, char **argv, char *combinedopt)
2052 struct ata_params *ident_buf;
2053 int error, confirm, quiet, c, action, actions, setpwd;
2054 int security_enabled, erase_timeout, pwdsize;
2055 struct ata_security_password pwd;
2063 memset(&pwd, 0, sizeof(pwd));
2065 /* default action is to print security information */
2066 action = ATA_SECURITY_ACTION_PRINT;
2068 /* user is master by default as its safer that way */
2069 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2070 pwdsize = sizeof(pwd.password);
2072 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2075 action = ATA_SECURITY_ACTION_FREEZE;
2080 if (strcasecmp(optarg, "user") == 0) {
2081 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2082 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2083 } else if (strcasecmp(optarg, "master") != 0) {
2084 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2085 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2087 warnx("-U argument '%s' is invalid (must be "
2088 "'user' or 'master')", optarg);
2094 if (strcasecmp(optarg, "high") == 0) {
2095 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2096 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2097 } else if (strcasecmp(optarg, "maximum") == 0) {
2098 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2099 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2101 warnx("-l argument '%s' is unknown (must be "
2102 "'high' or 'maximum')", optarg);
2108 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2110 action = ATA_SECURITY_ACTION_UNLOCK;
2115 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2117 action = ATA_SECURITY_ACTION_DISABLE;
2122 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2124 action = ATA_SECURITY_ACTION_ERASE;
2129 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2131 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2132 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2137 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2140 if (action == ATA_SECURITY_ACTION_PRINT)
2141 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2143 * Don't increment action as this can be combined
2144 * with other actions.
2157 erase_timeout = atoi(optarg) * 1000;
2163 warnx("too many security actions specified");
2167 if ((ccb = cam_getccb(device)) == NULL) {
2168 warnx("couldn't allocate CCB");
2172 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2179 printf("%s%d: ", device->device_name, device->dev_unit_num);
2180 ata_print_ident(ident_buf);
2181 camxferrate(device);
2184 if (action == ATA_SECURITY_ACTION_PRINT) {
2185 atasecurity_print(ident_buf);
2191 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2192 warnx("Security not supported");
2198 /* default timeout 15 seconds the same as linux hdparm */
2199 timeout = timeout ? timeout : 15 * 1000;
2201 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2203 /* first set the password if requested */
2205 /* confirm we can erase before setting the password if erasing */
2207 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2208 action == ATA_SECURITY_ACTION_ERASE) &&
2209 atasecurity_erase_confirm(device, ident_buf) == 0) {
2215 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2216 pwd.revision = ident_buf->master_passwd_revision;
2217 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2218 --pwd.revision == 0) {
2219 pwd.revision = 0xfffe;
2222 error = atasecurity_set_password(device, ccb, retry_count,
2223 timeout, &pwd, quiet);
2229 security_enabled = 1;
2233 case ATA_SECURITY_ACTION_FREEZE:
2234 error = atasecurity_freeze(device, ccb, retry_count,
2238 case ATA_SECURITY_ACTION_UNLOCK:
2239 if (security_enabled) {
2240 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2241 error = atasecurity_unlock(device, ccb,
2242 retry_count, timeout, &pwd, quiet);
2244 warnx("Can't unlock, drive is not locked");
2248 warnx("Can't unlock, security is disabled");
2253 case ATA_SECURITY_ACTION_DISABLE:
2254 if (security_enabled) {
2255 /* First unlock the drive if its locked */
2256 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2257 error = atasecurity_unlock(device, ccb,
2265 error = atasecurity_disable(device,
2273 warnx("Can't disable security (already disabled)");
2278 case ATA_SECURITY_ACTION_ERASE:
2279 if (security_enabled) {
2280 if (erase_timeout == 0) {
2281 erase_timeout = atasecurity_erase_timeout_msecs(
2282 ident_buf->erase_time);
2285 error = atasecurity_erase(device, ccb, retry_count,
2286 timeout, erase_timeout, &pwd,
2289 warnx("Can't secure erase (security is disabled)");
2294 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
2295 if (security_enabled) {
2296 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
2297 if (erase_timeout == 0) {
2299 atasecurity_erase_timeout_msecs(
2300 ident_buf->enhanced_erase_time);
2303 error = atasecurity_erase(device, ccb,
2304 retry_count, timeout,
2305 erase_timeout, &pwd,
2308 warnx("Enhanced erase is not supported");
2312 warnx("Can't secure erase (enhanced), "
2313 "(security is disabled)");
2324 #endif /* MINIMALISTIC */
2327 * Parse out a bus, or a bus, target and lun in the following
2333 * Returns the number of parsed components, or 0.
2336 parse_btl(char *tstr, int *bus, int *target, int *lun, cam_argmask *arglst)
2341 while (isspace(*tstr) && (*tstr != '\0'))
2344 tmpstr = (char *)strtok(tstr, ":");
2345 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
2346 *bus = strtol(tmpstr, NULL, 0);
2347 *arglst |= CAM_ARG_BUS;
2349 tmpstr = (char *)strtok(NULL, ":");
2350 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
2351 *target = strtol(tmpstr, NULL, 0);
2352 *arglst |= CAM_ARG_TARGET;
2354 tmpstr = (char *)strtok(NULL, ":");
2355 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
2356 *lun = strtol(tmpstr, NULL, 0);
2357 *arglst |= CAM_ARG_LUN;
2367 dorescan_or_reset(int argc, char **argv, int rescan)
2369 static const char must[] =
2370 "you must specify \"all\", a bus, or a bus:target:lun to %s";
2372 int bus = -1, target = -1, lun = -1;
2376 warnx(must, rescan? "rescan" : "reset");
2380 tstr = argv[optind];
2381 while (isspace(*tstr) && (*tstr != '\0'))
2383 if (strncasecmp(tstr, "all", strlen("all")) == 0)
2384 arglist |= CAM_ARG_BUS;
2386 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
2387 if (rv != 1 && rv != 3) {
2388 warnx(must, rescan? "rescan" : "reset");
2393 if ((arglist & CAM_ARG_BUS)
2394 && (arglist & CAM_ARG_TARGET)
2395 && (arglist & CAM_ARG_LUN))
2396 error = scanlun_or_reset_dev(bus, target, lun, rescan);
2398 error = rescan_or_reset_bus(bus, rescan);
2404 rescan_or_reset_bus(int bus, int rescan)
2406 union ccb ccb, matchccb;
2412 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
2413 warnx("error opening transport layer device %s", XPT_DEVICE);
2414 warn("%s", XPT_DEVICE);
2419 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
2420 ccb.ccb_h.path_id = bus;
2421 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
2422 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
2423 ccb.crcn.flags = CAM_FLAG_NONE;
2425 /* run this at a low priority */
2426 ccb.ccb_h.pinfo.priority = 5;
2428 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
2429 warn("CAMIOCOMMAND ioctl failed");
2434 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
2435 fprintf(stdout, "%s of bus %d was successful\n",
2436 rescan ? "Re-scan" : "Reset", bus);
2438 fprintf(stdout, "%s of bus %d returned error %#x\n",
2439 rescan ? "Re-scan" : "Reset", bus,
2440 ccb.ccb_h.status & CAM_STATUS_MASK);
2451 * The right way to handle this is to modify the xpt so that it can
2452 * handle a wildcarded bus in a rescan or reset CCB. At the moment
2453 * that isn't implemented, so instead we enumerate the busses and
2454 * send the rescan or reset to those busses in the case where the
2455 * given bus is -1 (wildcard). We don't send a rescan or reset
2456 * to the xpt bus; sending a rescan to the xpt bus is effectively a
2457 * no-op, sending a rescan to the xpt bus would result in a status of
2460 bzero(&(&matchccb.ccb_h)[1],
2461 sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr));
2462 matchccb.ccb_h.func_code = XPT_DEV_MATCH;
2463 matchccb.ccb_h.path_id = CAM_BUS_WILDCARD;
2464 bufsize = sizeof(struct dev_match_result) * 20;
2465 matchccb.cdm.match_buf_len = bufsize;
2466 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
2467 if (matchccb.cdm.matches == NULL) {
2468 warnx("can't malloc memory for matches");
2472 matchccb.cdm.num_matches = 0;
2474 matchccb.cdm.num_patterns = 1;
2475 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
2477 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
2478 matchccb.cdm.pattern_buf_len);
2479 if (matchccb.cdm.patterns == NULL) {
2480 warnx("can't malloc memory for patterns");
2484 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
2485 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
2490 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
2491 warn("CAMIOCOMMAND ioctl failed");
2496 if ((matchccb.ccb_h.status != CAM_REQ_CMP)
2497 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
2498 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
2499 warnx("got CAM error %#x, CDM error %d\n",
2500 matchccb.ccb_h.status, matchccb.cdm.status);
2505 for (i = 0; i < matchccb.cdm.num_matches; i++) {
2506 struct bus_match_result *bus_result;
2508 /* This shouldn't happen. */
2509 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
2512 bus_result = &matchccb.cdm.matches[i].result.bus_result;
2515 * We don't want to rescan or reset the xpt bus.
2518 if ((int)bus_result->path_id == -1)
2521 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
2523 ccb.ccb_h.path_id = bus_result->path_id;
2524 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
2525 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
2526 ccb.crcn.flags = CAM_FLAG_NONE;
2528 /* run this at a low priority */
2529 ccb.ccb_h.pinfo.priority = 5;
2531 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
2532 warn("CAMIOCOMMAND ioctl failed");
2537 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
2538 fprintf(stdout, "%s of bus %d was successful\n",
2539 rescan? "Re-scan" : "Reset",
2540 bus_result->path_id);
2543 * Don't bail out just yet, maybe the other
2544 * rescan or reset commands will complete
2547 fprintf(stderr, "%s of bus %d returned error "
2548 "%#x\n", rescan? "Re-scan" : "Reset",
2549 bus_result->path_id,
2550 ccb.ccb_h.status & CAM_STATUS_MASK);
2554 } while ((matchccb.ccb_h.status == CAM_REQ_CMP)
2555 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
2562 if (matchccb.cdm.patterns != NULL)
2563 free(matchccb.cdm.patterns);
2564 if (matchccb.cdm.matches != NULL)
2565 free(matchccb.cdm.matches);
2571 scanlun_or_reset_dev(int bus, int target, int lun, int scan)
2574 struct cam_device *device;
2580 warnx("invalid bus number %d", bus);
2585 warnx("invalid target number %d", target);
2590 warnx("invalid lun number %d", lun);
2596 bzero(&ccb, sizeof(union ccb));
2599 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
2600 warnx("error opening transport layer device %s\n",
2602 warn("%s", XPT_DEVICE);
2606 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
2607 if (device == NULL) {
2608 warnx("%s", cam_errbuf);
2613 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
2614 ccb.ccb_h.path_id = bus;
2615 ccb.ccb_h.target_id = target;
2616 ccb.ccb_h.target_lun = lun;
2617 ccb.ccb_h.timeout = 5000;
2618 ccb.crcn.flags = CAM_FLAG_NONE;
2620 /* run this at a low priority */
2621 ccb.ccb_h.pinfo.priority = 5;
2624 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
2625 warn("CAMIOCOMMAND ioctl failed");
2630 if (cam_send_ccb(device, &ccb) < 0) {
2631 warn("error sending XPT_RESET_DEV CCB");
2632 cam_close_device(device);
2640 cam_close_device(device);
2643 * An error code of CAM_BDR_SENT is normal for a BDR request.
2645 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
2647 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
2648 fprintf(stdout, "%s of %d:%d:%d was successful\n",
2649 scan? "Re-scan" : "Reset", bus, target, lun);
2652 fprintf(stdout, "%s of %d:%d:%d returned error %#x\n",
2653 scan? "Re-scan" : "Reset", bus, target, lun,
2654 ccb.ccb_h.status & CAM_STATUS_MASK);
2659 #ifndef MINIMALISTIC
2661 readdefects(struct cam_device *device, int argc, char **argv,
2662 char *combinedopt, int retry_count, int timeout)
2664 union ccb *ccb = NULL;
2665 struct scsi_read_defect_data_10 *rdd_cdb;
2666 u_int8_t *defect_list = NULL;
2667 u_int32_t max_dlist_length = SRDD10_MAX_LENGTH, dlist_length = 0;
2668 u_int32_t returned_length = 0;
2669 u_int32_t num_returned = 0;
2670 u_int8_t returned_format;
2673 int lists_specified;
2676 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2682 while (isspace(*tstr) && (*tstr != '\0'))
2684 if (strcmp(tstr, "block") == 0)
2685 arglist |= CAM_ARG_FORMAT_BLOCK;
2686 else if (strcmp(tstr, "bfi") == 0)
2687 arglist |= CAM_ARG_FORMAT_BFI;
2688 else if (strcmp(tstr, "phys") == 0)
2689 arglist |= CAM_ARG_FORMAT_PHYS;
2692 warnx("invalid defect format %s", tstr);
2693 goto defect_bailout;
2698 arglist |= CAM_ARG_GLIST;
2701 arglist |= CAM_ARG_PLIST;
2708 ccb = cam_getccb(device);
2711 * Eventually we should probably support the 12 byte READ DEFECT
2712 * DATA command. It supports a longer parameter list, which may be
2713 * necessary on newer drives with lots of defects. According to
2714 * the SBC-3 spec, drives are supposed to return an illegal request
2715 * if they have more defect data than will fit in 64K.
2717 defect_list = malloc(max_dlist_length);
2718 if (defect_list == NULL) {
2719 warnx("can't malloc memory for defect list");
2721 goto defect_bailout;
2725 * We start off asking for just the header to determine how much
2726 * defect data is available. Some Hitachi drives return an error
2727 * if you ask for more data than the drive has. Once we know the
2728 * length, we retry the command with the returned length.
2730 dlist_length = sizeof(struct scsi_read_defect_data_hdr_10);
2732 rdd_cdb =(struct scsi_read_defect_data_10 *)&ccb->csio.cdb_io.cdb_bytes;
2736 lists_specified = 0;
2739 * cam_getccb() zeros the CCB header only. So we need to zero the
2740 * payload portion of the ccb.
2742 bzero(&(&ccb->ccb_h)[1],
2743 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
2745 cam_fill_csio(&ccb->csio,
2746 /*retries*/ retry_count,
2748 /*flags*/ CAM_DIR_IN | ((arglist & CAM_ARG_ERR_RECOVER) ?
2749 CAM_PASS_ERR_RECOVER : 0),
2750 /*tag_action*/ MSG_SIMPLE_Q_TAG,
2751 /*data_ptr*/ defect_list,
2752 /*dxfer_len*/ dlist_length,
2753 /*sense_len*/ SSD_FULL_SIZE,
2754 /*cdb_len*/ sizeof(struct scsi_read_defect_data_10),
2755 /*timeout*/ timeout ? timeout : 5000);
2757 rdd_cdb->opcode = READ_DEFECT_DATA_10;
2758 if (arglist & CAM_ARG_FORMAT_BLOCK)
2759 rdd_cdb->format = SRDD10_BLOCK_FORMAT;
2760 else if (arglist & CAM_ARG_FORMAT_BFI)
2761 rdd_cdb->format = SRDD10_BYTES_FROM_INDEX_FORMAT;
2762 else if (arglist & CAM_ARG_FORMAT_PHYS)
2763 rdd_cdb->format = SRDD10_PHYSICAL_SECTOR_FORMAT;
2766 warnx("no defect list format specified");
2767 goto defect_bailout;
2769 if (arglist & CAM_ARG_PLIST) {
2770 rdd_cdb->format |= SRDD10_PLIST;
2774 if (arglist & CAM_ARG_GLIST) {
2775 rdd_cdb->format |= SRDD10_GLIST;
2779 scsi_ulto2b(dlist_length, rdd_cdb->alloc_length);
2781 /* Disable freezing the device queue */
2782 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
2784 if (cam_send_ccb(device, ccb) < 0) {
2785 perror("error reading defect list");
2787 if (arglist & CAM_ARG_VERBOSE) {
2788 cam_error_print(device, ccb, CAM_ESF_ALL,
2789 CAM_EPF_ALL, stderr);
2793 goto defect_bailout;
2796 returned_length = scsi_2btoul(((struct
2797 scsi_read_defect_data_hdr_10 *)defect_list)->length);
2799 if (get_length != 0) {
2802 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
2803 CAM_SCSI_STATUS_ERROR) {
2804 struct scsi_sense_data *sense;
2805 int error_code, sense_key, asc, ascq;
2807 sense = &ccb->csio.sense_data;
2808 scsi_extract_sense_len(sense, ccb->csio.sense_len -
2809 ccb->csio.sense_resid, &error_code, &sense_key,
2810 &asc, &ascq, /*show_errors*/ 1);
2813 * If the drive is reporting that it just doesn't
2814 * support the defect list format, go ahead and use
2815 * the length it reported. Otherwise, the length
2816 * may not be valid, so use the maximum.
2818 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
2819 && (asc == 0x1c) && (ascq == 0x00)
2820 && (returned_length > 0)) {
2821 dlist_length = returned_length +
2822 sizeof(struct scsi_read_defect_data_hdr_10);
2823 dlist_length = min(dlist_length,
2826 dlist_length = max_dlist_length;
2827 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
2830 warnx("Error reading defect header");
2831 if (arglist & CAM_ARG_VERBOSE)
2832 cam_error_print(device, ccb, CAM_ESF_ALL,
2833 CAM_EPF_ALL, stderr);
2834 goto defect_bailout;
2836 dlist_length = returned_length +
2837 sizeof(struct scsi_read_defect_data_hdr_10);
2838 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
2844 returned_format = ((struct scsi_read_defect_data_hdr_10 *)
2845 defect_list)->format;
2847 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
2848 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
2849 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
2850 struct scsi_sense_data *sense;
2851 int error_code, sense_key, asc, ascq;
2853 sense = &ccb->csio.sense_data;
2854 scsi_extract_sense_len(sense, ccb->csio.sense_len -
2855 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
2856 &ascq, /*show_errors*/ 1);
2859 * According to the SCSI spec, if the disk doesn't support
2860 * the requested format, it will generally return a sense
2861 * key of RECOVERED ERROR, and an additional sense code
2862 * of "DEFECT LIST NOT FOUND". So, we check for that, and
2863 * also check to make sure that the returned length is
2864 * greater than 0, and then print out whatever format the
2867 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
2868 && (asc == 0x1c) && (ascq == 0x00)
2869 && (returned_length > 0)) {
2870 warnx("requested defect format not available");
2871 switch(returned_format & SRDDH10_DLIST_FORMAT_MASK) {
2872 case SRDD10_BLOCK_FORMAT:
2873 warnx("Device returned block format");
2875 case SRDD10_BYTES_FROM_INDEX_FORMAT:
2876 warnx("Device returned bytes from index"
2879 case SRDD10_PHYSICAL_SECTOR_FORMAT:
2880 warnx("Device returned physical sector format");
2884 warnx("Device returned unknown defect"
2885 " data format %#x", returned_format);
2886 goto defect_bailout;
2887 break; /* NOTREACHED */
2891 warnx("Error returned from read defect data command");
2892 if (arglist & CAM_ARG_VERBOSE)
2893 cam_error_print(device, ccb, CAM_ESF_ALL,
2894 CAM_EPF_ALL, stderr);
2895 goto defect_bailout;
2897 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2899 warnx("Error returned from read defect data command");
2900 if (arglist & CAM_ARG_VERBOSE)
2901 cam_error_print(device, ccb, CAM_ESF_ALL,
2902 CAM_EPF_ALL, stderr);
2903 goto defect_bailout;
2907 * XXX KDM I should probably clean up the printout format for the
2910 switch (returned_format & SRDDH10_DLIST_FORMAT_MASK){
2911 case SRDDH10_PHYSICAL_SECTOR_FORMAT:
2913 struct scsi_defect_desc_phys_sector *dlist;
2915 dlist = (struct scsi_defect_desc_phys_sector *)
2917 sizeof(struct scsi_read_defect_data_hdr_10));
2919 num_returned = returned_length /
2920 sizeof(struct scsi_defect_desc_phys_sector);
2922 fprintf(stderr, "Got %d defect", num_returned);
2924 if ((lists_specified == 0) || (num_returned == 0)) {
2925 fprintf(stderr, "s.\n");
2927 } else if (num_returned == 1)
2928 fprintf(stderr, ":\n");
2930 fprintf(stderr, "s:\n");
2932 for (i = 0; i < num_returned; i++) {
2933 fprintf(stdout, "%d:%d:%d\n",
2934 scsi_3btoul(dlist[i].cylinder),
2936 scsi_4btoul(dlist[i].sector));
2940 case SRDDH10_BYTES_FROM_INDEX_FORMAT:
2942 struct scsi_defect_desc_bytes_from_index *dlist;
2944 dlist = (struct scsi_defect_desc_bytes_from_index *)
2946 sizeof(struct scsi_read_defect_data_hdr_10));
2948 num_returned = returned_length /
2949 sizeof(struct scsi_defect_desc_bytes_from_index);
2951 fprintf(stderr, "Got %d defect", num_returned);
2953 if ((lists_specified == 0) || (num_returned == 0)) {
2954 fprintf(stderr, "s.\n");
2956 } else if (num_returned == 1)
2957 fprintf(stderr, ":\n");
2959 fprintf(stderr, "s:\n");
2961 for (i = 0; i < num_returned; i++) {
2962 fprintf(stdout, "%d:%d:%d\n",
2963 scsi_3btoul(dlist[i].cylinder),
2965 scsi_4btoul(dlist[i].bytes_from_index));
2969 case SRDDH10_BLOCK_FORMAT:
2971 struct scsi_defect_desc_block *dlist;
2973 dlist = (struct scsi_defect_desc_block *)(defect_list +
2974 sizeof(struct scsi_read_defect_data_hdr_10));
2976 num_returned = returned_length /
2977 sizeof(struct scsi_defect_desc_block);
2979 fprintf(stderr, "Got %d defect", num_returned);
2981 if ((lists_specified == 0) || (num_returned == 0)) {
2982 fprintf(stderr, "s.\n");
2984 } else if (num_returned == 1)
2985 fprintf(stderr, ":\n");
2987 fprintf(stderr, "s:\n");
2989 for (i = 0; i < num_returned; i++)
2990 fprintf(stdout, "%u\n",
2991 scsi_4btoul(dlist[i].address));
2995 fprintf(stderr, "Unknown defect format %d\n",
2996 returned_format & SRDDH10_DLIST_FORMAT_MASK);
3002 if (defect_list != NULL)
3010 #endif /* MINIMALISTIC */
3014 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
3018 ccb = cam_getccb(device);
3024 #ifndef MINIMALISTIC
3026 mode_sense(struct cam_device *device, int mode_page, int page_control,
3027 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen)
3032 ccb = cam_getccb(device);
3035 errx(1, "mode_sense: couldn't allocate CCB");
3037 bzero(&(&ccb->ccb_h)[1],
3038 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3040 scsi_mode_sense(&ccb->csio,
3041 /* retries */ retry_count,
3043 /* tag_action */ MSG_SIMPLE_Q_TAG,
3045 /* page_code */ page_control << 6,
3046 /* page */ mode_page,
3047 /* param_buf */ data,
3048 /* param_len */ datalen,
3049 /* sense_len */ SSD_FULL_SIZE,
3050 /* timeout */ timeout ? timeout : 5000);
3052 if (arglist & CAM_ARG_ERR_RECOVER)
3053 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3055 /* Disable freezing the device queue */
3056 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3058 if (((retval = cam_send_ccb(device, ccb)) < 0)
3059 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
3060 if (arglist & CAM_ARG_VERBOSE) {
3061 cam_error_print(device, ccb, CAM_ESF_ALL,
3062 CAM_EPF_ALL, stderr);
3065 cam_close_device(device);
3067 err(1, "error sending mode sense command");
3069 errx(1, "error sending mode sense command");
3076 mode_select(struct cam_device *device, int save_pages, int retry_count,
3077 int timeout, u_int8_t *data, int datalen)
3082 ccb = cam_getccb(device);
3085 errx(1, "mode_select: couldn't allocate CCB");
3087 bzero(&(&ccb->ccb_h)[1],
3088 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3090 scsi_mode_select(&ccb->csio,
3091 /* retries */ retry_count,
3093 /* tag_action */ MSG_SIMPLE_Q_TAG,
3094 /* scsi_page_fmt */ 1,
3095 /* save_pages */ save_pages,
3096 /* param_buf */ data,
3097 /* param_len */ datalen,
3098 /* sense_len */ SSD_FULL_SIZE,
3099 /* timeout */ timeout ? timeout : 5000);
3101 if (arglist & CAM_ARG_ERR_RECOVER)
3102 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
3104 /* Disable freezing the device queue */
3105 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3107 if (((retval = cam_send_ccb(device, ccb)) < 0)
3108 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
3109 if (arglist & CAM_ARG_VERBOSE) {
3110 cam_error_print(device, ccb, CAM_ESF_ALL,
3111 CAM_EPF_ALL, stderr);
3114 cam_close_device(device);
3117 err(1, "error sending mode select command");
3119 errx(1, "error sending mode select command");
3127 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
3128 int retry_count, int timeout)
3130 int c, mode_page = -1, page_control = 0;
3131 int binary = 0, list = 0;
3133 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3139 arglist |= CAM_ARG_DBD;
3142 arglist |= CAM_ARG_MODE_EDIT;
3148 mode_page = strtol(optarg, NULL, 0);
3150 errx(1, "invalid mode page %d", mode_page);
3153 page_control = strtol(optarg, NULL, 0);
3154 if ((page_control < 0) || (page_control > 3))
3155 errx(1, "invalid page control field %d",
3157 arglist |= CAM_ARG_PAGE_CNTL;
3164 if (mode_page == -1 && list == 0)
3165 errx(1, "you must specify a mode page!");
3168 mode_list(device, page_control, arglist & CAM_ARG_DBD,
3169 retry_count, timeout);
3171 mode_edit(device, mode_page, page_control,
3172 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary,
3173 retry_count, timeout);
3178 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
3179 int retry_count, int timeout)
3182 u_int32_t flags = CAM_DIR_NONE;
3183 u_int8_t *data_ptr = NULL;
3185 u_int8_t atacmd[12];
3186 struct get_hook hook;
3187 int c, data_bytes = 0;
3193 char *datastr = NULL, *tstr, *resstr = NULL;
3195 int fd_data = 0, fd_res = 0;
3198 ccb = cam_getccb(device);
3201 warnx("scsicmd: error allocating ccb");
3205 bzero(&(&ccb->ccb_h)[1],
3206 sizeof(union ccb) - sizeof(struct ccb_hdr));
3208 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3212 while (isspace(*tstr) && (*tstr != '\0'))
3214 hook.argc = argc - optind;
3215 hook.argv = argv + optind;
3217 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
3220 * Increment optind by the number of arguments the
3221 * encoding routine processed. After each call to
3222 * getopt(3), optind points to the argument that
3223 * getopt should process _next_. In this case,
3224 * that means it points to the first command string
3225 * argument, if there is one. Once we increment
3226 * this, it should point to either the next command
3227 * line argument, or it should be past the end of
3234 while (isspace(*tstr) && (*tstr != '\0'))
3236 hook.argc = argc - optind;
3237 hook.argv = argv + optind;
3239 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
3242 * Increment optind by the number of arguments the
3243 * encoding routine processed. After each call to
3244 * getopt(3), optind points to the argument that
3245 * getopt should process _next_. In this case,
3246 * that means it points to the first command string
3247 * argument, if there is one. Once we increment
3248 * this, it should point to either the next command
3249 * line argument, or it should be past the end of
3261 if (arglist & CAM_ARG_CMD_OUT) {
3262 warnx("command must either be "
3263 "read or write, not both");
3265 goto scsicmd_bailout;
3267 arglist |= CAM_ARG_CMD_IN;
3269 data_bytes = strtol(optarg, NULL, 0);
3270 if (data_bytes <= 0) {
3271 warnx("invalid number of input bytes %d",
3274 goto scsicmd_bailout;
3276 hook.argc = argc - optind;
3277 hook.argv = argv + optind;
3280 datastr = cget(&hook, NULL);
3282 * If the user supplied "-" instead of a format, he
3283 * wants the data to be written to stdout.
3285 if ((datastr != NULL)
3286 && (datastr[0] == '-'))
3289 data_ptr = (u_int8_t *)malloc(data_bytes);
3290 if (data_ptr == NULL) {
3291 warnx("can't malloc memory for data_ptr");
3293 goto scsicmd_bailout;
3297 if (arglist & CAM_ARG_CMD_IN) {
3298 warnx("command must either be "
3299 "read or write, not both");
3301 goto scsicmd_bailout;
3303 arglist |= CAM_ARG_CMD_OUT;
3304 flags = CAM_DIR_OUT;
3305 data_bytes = strtol(optarg, NULL, 0);
3306 if (data_bytes <= 0) {
3307 warnx("invalid number of output bytes %d",
3310 goto scsicmd_bailout;
3312 hook.argc = argc - optind;
3313 hook.argv = argv + optind;
3315 datastr = cget(&hook, NULL);
3316 data_ptr = (u_int8_t *)malloc(data_bytes);
3317 if (data_ptr == NULL) {
3318 warnx("can't malloc memory for data_ptr");
3320 goto scsicmd_bailout;
3322 bzero(data_ptr, data_bytes);
3324 * If the user supplied "-" instead of a format, he
3325 * wants the data to be read from stdin.
3327 if ((datastr != NULL)
3328 && (datastr[0] == '-'))
3331 buff_encode_visit(data_ptr, data_bytes, datastr,
3337 hook.argc = argc - optind;
3338 hook.argv = argv + optind;
3340 resstr = cget(&hook, NULL);
3341 if ((resstr != NULL) && (resstr[0] == '-'))
3351 * If fd_data is set, and we're writing to the device, we need to
3352 * read the data the user wants written from stdin.
3354 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
3356 int amt_to_read = data_bytes;
3357 u_int8_t *buf_ptr = data_ptr;
3359 for (amt_read = 0; amt_to_read > 0;
3360 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
3361 if (amt_read == -1) {
3362 warn("error reading data from stdin");
3364 goto scsicmd_bailout;
3366 amt_to_read -= amt_read;
3367 buf_ptr += amt_read;
3371 if (arglist & CAM_ARG_ERR_RECOVER)
3372 flags |= CAM_PASS_ERR_RECOVER;
3374 /* Disable freezing the device queue */
3375 flags |= CAM_DEV_QFRZDIS;
3379 * This is taken from the SCSI-3 draft spec.
3380 * (T10/1157D revision 0.3)
3381 * The top 3 bits of an opcode are the group code.
3382 * The next 5 bits are the command code.
3383 * Group 0: six byte commands
3384 * Group 1: ten byte commands
3385 * Group 2: ten byte commands
3387 * Group 4: sixteen byte commands
3388 * Group 5: twelve byte commands
3389 * Group 6: vendor specific
3390 * Group 7: vendor specific
3392 switch((cdb[0] >> 5) & 0x7) {
3403 /* computed by buff_encode_visit */
3414 * We should probably use csio_build_visit or something like that
3415 * here, but it's easier to encode arguments as you go. The
3416 * alternative would be skipping the CDB argument and then encoding
3417 * it here, since we've got the data buffer argument by now.
3419 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
3421 cam_fill_csio(&ccb->csio,
3422 /*retries*/ retry_count,
3425 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3426 /*data_ptr*/ data_ptr,
3427 /*dxfer_len*/ data_bytes,
3428 /*sense_len*/ SSD_FULL_SIZE,
3429 /*cdb_len*/ cdb_len,
3430 /*timeout*/ timeout ? timeout : 5000);
3433 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
3435 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
3437 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
3439 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
3441 cam_fill_ataio(&ccb->ataio,
3442 /*retries*/ retry_count,
3446 /*data_ptr*/ data_ptr,
3447 /*dxfer_len*/ data_bytes,
3448 /*timeout*/ timeout ? timeout : 5000);
3451 if (((retval = cam_send_ccb(device, ccb)) < 0)
3452 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
3453 const char warnstr[] = "error sending command";
3460 if (arglist & CAM_ARG_VERBOSE) {
3461 cam_error_print(device, ccb, CAM_ESF_ALL,
3462 CAM_EPF_ALL, stderr);
3466 goto scsicmd_bailout;
3469 if (atacmd_len && need_res) {
3471 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
3473 fprintf(stdout, "\n");
3476 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
3477 ccb->ataio.res.status,
3478 ccb->ataio.res.error,
3479 ccb->ataio.res.lba_low,
3480 ccb->ataio.res.lba_mid,
3481 ccb->ataio.res.lba_high,
3482 ccb->ataio.res.device,
3483 ccb->ataio.res.lba_low_exp,
3484 ccb->ataio.res.lba_mid_exp,
3485 ccb->ataio.res.lba_high_exp,
3486 ccb->ataio.res.sector_count,
3487 ccb->ataio.res.sector_count_exp);
3492 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3493 && (arglist & CAM_ARG_CMD_IN)
3494 && (data_bytes > 0)) {
3496 buff_decode_visit(data_ptr, data_bytes, datastr,
3498 fprintf(stdout, "\n");
3500 ssize_t amt_written;
3501 int amt_to_write = data_bytes;
3502 u_int8_t *buf_ptr = data_ptr;
3504 for (amt_written = 0; (amt_to_write > 0) &&
3505 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
3506 amt_to_write -= amt_written;
3507 buf_ptr += amt_written;
3509 if (amt_written == -1) {
3510 warn("error writing data to stdout");
3512 goto scsicmd_bailout;
3513 } else if ((amt_written == 0)
3514 && (amt_to_write > 0)) {
3515 warnx("only wrote %u bytes out of %u",
3516 data_bytes - amt_to_write, data_bytes);
3523 if ((data_bytes > 0) && (data_ptr != NULL))
3532 camdebug(int argc, char **argv, char *combinedopt)
3535 int bus = -1, target = -1, lun = -1;
3536 char *tstr, *tmpstr = NULL;
3540 bzero(&ccb, sizeof(union ccb));
3542 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3545 arglist |= CAM_ARG_DEBUG_INFO;
3546 ccb.cdbg.flags |= CAM_DEBUG_INFO;
3549 arglist |= CAM_ARG_DEBUG_PERIPH;
3550 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
3553 arglist |= CAM_ARG_DEBUG_SUBTRACE;
3554 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
3557 arglist |= CAM_ARG_DEBUG_TRACE;
3558 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
3561 arglist |= CAM_ARG_DEBUG_XPT;
3562 ccb.cdbg.flags |= CAM_DEBUG_XPT;
3565 arglist |= CAM_ARG_DEBUG_CDB;
3566 ccb.cdbg.flags |= CAM_DEBUG_CDB;
3569 arglist |= CAM_ARG_DEBUG_PROBE;
3570 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
3577 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3578 warnx("error opening transport layer device %s", XPT_DEVICE);
3579 warn("%s", XPT_DEVICE);
3586 warnx("you must specify \"off\", \"all\" or a bus,");
3587 warnx("bus:target, or bus:target:lun");
3594 while (isspace(*tstr) && (*tstr != '\0'))
3597 if (strncmp(tstr, "off", 3) == 0) {
3598 ccb.cdbg.flags = CAM_DEBUG_NONE;
3599 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
3600 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
3601 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
3602 } else if (strncmp(tstr, "all", 3) != 0) {
3603 tmpstr = (char *)strtok(tstr, ":");
3604 if ((tmpstr != NULL) && (*tmpstr != '\0')){
3605 bus = strtol(tmpstr, NULL, 0);
3606 arglist |= CAM_ARG_BUS;
3607 tmpstr = (char *)strtok(NULL, ":");
3608 if ((tmpstr != NULL) && (*tmpstr != '\0')){
3609 target = strtol(tmpstr, NULL, 0);
3610 arglist |= CAM_ARG_TARGET;
3611 tmpstr = (char *)strtok(NULL, ":");
3612 if ((tmpstr != NULL) && (*tmpstr != '\0')){
3613 lun = strtol(tmpstr, NULL, 0);
3614 arglist |= CAM_ARG_LUN;
3619 warnx("you must specify \"all\", \"off\", or a bus,");
3620 warnx("bus:target, or bus:target:lun to debug");
3626 ccb.ccb_h.func_code = XPT_DEBUG;
3627 ccb.ccb_h.path_id = bus;
3628 ccb.ccb_h.target_id = target;
3629 ccb.ccb_h.target_lun = lun;
3631 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
3632 warn("CAMIOCOMMAND ioctl failed");
3637 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
3638 CAM_FUNC_NOTAVAIL) {
3639 warnx("CAM debugging not available");
3640 warnx("you need to put options CAMDEBUG in"
3641 " your kernel config file!");
3643 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
3645 warnx("XPT_DEBUG CCB failed with status %#x",
3649 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
3651 "Debugging turned off\n");
3654 "Debugging enabled for "
3667 tagcontrol(struct cam_device *device, int argc, char **argv,
3677 ccb = cam_getccb(device);
3680 warnx("tagcontrol: error allocating ccb");
3684 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3687 numtags = strtol(optarg, NULL, 0);
3689 warnx("tag count %d is < 0", numtags);
3691 goto tagcontrol_bailout;
3702 cam_path_string(device, pathstr, sizeof(pathstr));
3705 bzero(&(&ccb->ccb_h)[1],
3706 sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
3707 ccb->ccb_h.func_code = XPT_REL_SIMQ;
3708 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
3709 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
3710 ccb->crs.openings = numtags;
3713 if (cam_send_ccb(device, ccb) < 0) {
3714 perror("error sending XPT_REL_SIMQ CCB");
3716 goto tagcontrol_bailout;
3719 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3720 warnx("XPT_REL_SIMQ CCB failed");
3721 cam_error_print(device, ccb, CAM_ESF_ALL,
3722 CAM_EPF_ALL, stderr);
3724 goto tagcontrol_bailout;
3729 fprintf(stdout, "%stagged openings now %d\n",
3730 pathstr, ccb->crs.openings);
3733 bzero(&(&ccb->ccb_h)[1],
3734 sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr));
3736 ccb->ccb_h.func_code = XPT_GDEV_STATS;
3738 if (cam_send_ccb(device, ccb) < 0) {
3739 perror("error sending XPT_GDEV_STATS CCB");
3741 goto tagcontrol_bailout;
3744 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3745 warnx("XPT_GDEV_STATS CCB failed");
3746 cam_error_print(device, ccb, CAM_ESF_ALL,
3747 CAM_EPF_ALL, stderr);
3749 goto tagcontrol_bailout;
3752 if (arglist & CAM_ARG_VERBOSE) {
3753 fprintf(stdout, "%s", pathstr);
3754 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
3755 fprintf(stdout, "%s", pathstr);
3756 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
3757 fprintf(stdout, "%s", pathstr);
3758 fprintf(stdout, "devq_openings %d\n", ccb->cgds.devq_openings);
3759 fprintf(stdout, "%s", pathstr);
3760 fprintf(stdout, "devq_queued %d\n", ccb->cgds.devq_queued);
3761 fprintf(stdout, "%s", pathstr);
3762 fprintf(stdout, "held %d\n", ccb->cgds.held);
3763 fprintf(stdout, "%s", pathstr);
3764 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
3765 fprintf(stdout, "%s", pathstr);
3766 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
3769 fprintf(stdout, "%s", pathstr);
3770 fprintf(stdout, "device openings: ");
3772 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
3773 ccb->cgds.dev_active);
3783 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
3787 cam_path_string(device, pathstr, sizeof(pathstr));
3789 if (cts->transport == XPORT_SPI) {
3790 struct ccb_trans_settings_spi *spi =
3791 &cts->xport_specific.spi;
3793 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
3795 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
3798 if (spi->sync_offset != 0) {
3801 freq = scsi_calc_syncsrate(spi->sync_period);
3802 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
3803 pathstr, freq / 1000, freq % 1000);
3807 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
3808 fprintf(stdout, "%soffset: %d\n", pathstr,
3812 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
3813 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
3814 (0x01 << spi->bus_width) * 8);
3817 if (spi->valid & CTS_SPI_VALID_DISC) {
3818 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
3819 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
3820 "enabled" : "disabled");
3823 if (cts->transport == XPORT_FC) {
3824 struct ccb_trans_settings_fc *fc =
3825 &cts->xport_specific.fc;
3827 if (fc->valid & CTS_FC_VALID_WWNN)
3828 fprintf(stdout, "%sWWNN: 0x%llx", pathstr,
3829 (long long) fc->wwnn);
3830 if (fc->valid & CTS_FC_VALID_WWPN)
3831 fprintf(stdout, "%sWWPN: 0x%llx", pathstr,
3832 (long long) fc->wwpn);
3833 if (fc->valid & CTS_FC_VALID_PORT)
3834 fprintf(stdout, "%sPortID: 0x%x", pathstr, fc->port);
3835 if (fc->valid & CTS_FC_VALID_SPEED)
3836 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
3837 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
3839 if (cts->transport == XPORT_SAS) {
3840 struct ccb_trans_settings_sas *sas =
3841 &cts->xport_specific.sas;
3843 if (sas->valid & CTS_SAS_VALID_SPEED)
3844 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
3845 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
3847 if (cts->transport == XPORT_ATA) {
3848 struct ccb_trans_settings_pata *pata =
3849 &cts->xport_specific.ata;
3851 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
3852 fprintf(stdout, "%sATA mode: %s\n", pathstr,
3853 ata_mode2string(pata->mode));
3855 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
3856 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
3859 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
3860 fprintf(stdout, "%sPIO transaction length: %d\n",
3861 pathstr, pata->bytecount);
3864 if (cts->transport == XPORT_SATA) {
3865 struct ccb_trans_settings_sata *sata =
3866 &cts->xport_specific.sata;
3868 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
3869 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
3872 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
3873 fprintf(stdout, "%sATA mode: %s\n", pathstr,
3874 ata_mode2string(sata->mode));
3876 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
3877 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
3880 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
3881 fprintf(stdout, "%sPIO transaction length: %d\n",
3882 pathstr, sata->bytecount);
3884 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
3885 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
3888 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
3889 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
3892 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
3893 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
3897 if (cts->protocol == PROTO_ATA) {
3898 struct ccb_trans_settings_ata *ata=
3899 &cts->proto_specific.ata;
3901 if (ata->valid & CTS_ATA_VALID_TQ) {
3902 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
3903 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
3904 "enabled" : "disabled");
3907 if (cts->protocol == PROTO_SCSI) {
3908 struct ccb_trans_settings_scsi *scsi=
3909 &cts->proto_specific.scsi;
3911 if (scsi->valid & CTS_SCSI_VALID_TQ) {
3912 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
3913 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
3914 "enabled" : "disabled");
3921 * Get a path inquiry CCB for the specified device.
3924 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
3929 ccb = cam_getccb(device);
3931 warnx("get_cpi: couldn't allocate CCB");
3934 bzero(&(&ccb->ccb_h)[1],
3935 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
3936 ccb->ccb_h.func_code = XPT_PATH_INQ;
3937 if (cam_send_ccb(device, ccb) < 0) {
3938 warn("get_cpi: error sending Path Inquiry CCB");
3939 if (arglist & CAM_ARG_VERBOSE)
3940 cam_error_print(device, ccb, CAM_ESF_ALL,
3941 CAM_EPF_ALL, stderr);
3943 goto get_cpi_bailout;
3945 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3946 if (arglist & CAM_ARG_VERBOSE)
3947 cam_error_print(device, ccb, CAM_ESF_ALL,
3948 CAM_EPF_ALL, stderr);
3950 goto get_cpi_bailout;
3952 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
3960 * Get a get device CCB for the specified device.
3963 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
3968 ccb = cam_getccb(device);
3970 warnx("get_cgd: couldn't allocate CCB");
3973 bzero(&(&ccb->ccb_h)[1],
3974 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
3975 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
3976 if (cam_send_ccb(device, ccb) < 0) {
3977 warn("get_cgd: error sending Path Inquiry CCB");
3978 if (arglist & CAM_ARG_VERBOSE)
3979 cam_error_print(device, ccb, CAM_ESF_ALL,
3980 CAM_EPF_ALL, stderr);
3982 goto get_cgd_bailout;
3984 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3985 if (arglist & CAM_ARG_VERBOSE)
3986 cam_error_print(device, ccb, CAM_ESF_ALL,
3987 CAM_EPF_ALL, stderr);
3989 goto get_cgd_bailout;
3991 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
3998 /* return the type of disk (really the command type) */
4000 get_disk_type(struct cam_device *device)
4002 struct ccb_getdev cgd;
4004 (void) memset(&cgd, 0x0, sizeof(cgd));
4005 get_cgd(device, &cgd);
4006 switch(cgd.protocol) {
4019 cpi_print(struct ccb_pathinq *cpi)
4021 char adapter_str[1024];
4024 snprintf(adapter_str, sizeof(adapter_str),
4025 "%s%d:", cpi->dev_name, cpi->unit_number);
4027 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
4030 for (i = 1; i < 0xff; i = i << 1) {
4033 if ((i & cpi->hba_inquiry) == 0)
4036 fprintf(stdout, "%s supports ", adapter_str);
4040 str = "MDP message";
4043 str = "32 bit wide SCSI";
4046 str = "16 bit wide SCSI";
4049 str = "SDTR message";
4052 str = "linked CDBs";
4055 str = "tag queue messages";
4058 str = "soft reset alternative";
4061 str = "SATA Port Multiplier";
4064 str = "unknown PI bit set";
4067 fprintf(stdout, "%s\n", str);
4070 for (i = 1; i < 0xff; i = i << 1) {
4073 if ((i & cpi->hba_misc) == 0)
4076 fprintf(stdout, "%s ", adapter_str);
4080 str = "bus scans from high ID to low ID";
4083 str = "removable devices not included in scan";
4085 case PIM_NOINITIATOR:
4086 str = "initiator role not supported";
4088 case PIM_NOBUSRESET:
4089 str = "user has disabled initial BUS RESET or"
4090 " controller is in target/mixed mode";
4093 str = "do not send 6-byte commands";
4096 str = "scan bus sequentially";
4099 str = "unknown PIM bit set";
4102 fprintf(stdout, "%s\n", str);
4105 for (i = 1; i < 0xff; i = i << 1) {
4108 if ((i & cpi->target_sprt) == 0)
4111 fprintf(stdout, "%s supports ", adapter_str);
4114 str = "target mode processor mode";
4117 str = "target mode phase cog. mode";
4119 case PIT_DISCONNECT:
4120 str = "disconnects in target mode";
4123 str = "terminate I/O message in target mode";
4126 str = "group 6 commands in target mode";
4129 str = "group 7 commands in target mode";
4132 str = "unknown PIT bit set";
4136 fprintf(stdout, "%s\n", str);
4138 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
4140 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
4142 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
4144 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
4145 adapter_str, cpi->hpath_id);
4146 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
4148 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
4149 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
4150 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
4151 adapter_str, cpi->hba_vendor);
4152 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
4153 adapter_str, cpi->hba_device);
4154 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
4155 adapter_str, cpi->hba_subvendor);
4156 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
4157 adapter_str, cpi->hba_subdevice);
4158 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
4159 fprintf(stdout, "%s base transfer speed: ", adapter_str);
4160 if (cpi->base_transfer_speed > 1000)
4161 fprintf(stdout, "%d.%03dMB/sec\n",
4162 cpi->base_transfer_speed / 1000,
4163 cpi->base_transfer_speed % 1000);
4165 fprintf(stdout, "%dKB/sec\n",
4166 (cpi->base_transfer_speed % 1000) * 1000);
4167 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
4168 adapter_str, cpi->maxio);
4172 get_print_cts(struct cam_device *device, int user_settings, int quiet,
4173 struct ccb_trans_settings *cts)
4179 ccb = cam_getccb(device);
4182 warnx("get_print_cts: error allocating ccb");
4186 bzero(&(&ccb->ccb_h)[1],
4187 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
4189 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
4191 if (user_settings == 0)
4192 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
4194 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
4196 if (cam_send_ccb(device, ccb) < 0) {
4197 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
4198 if (arglist & CAM_ARG_VERBOSE)
4199 cam_error_print(device, ccb, CAM_ESF_ALL,
4200 CAM_EPF_ALL, stderr);
4202 goto get_print_cts_bailout;
4205 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4206 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
4207 if (arglist & CAM_ARG_VERBOSE)
4208 cam_error_print(device, ccb, CAM_ESF_ALL,
4209 CAM_EPF_ALL, stderr);
4211 goto get_print_cts_bailout;
4215 cts_print(device, &ccb->cts);
4218 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
4220 get_print_cts_bailout:
4228 ratecontrol(struct cam_device *device, int retry_count, int timeout,
4229 int argc, char **argv, char *combinedopt)
4233 int user_settings = 0;
4235 int disc_enable = -1, tag_enable = -1;
4238 double syncrate = -1;
4241 int change_settings = 0, send_tur = 0;
4242 struct ccb_pathinq cpi;
4244 ccb = cam_getccb(device);
4246 warnx("ratecontrol: error allocating ccb");
4249 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4258 if (strncasecmp(optarg, "enable", 6) == 0)
4260 else if (strncasecmp(optarg, "disable", 7) == 0)
4263 warnx("-D argument \"%s\" is unknown", optarg);
4265 goto ratecontrol_bailout;
4267 change_settings = 1;
4270 mode = ata_string2mode(optarg);
4272 warnx("unknown mode '%s'", optarg);
4274 goto ratecontrol_bailout;
4276 change_settings = 1;
4279 offset = strtol(optarg, NULL, 0);
4281 warnx("offset value %d is < 0", offset);
4283 goto ratecontrol_bailout;
4285 change_settings = 1;
4291 syncrate = atof(optarg);
4293 warnx("sync rate %f is < 0", syncrate);
4295 goto ratecontrol_bailout;
4297 change_settings = 1;
4300 if (strncasecmp(optarg, "enable", 6) == 0)
4302 else if (strncasecmp(optarg, "disable", 7) == 0)
4305 warnx("-T argument \"%s\" is unknown", optarg);
4307 goto ratecontrol_bailout;
4309 change_settings = 1;
4315 bus_width = strtol(optarg, NULL, 0);
4316 if (bus_width < 0) {
4317 warnx("bus width %d is < 0", bus_width);
4319 goto ratecontrol_bailout;
4321 change_settings = 1;
4327 bzero(&(&ccb->ccb_h)[1],
4328 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
4330 * Grab path inquiry information, so we can determine whether
4331 * or not the initiator is capable of the things that the user
4334 ccb->ccb_h.func_code = XPT_PATH_INQ;
4335 if (cam_send_ccb(device, ccb) < 0) {
4336 perror("error sending XPT_PATH_INQ CCB");
4337 if (arglist & CAM_ARG_VERBOSE) {
4338 cam_error_print(device, ccb, CAM_ESF_ALL,
4339 CAM_EPF_ALL, stderr);
4342 goto ratecontrol_bailout;
4344 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4345 warnx("XPT_PATH_INQ CCB failed");
4346 if (arglist & CAM_ARG_VERBOSE) {
4347 cam_error_print(device, ccb, CAM_ESF_ALL,
4348 CAM_EPF_ALL, stderr);
4351 goto ratecontrol_bailout;
4353 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
4354 bzero(&(&ccb->ccb_h)[1],
4355 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
4357 fprintf(stdout, "%s parameters:\n",
4358 user_settings ? "User" : "Current");
4360 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
4362 goto ratecontrol_bailout;
4364 if (arglist & CAM_ARG_VERBOSE)
4367 if (change_settings) {
4368 int didsettings = 0;
4369 struct ccb_trans_settings_spi *spi = NULL;
4370 struct ccb_trans_settings_pata *pata = NULL;
4371 struct ccb_trans_settings_sata *sata = NULL;
4372 struct ccb_trans_settings_ata *ata = NULL;
4373 struct ccb_trans_settings_scsi *scsi = NULL;
4375 if (ccb->cts.transport == XPORT_SPI)
4376 spi = &ccb->cts.xport_specific.spi;
4377 if (ccb->cts.transport == XPORT_ATA)
4378 pata = &ccb->cts.xport_specific.ata;
4379 if (ccb->cts.transport == XPORT_SATA)
4380 sata = &ccb->cts.xport_specific.sata;
4381 if (ccb->cts.protocol == PROTO_ATA)
4382 ata = &ccb->cts.proto_specific.ata;
4383 if (ccb->cts.protocol == PROTO_SCSI)
4384 scsi = &ccb->cts.proto_specific.scsi;
4385 ccb->cts.xport_specific.valid = 0;
4386 ccb->cts.proto_specific.valid = 0;
4387 if (spi && disc_enable != -1) {
4388 spi->valid |= CTS_SPI_VALID_DISC;
4389 if (disc_enable == 0)
4390 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
4392 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
4395 if (tag_enable != -1) {
4396 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
4397 warnx("HBA does not support tagged queueing, "
4398 "so you cannot modify tag settings");
4400 goto ratecontrol_bailout;
4403 ata->valid |= CTS_SCSI_VALID_TQ;
4404 if (tag_enable == 0)
4405 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
4407 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
4410 scsi->valid |= CTS_SCSI_VALID_TQ;
4411 if (tag_enable == 0)
4412 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
4414 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
4418 if (spi && offset != -1) {
4419 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
4420 warnx("HBA is not capable of changing offset");
4422 goto ratecontrol_bailout;
4424 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
4425 spi->sync_offset = offset;
4428 if (spi && syncrate != -1) {
4429 int prelim_sync_period;
4431 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
4432 warnx("HBA is not capable of changing "
4435 goto ratecontrol_bailout;
4437 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
4439 * The sync rate the user gives us is in MHz.
4440 * We need to translate it into KHz for this
4445 * Next, we calculate a "preliminary" sync period
4446 * in tenths of a nanosecond.
4449 prelim_sync_period = 0;
4451 prelim_sync_period = 10000000 / syncrate;
4453 scsi_calc_syncparam(prelim_sync_period);
4456 if (sata && syncrate != -1) {
4457 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
4458 warnx("HBA is not capable of changing "
4461 goto ratecontrol_bailout;
4463 if (!user_settings) {
4464 warnx("You can modify only user rate "
4465 "settings for SATA");
4467 goto ratecontrol_bailout;
4469 sata->revision = ata_speed2revision(syncrate * 100);
4470 if (sata->revision < 0) {
4471 warnx("Invalid rate %f", syncrate);
4473 goto ratecontrol_bailout;
4475 sata->valid |= CTS_SATA_VALID_REVISION;
4478 if ((pata || sata) && mode != -1) {
4479 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
4480 warnx("HBA is not capable of changing "
4483 goto ratecontrol_bailout;
4485 if (!user_settings) {
4486 warnx("You can modify only user mode "
4487 "settings for ATA/SATA");
4489 goto ratecontrol_bailout;
4493 pata->valid |= CTS_ATA_VALID_MODE;
4496 sata->valid |= CTS_SATA_VALID_MODE;
4501 * The bus_width argument goes like this:
4505 * Therefore, if you shift the number of bits given on the
4506 * command line right by 4, you should get the correct
4509 if (spi && bus_width != -1) {
4511 * We might as well validate things here with a
4512 * decipherable error message, rather than what
4513 * will probably be an indecipherable error message
4514 * by the time it gets back to us.
4516 if ((bus_width == 16)
4517 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
4518 warnx("HBA does not support 16 bit bus width");
4520 goto ratecontrol_bailout;
4521 } else if ((bus_width == 32)
4522 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
4523 warnx("HBA does not support 32 bit bus width");
4525 goto ratecontrol_bailout;
4526 } else if ((bus_width != 8)
4527 && (bus_width != 16)
4528 && (bus_width != 32)) {
4529 warnx("Invalid bus width %d", bus_width);
4531 goto ratecontrol_bailout;
4533 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
4534 spi->bus_width = bus_width >> 4;
4537 if (didsettings == 0) {
4538 goto ratecontrol_bailout;
4540 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
4541 if (cam_send_ccb(device, ccb) < 0) {
4542 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
4543 if (arglist & CAM_ARG_VERBOSE) {
4544 cam_error_print(device, ccb, CAM_ESF_ALL,
4545 CAM_EPF_ALL, stderr);
4548 goto ratecontrol_bailout;
4550 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4551 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
4552 if (arglist & CAM_ARG_VERBOSE) {
4553 cam_error_print(device, ccb, CAM_ESF_ALL,
4554 CAM_EPF_ALL, stderr);
4557 goto ratecontrol_bailout;
4561 retval = testunitready(device, retry_count, timeout,
4562 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
4564 * If the TUR didn't succeed, just bail.
4568 fprintf(stderr, "Test Unit Ready failed\n");
4569 goto ratecontrol_bailout;
4572 if ((change_settings || send_tur) && !quiet &&
4573 (ccb->cts.transport == XPORT_ATA ||
4574 ccb->cts.transport == XPORT_SATA || send_tur)) {
4575 fprintf(stdout, "New parameters:\n");
4576 retval = get_print_cts(device, user_settings, 0, NULL);
4579 ratecontrol_bailout:
4585 scsiformat(struct cam_device *device, int argc, char **argv,
4586 char *combinedopt, int retry_count, int timeout)
4590 int ycount = 0, quiet = 0;
4591 int error = 0, retval = 0;
4592 int use_timeout = 10800 * 1000;
4594 struct format_defect_list_header fh;
4595 u_int8_t *data_ptr = NULL;
4596 u_int32_t dxfer_len = 0;
4598 int num_warnings = 0;
4601 ccb = cam_getccb(device);
4604 warnx("scsiformat: error allocating ccb");
4608 bzero(&(&ccb->ccb_h)[1],
4609 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
4611 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4632 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
4633 "following device:\n");
4635 error = scsidoinquiry(device, argc, argv, combinedopt,
4636 retry_count, timeout);
4639 warnx("scsiformat: error sending inquiry");
4640 goto scsiformat_bailout;
4645 if (!get_confirmation()) {
4647 goto scsiformat_bailout;
4652 use_timeout = timeout;
4655 fprintf(stdout, "Current format timeout is %d seconds\n",
4656 use_timeout / 1000);
4660 * If the user hasn't disabled questions and didn't specify a
4661 * timeout on the command line, ask them if they want the current
4665 && (timeout == 0)) {
4667 int new_timeout = 0;
4669 fprintf(stdout, "Enter new timeout in seconds or press\n"
4670 "return to keep the current timeout [%d] ",
4671 use_timeout / 1000);
4673 if (fgets(str, sizeof(str), stdin) != NULL) {
4675 new_timeout = atoi(str);
4678 if (new_timeout != 0) {
4679 use_timeout = new_timeout * 1000;
4680 fprintf(stdout, "Using new timeout value %d\n",
4681 use_timeout / 1000);
4686 * Keep this outside the if block below to silence any unused
4687 * variable warnings.
4689 bzero(&fh, sizeof(fh));
4692 * If we're in immediate mode, we've got to include the format
4695 if (immediate != 0) {
4696 fh.byte2 = FU_DLH_IMMED;
4697 data_ptr = (u_int8_t *)&fh;
4698 dxfer_len = sizeof(fh);
4699 byte2 = FU_FMT_DATA;
4700 } else if (quiet == 0) {
4701 fprintf(stdout, "Formatting...");
4705 scsi_format_unit(&ccb->csio,
4706 /* retries */ retry_count,
4708 /* tag_action */ MSG_SIMPLE_Q_TAG,
4711 /* data_ptr */ data_ptr,
4712 /* dxfer_len */ dxfer_len,
4713 /* sense_len */ SSD_FULL_SIZE,
4714 /* timeout */ use_timeout);
4716 /* Disable freezing the device queue */
4717 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4719 if (arglist & CAM_ARG_ERR_RECOVER)
4720 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4722 if (((retval = cam_send_ccb(device, ccb)) < 0)
4723 || ((immediate == 0)
4724 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
4725 const char errstr[] = "error sending format command";
4732 if (arglist & CAM_ARG_VERBOSE) {
4733 cam_error_print(device, ccb, CAM_ESF_ALL,
4734 CAM_EPF_ALL, stderr);
4737 goto scsiformat_bailout;
4741 * If we ran in non-immediate mode, we already checked for errors
4742 * above and printed out any necessary information. If we're in
4743 * immediate mode, we need to loop through and get status
4744 * information periodically.
4746 if (immediate == 0) {
4748 fprintf(stdout, "Format Complete\n");
4750 goto scsiformat_bailout;
4757 bzero(&(&ccb->ccb_h)[1],
4758 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
4761 * There's really no need to do error recovery or
4762 * retries here, since we're just going to sit in a
4763 * loop and wait for the device to finish formatting.
4765 scsi_test_unit_ready(&ccb->csio,
4768 /* tag_action */ MSG_SIMPLE_Q_TAG,
4769 /* sense_len */ SSD_FULL_SIZE,
4770 /* timeout */ 5000);
4772 /* Disable freezing the device queue */
4773 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4775 retval = cam_send_ccb(device, ccb);
4778 * If we get an error from the ioctl, bail out. SCSI
4779 * errors are expected.
4782 warn("error sending CAMIOCOMMAND ioctl");
4783 if (arglist & CAM_ARG_VERBOSE) {
4784 cam_error_print(device, ccb, CAM_ESF_ALL,
4785 CAM_EPF_ALL, stderr);
4788 goto scsiformat_bailout;
4791 status = ccb->ccb_h.status & CAM_STATUS_MASK;
4793 if ((status != CAM_REQ_CMP)
4794 && (status == CAM_SCSI_STATUS_ERROR)
4795 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4796 struct scsi_sense_data *sense;
4797 int error_code, sense_key, asc, ascq;
4799 sense = &ccb->csio.sense_data;
4800 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4801 ccb->csio.sense_resid, &error_code, &sense_key,
4802 &asc, &ascq, /*show_errors*/ 1);
4805 * According to the SCSI-2 and SCSI-3 specs, a
4806 * drive that is in the middle of a format should
4807 * return NOT READY with an ASC of "logical unit
4808 * not ready, format in progress". The sense key
4809 * specific bytes will then be a progress indicator.
4811 if ((sense_key == SSD_KEY_NOT_READY)
4812 && (asc == 0x04) && (ascq == 0x04)) {
4815 if ((scsi_get_sks(sense, ccb->csio.sense_len -
4816 ccb->csio.sense_resid, sks) == 0)
4819 u_int64_t percentage;
4821 val = scsi_2btoul(&sks[1]);
4822 percentage = 10000 * val;
4825 "\rFormatting: %ju.%02u %% "
4827 (uintmax_t)(percentage /
4829 (unsigned)((percentage /
4833 } else if ((quiet == 0)
4834 && (++num_warnings <= 1)) {
4835 warnx("Unexpected SCSI Sense Key "
4836 "Specific value returned "
4838 scsi_sense_print(device, &ccb->csio,
4840 warnx("Unable to print status "
4841 "information, but format will "
4843 warnx("will exit when format is "
4848 warnx("Unexpected SCSI error during format");
4849 cam_error_print(device, ccb, CAM_ESF_ALL,
4850 CAM_EPF_ALL, stderr);
4852 goto scsiformat_bailout;
4855 } else if (status != CAM_REQ_CMP) {
4856 warnx("Unexpected CAM status %#x", status);
4857 if (arglist & CAM_ARG_VERBOSE)
4858 cam_error_print(device, ccb, CAM_ESF_ALL,
4859 CAM_EPF_ALL, stderr);
4861 goto scsiformat_bailout;
4864 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
4867 fprintf(stdout, "\nFormat Complete\n");
4877 scsireportluns(struct cam_device *device, int argc, char **argv,
4878 char *combinedopt, int retry_count, int timeout)
4881 int c, countonly, lunsonly;
4882 struct scsi_report_luns_data *lundata;
4884 uint8_t report_type;
4885 uint32_t list_len, i, j;
4890 report_type = RPL_REPORT_DEFAULT;
4891 ccb = cam_getccb(device);
4894 warnx("%s: error allocating ccb", __func__);
4898 bzero(&(&ccb->ccb_h)[1],
4899 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
4904 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4913 if (strcasecmp(optarg, "default") == 0)
4914 report_type = RPL_REPORT_DEFAULT;
4915 else if (strcasecmp(optarg, "wellknown") == 0)
4916 report_type = RPL_REPORT_WELLKNOWN;
4917 else if (strcasecmp(optarg, "all") == 0)
4918 report_type = RPL_REPORT_ALL;
4920 warnx("%s: invalid report type \"%s\"",
4931 if ((countonly != 0)
4932 && (lunsonly != 0)) {
4933 warnx("%s: you can only specify one of -c or -l", __func__);
4938 * According to SPC-4, the allocation length must be at least 16
4939 * bytes -- enough for the header and one LUN.
4941 alloc_len = sizeof(*lundata) + 8;
4945 lundata = malloc(alloc_len);
4947 if (lundata == NULL) {
4948 warn("%s: error mallocing %d bytes", __func__, alloc_len);
4953 scsi_report_luns(&ccb->csio,
4954 /*retries*/ retry_count,
4956 /*tag_action*/ MSG_SIMPLE_Q_TAG,
4957 /*select_report*/ report_type,
4958 /*rpl_buf*/ lundata,
4959 /*alloc_len*/ alloc_len,
4960 /*sense_len*/ SSD_FULL_SIZE,
4961 /*timeout*/ timeout ? timeout : 5000);
4963 /* Disable freezing the device queue */
4964 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4966 if (arglist & CAM_ARG_ERR_RECOVER)
4967 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4969 if (cam_send_ccb(device, ccb) < 0) {
4970 warn("error sending REPORT LUNS command");
4972 if (arglist & CAM_ARG_VERBOSE)
4973 cam_error_print(device, ccb, CAM_ESF_ALL,
4974 CAM_EPF_ALL, stderr);
4980 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4981 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
4987 list_len = scsi_4btoul(lundata->length);
4990 * If we need to list the LUNs, and our allocation
4991 * length was too short, reallocate and retry.
4993 if ((countonly == 0)
4994 && (list_len > (alloc_len - sizeof(*lundata)))) {
4995 alloc_len = list_len + sizeof(*lundata);
5001 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
5002 ((list_len / 8) > 1) ? "s" : "");
5007 for (i = 0; i < (list_len / 8); i++) {
5011 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
5013 fprintf(stdout, ",");
5014 switch (lundata->luns[i].lundata[j] &
5015 RPL_LUNDATA_ATYP_MASK) {
5016 case RPL_LUNDATA_ATYP_PERIPH:
5017 if ((lundata->luns[i].lundata[j] &
5018 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
5019 fprintf(stdout, "%d:",
5020 lundata->luns[i].lundata[j] &
5021 RPL_LUNDATA_PERIPH_BUS_MASK);
5023 && ((lundata->luns[i].lundata[j+2] &
5024 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
5027 fprintf(stdout, "%d",
5028 lundata->luns[i].lundata[j+1]);
5030 case RPL_LUNDATA_ATYP_FLAT: {
5032 tmplun[0] = lundata->luns[i].lundata[j] &
5033 RPL_LUNDATA_FLAT_LUN_MASK;
5034 tmplun[1] = lundata->luns[i].lundata[j+1];
5036 fprintf(stdout, "%d", scsi_2btoul(tmplun));
5040 case RPL_LUNDATA_ATYP_LUN:
5041 fprintf(stdout, "%d:%d:%d",
5042 (lundata->luns[i].lundata[j+1] &
5043 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
5044 lundata->luns[i].lundata[j] &
5045 RPL_LUNDATA_LUN_TARG_MASK,
5046 lundata->luns[i].lundata[j+1] &
5047 RPL_LUNDATA_LUN_LUN_MASK);
5049 case RPL_LUNDATA_ATYP_EXTLUN: {
5050 int field_len_code, eam_code;
5052 eam_code = lundata->luns[i].lundata[j] &
5053 RPL_LUNDATA_EXT_EAM_MASK;
5054 field_len_code = (lundata->luns[i].lundata[j] &
5055 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
5057 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
5058 && (field_len_code == 0x00)) {
5059 fprintf(stdout, "%d",
5060 lundata->luns[i].lundata[j+1]);
5061 } else if ((eam_code ==
5062 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
5063 && (field_len_code == 0x03)) {
5067 * This format takes up all 8 bytes.
5068 * If we aren't starting at offset 0,
5072 fprintf(stdout, "Invalid "
5075 "specified format", j);
5079 bzero(tmp_lun, sizeof(tmp_lun));
5080 bcopy(&lundata->luns[i].lundata[j+1],
5081 &tmp_lun[1], sizeof(tmp_lun) - 1);
5082 fprintf(stdout, "%#jx",
5083 (intmax_t)scsi_8btou64(tmp_lun));
5086 fprintf(stderr, "Unknown Extended LUN"
5087 "Address method %#x, length "
5088 "code %#x", eam_code,
5095 fprintf(stderr, "Unknown LUN address method "
5096 "%#x\n", lundata->luns[i].lundata[0] &
5097 RPL_LUNDATA_ATYP_MASK);
5101 * For the flat addressing method, there are no
5102 * other levels after it.
5107 fprintf(stdout, "\n");
5120 scsireadcapacity(struct cam_device *device, int argc, char **argv,
5121 char *combinedopt, int retry_count, int timeout)
5124 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
5125 struct scsi_read_capacity_data rcap;
5126 struct scsi_read_capacity_data_long rcaplong;
5140 ccb = cam_getccb(device);
5143 warnx("%s: error allocating ccb", __func__);
5147 bzero(&(&ccb->ccb_h)[1],
5148 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
5150 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5177 if ((blocksizeonly != 0)
5178 && (numblocks != 0)) {
5179 warnx("%s: you can only specify one of -b or -N", __func__);
5184 if ((blocksizeonly != 0)
5185 && (sizeonly != 0)) {
5186 warnx("%s: you can only specify one of -b or -s", __func__);
5193 warnx("%s: you can only specify one of -h/-H or -q", __func__);
5199 && (blocksizeonly != 0)) {
5200 warnx("%s: you can only specify one of -h/-H or -b", __func__);
5205 scsi_read_capacity(&ccb->csio,
5206 /*retries*/ retry_count,
5208 /*tag_action*/ MSG_SIMPLE_Q_TAG,
5211 /*timeout*/ timeout ? timeout : 5000);
5213 /* Disable freezing the device queue */
5214 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5216 if (arglist & CAM_ARG_ERR_RECOVER)
5217 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5219 if (cam_send_ccb(device, ccb) < 0) {
5220 warn("error sending READ CAPACITY command");
5222 if (arglist & CAM_ARG_VERBOSE)
5223 cam_error_print(device, ccb, CAM_ESF_ALL,
5224 CAM_EPF_ALL, stderr);
5230 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5231 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
5236 maxsector = scsi_4btoul(rcap.addr);
5237 block_len = scsi_4btoul(rcap.length);
5240 * A last block of 2^32-1 means that the true capacity is over 2TB,
5241 * and we need to issue the long READ CAPACITY to get the real
5242 * capacity. Otherwise, we're all set.
5244 if (maxsector != 0xffffffff)
5247 scsi_read_capacity_16(&ccb->csio,
5248 /*retries*/ retry_count,
5250 /*tag_action*/ MSG_SIMPLE_Q_TAG,
5255 /*sense_len*/ SSD_FULL_SIZE,
5256 /*timeout*/ timeout ? timeout : 5000);
5258 /* Disable freezing the device queue */
5259 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5261 if (arglist & CAM_ARG_ERR_RECOVER)
5262 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5264 if (cam_send_ccb(device, ccb) < 0) {
5265 warn("error sending READ CAPACITY (16) command");
5267 if (arglist & CAM_ARG_VERBOSE)
5268 cam_error_print(device, ccb, CAM_ESF_ALL,
5269 CAM_EPF_ALL, stderr);
5275 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5276 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
5281 maxsector = scsi_8btou64(rcaplong.addr);
5282 block_len = scsi_4btoul(rcaplong.length);
5285 if (blocksizeonly == 0) {
5287 * Humanize implies !quiet, and also implies numblocks.
5289 if (humanize != 0) {
5294 tmpbytes = (maxsector + 1) * block_len;
5295 ret = humanize_number(tmpstr, sizeof(tmpstr),
5296 tmpbytes, "", HN_AUTOSCALE,
5299 HN_DIVISOR_1000 : 0));
5301 warnx("%s: humanize_number failed!", __func__);
5305 fprintf(stdout, "Device Size: %s%s", tmpstr,
5306 (sizeonly == 0) ? ", " : "\n");
5307 } else if (numblocks != 0) {
5308 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
5309 "Blocks: " : "", (uintmax_t)maxsector + 1,
5310 (sizeonly == 0) ? ", " : "\n");
5312 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
5313 "Last Block: " : "", (uintmax_t)maxsector,
5314 (sizeonly == 0) ? ", " : "\n");
5318 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
5319 "Block Length: " : "", block_len, (quiet == 0) ?
5328 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
5329 int retry_count, int timeout)
5333 uint8_t *smp_request = NULL, *smp_response = NULL;
5334 int request_size = 0, response_size = 0;
5335 int fd_request = 0, fd_response = 0;
5336 char *datastr = NULL;
5337 struct get_hook hook;
5342 * Note that at the moment we don't support sending SMP CCBs to
5343 * devices that aren't probed by CAM.
5345 ccb = cam_getccb(device);
5347 warnx("%s: error allocating CCB", __func__);
5351 bzero(&(&ccb->ccb_h)[1],
5352 sizeof(union ccb) - sizeof(struct ccb_hdr));
5354 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5357 arglist |= CAM_ARG_CMD_IN;
5358 response_size = strtol(optarg, NULL, 0);
5359 if (response_size <= 0) {
5360 warnx("invalid number of response bytes %d",
5363 goto smpcmd_bailout;
5365 hook.argc = argc - optind;
5366 hook.argv = argv + optind;
5369 datastr = cget(&hook, NULL);
5371 * If the user supplied "-" instead of a format, he
5372 * wants the data to be written to stdout.
5374 if ((datastr != NULL)
5375 && (datastr[0] == '-'))
5378 smp_response = (u_int8_t *)malloc(response_size);
5379 if (smp_response == NULL) {
5380 warn("can't malloc memory for SMP response");
5382 goto smpcmd_bailout;
5386 arglist |= CAM_ARG_CMD_OUT;
5387 request_size = strtol(optarg, NULL, 0);
5388 if (request_size <= 0) {
5389 warnx("invalid number of request bytes %d",
5392 goto smpcmd_bailout;
5394 hook.argc = argc - optind;
5395 hook.argv = argv + optind;
5397 datastr = cget(&hook, NULL);
5398 smp_request = (u_int8_t *)malloc(request_size);
5399 if (smp_request == NULL) {
5400 warn("can't malloc memory for SMP request");
5402 goto smpcmd_bailout;
5404 bzero(smp_request, request_size);
5406 * If the user supplied "-" instead of a format, he
5407 * wants the data to be read from stdin.
5409 if ((datastr != NULL)
5410 && (datastr[0] == '-'))
5413 buff_encode_visit(smp_request, request_size,
5424 * If fd_data is set, and we're writing to the device, we need to
5425 * read the data the user wants written from stdin.
5427 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
5429 int amt_to_read = request_size;
5430 u_int8_t *buf_ptr = smp_request;
5432 for (amt_read = 0; amt_to_read > 0;
5433 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
5434 if (amt_read == -1) {
5435 warn("error reading data from stdin");
5437 goto smpcmd_bailout;
5439 amt_to_read -= amt_read;
5440 buf_ptr += amt_read;
5444 if (((arglist & CAM_ARG_CMD_IN) == 0)
5445 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
5446 warnx("%s: need both the request (-r) and response (-R) "
5447 "arguments", __func__);
5449 goto smpcmd_bailout;
5452 flags |= CAM_DEV_QFRZDIS;
5454 cam_fill_smpio(&ccb->smpio,
5455 /*retries*/ retry_count,
5458 /*smp_request*/ smp_request,
5459 /*smp_request_len*/ request_size,
5460 /*smp_response*/ smp_response,
5461 /*smp_response_len*/ response_size,
5462 /*timeout*/ timeout ? timeout : 5000);
5464 ccb->smpio.flags = SMP_FLAG_NONE;
5466 if (((retval = cam_send_ccb(device, ccb)) < 0)
5467 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
5468 const char warnstr[] = "error sending command";
5475 if (arglist & CAM_ARG_VERBOSE) {
5476 cam_error_print(device, ccb, CAM_ESF_ALL,
5477 CAM_EPF_ALL, stderr);
5481 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
5482 && (response_size > 0)) {
5483 if (fd_response == 0) {
5484 buff_decode_visit(smp_response, response_size,
5485 datastr, arg_put, NULL);
5486 fprintf(stdout, "\n");
5488 ssize_t amt_written;
5489 int amt_to_write = response_size;
5490 u_int8_t *buf_ptr = smp_response;
5492 for (amt_written = 0; (amt_to_write > 0) &&
5493 (amt_written = write(STDOUT_FILENO, buf_ptr,
5494 amt_to_write)) > 0;){
5495 amt_to_write -= amt_written;
5496 buf_ptr += amt_written;
5498 if (amt_written == -1) {
5499 warn("error writing data to stdout");
5501 goto smpcmd_bailout;
5502 } else if ((amt_written == 0)
5503 && (amt_to_write > 0)) {
5504 warnx("only wrote %u bytes out of %u",
5505 response_size - amt_to_write,
5514 if (smp_request != NULL)
5517 if (smp_response != NULL)
5524 smpreportgeneral(struct cam_device *device, int argc, char **argv,
5525 char *combinedopt, int retry_count, int timeout)
5528 struct smp_report_general_request *request = NULL;
5529 struct smp_report_general_response *response = NULL;
5530 struct sbuf *sb = NULL;
5532 int c, long_response = 0;
5536 * Note that at the moment we don't support sending SMP CCBs to
5537 * devices that aren't probed by CAM.
5539 ccb = cam_getccb(device);
5541 warnx("%s: error allocating CCB", __func__);
5545 bzero(&(&ccb->ccb_h)[1],
5546 sizeof(union ccb) - sizeof(struct ccb_hdr));
5548 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5557 request = malloc(sizeof(*request));
5558 if (request == NULL) {
5559 warn("%s: unable to allocate %zd bytes", __func__,
5565 response = malloc(sizeof(*response));
5566 if (response == NULL) {
5567 warn("%s: unable to allocate %zd bytes", __func__,
5574 smp_report_general(&ccb->smpio,
5578 /*request_len*/ sizeof(*request),
5579 (uint8_t *)response,
5580 /*response_len*/ sizeof(*response),
5581 /*long_response*/ long_response,
5584 if (((retval = cam_send_ccb(device, ccb)) < 0)
5585 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
5586 const char warnstr[] = "error sending command";
5593 if (arglist & CAM_ARG_VERBOSE) {
5594 cam_error_print(device, ccb, CAM_ESF_ALL,
5595 CAM_EPF_ALL, stderr);
5602 * If the device supports the long response bit, try again and see
5603 * if we can get all of the data.
5605 if ((response->long_response & SMP_RG_LONG_RESPONSE)
5606 && (long_response == 0)) {
5607 ccb->ccb_h.status = CAM_REQ_INPROG;
5608 bzero(&(&ccb->ccb_h)[1],
5609 sizeof(union ccb) - sizeof(struct ccb_hdr));
5615 * XXX KDM detect and decode SMP errors here.
5617 sb = sbuf_new_auto();
5619 warnx("%s: error allocating sbuf", __func__);
5623 smp_report_general_sbuf(response, sizeof(*response), sb);
5625 if (sbuf_finish(sb) != 0) {
5626 warnx("%s: sbuf_finish", __func__);
5630 printf("%s", sbuf_data(sb));
5636 if (request != NULL)
5639 if (response != NULL)
5648 static struct camcontrol_opts phy_ops[] = {
5649 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
5650 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
5651 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
5652 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
5653 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
5654 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
5655 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
5656 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
5657 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
5662 smpphycontrol(struct cam_device *device, int argc, char **argv,
5663 char *combinedopt, int retry_count, int timeout)
5666 struct smp_phy_control_request *request = NULL;
5667 struct smp_phy_control_response *response = NULL;
5668 int long_response = 0;
5671 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
5673 uint64_t attached_dev_name = 0;
5674 int dev_name_set = 0;
5675 uint32_t min_plr = 0, max_plr = 0;
5676 uint32_t pp_timeout_val = 0;
5677 int slumber_partial = 0;
5678 int set_pp_timeout_val = 0;
5682 * Note that at the moment we don't support sending SMP CCBs to
5683 * devices that aren't probed by CAM.
5685 ccb = cam_getccb(device);
5687 warnx("%s: error allocating CCB", __func__);
5691 bzero(&(&ccb->ccb_h)[1],
5692 sizeof(union ccb) - sizeof(struct ccb_hdr));
5694 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5702 if (strcasecmp(optarg, "enable") == 0)
5704 else if (strcasecmp(optarg, "disable") == 0)
5707 warnx("%s: Invalid argument %s", __func__,
5714 slumber_partial |= enable <<
5715 SMP_PC_SAS_SLUMBER_SHIFT;
5718 slumber_partial |= enable <<
5719 SMP_PC_SAS_PARTIAL_SHIFT;
5722 slumber_partial |= enable <<
5723 SMP_PC_SATA_SLUMBER_SHIFT;
5726 slumber_partial |= enable <<
5727 SMP_PC_SATA_PARTIAL_SHIFT;
5730 warnx("%s: programmer error", __func__);
5733 break; /*NOTREACHED*/
5738 attached_dev_name = (uintmax_t)strtoumax(optarg,
5747 * We don't do extensive checking here, so this
5748 * will continue to work when new speeds come out.
5750 min_plr = strtoul(optarg, NULL, 0);
5752 || (min_plr > 0xf)) {
5753 warnx("%s: invalid link rate %x",
5761 * We don't do extensive checking here, so this
5762 * will continue to work when new speeds come out.
5764 max_plr = strtoul(optarg, NULL, 0);
5766 || (max_plr > 0xf)) {
5767 warnx("%s: invalid link rate %x",
5774 camcontrol_optret optreturn;
5775 cam_argmask argnums;
5778 if (phy_op_set != 0) {
5779 warnx("%s: only one phy operation argument "
5780 "(-o) allowed", __func__);
5788 * Allow the user to specify the phy operation
5789 * numerically, as well as with a name. This will
5790 * future-proof it a bit, so options that are added
5791 * in future specs can be used.
5793 if (isdigit(optarg[0])) {
5794 phy_operation = strtoul(optarg, NULL, 0);
5795 if ((phy_operation == 0)
5796 || (phy_operation > 0xff)) {
5797 warnx("%s: invalid phy operation %#x",
5798 __func__, phy_operation);
5804 optreturn = getoption(phy_ops, optarg, &phy_operation,
5807 if (optreturn == CC_OR_AMBIGUOUS) {
5808 warnx("%s: ambiguous option %s", __func__,
5813 } else if (optreturn == CC_OR_NOT_FOUND) {
5814 warnx("%s: option %s not found", __func__,
5826 pp_timeout_val = strtoul(optarg, NULL, 0);
5827 if (pp_timeout_val > 15) {
5828 warnx("%s: invalid partial pathway timeout "
5829 "value %u, need a value less than 16",
5830 __func__, pp_timeout_val);
5834 set_pp_timeout_val = 1;
5842 warnx("%s: a PHY (-p phy) argument is required",__func__);
5847 if (((dev_name_set != 0)
5848 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
5849 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
5850 && (dev_name_set == 0))) {
5851 warnx("%s: -d name and -o setdevname arguments both "
5852 "required to set device name", __func__);
5857 request = malloc(sizeof(*request));
5858 if (request == NULL) {
5859 warn("%s: unable to allocate %zd bytes", __func__,
5865 response = malloc(sizeof(*response));
5866 if (response == NULL) {
5867 warn("%s: unable to allocate %zd bytes", __func__,
5873 smp_phy_control(&ccb->smpio,
5878 (uint8_t *)response,
5881 /*expected_exp_change_count*/ 0,
5884 (set_pp_timeout_val != 0) ? 1 : 0,
5892 if (((retval = cam_send_ccb(device, ccb)) < 0)
5893 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
5894 const char warnstr[] = "error sending command";
5901 if (arglist & CAM_ARG_VERBOSE) {
5903 * Use CAM_EPF_NORMAL so we only get one line of
5904 * SMP command decoding.
5906 cam_error_print(device, ccb, CAM_ESF_ALL,
5907 CAM_EPF_NORMAL, stderr);
5913 /* XXX KDM print out something here for success? */
5918 if (request != NULL)
5921 if (response != NULL)
5928 smpmaninfo(struct cam_device *device, int argc, char **argv,
5929 char *combinedopt, int retry_count, int timeout)
5932 struct smp_report_manuf_info_request request;
5933 struct smp_report_manuf_info_response response;
5934 struct sbuf *sb = NULL;
5935 int long_response = 0;
5940 * Note that at the moment we don't support sending SMP CCBs to
5941 * devices that aren't probed by CAM.
5943 ccb = cam_getccb(device);
5945 warnx("%s: error allocating CCB", __func__);
5949 bzero(&(&ccb->ccb_h)[1],
5950 sizeof(union ccb) - sizeof(struct ccb_hdr));
5952 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5961 bzero(&request, sizeof(request));
5962 bzero(&response, sizeof(response));
5964 smp_report_manuf_info(&ccb->smpio,
5969 (uint8_t *)&response,
5974 if (((retval = cam_send_ccb(device, ccb)) < 0)
5975 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
5976 const char warnstr[] = "error sending command";
5983 if (arglist & CAM_ARG_VERBOSE) {
5984 cam_error_print(device, ccb, CAM_ESF_ALL,
5985 CAM_EPF_ALL, stderr);
5991 sb = sbuf_new_auto();
5993 warnx("%s: error allocating sbuf", __func__);
5997 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
5999 if (sbuf_finish(sb) != 0) {
6000 warnx("%s: sbuf_finish", __func__);
6004 printf("%s", sbuf_data(sb));
6018 getdevid(struct cam_devitem *item)
6021 union ccb *ccb = NULL;
6023 struct cam_device *dev;
6025 dev = cam_open_btl(item->dev_match.path_id,
6026 item->dev_match.target_id,
6027 item->dev_match.target_lun, O_RDWR, NULL);
6030 warnx("%s", cam_errbuf);
6035 item->device_id_len = 0;
6037 ccb = cam_getccb(dev);
6039 warnx("%s: error allocating CCB", __func__);
6044 bzero(&(&ccb->ccb_h)[1],
6045 sizeof(union ccb) - sizeof(struct ccb_hdr));
6048 * On the first try, we just probe for the size of the data, and
6049 * then allocate that much memory and try again.
6052 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
6053 ccb->ccb_h.flags = CAM_DIR_IN;
6054 ccb->cdai.flags = 0;
6055 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
6056 ccb->cdai.bufsiz = item->device_id_len;
6057 if (item->device_id_len != 0)
6058 ccb->cdai.buf = (uint8_t *)item->device_id;
6060 if (cam_send_ccb(dev, ccb) < 0) {
6061 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
6066 if (ccb->ccb_h.status != CAM_REQ_CMP) {
6067 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
6072 if (item->device_id_len == 0) {
6074 * This is our first time through. Allocate the buffer,
6075 * and then go back to get the data.
6077 if (ccb->cdai.provsiz == 0) {
6078 warnx("%s: invalid .provsiz field returned with "
6079 "XPT_GDEV_ADVINFO CCB", __func__);
6083 item->device_id_len = ccb->cdai.provsiz;
6084 item->device_id = malloc(item->device_id_len);
6085 if (item->device_id == NULL) {
6086 warn("%s: unable to allocate %d bytes", __func__,
6087 item->device_id_len);
6091 ccb->ccb_h.status = CAM_REQ_INPROG;
6097 cam_close_device(dev);
6106 * XXX KDM merge this code with getdevtree()?
6109 buildbusdevlist(struct cam_devlist *devlist)
6112 int bufsize, fd = -1;
6113 struct dev_match_pattern *patterns;
6114 struct cam_devitem *item = NULL;
6115 int skip_device = 0;
6118 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
6119 warn("couldn't open %s", XPT_DEVICE);
6123 bzero(&ccb, sizeof(union ccb));
6125 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
6126 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
6127 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
6129 ccb.ccb_h.func_code = XPT_DEV_MATCH;
6130 bufsize = sizeof(struct dev_match_result) * 100;
6131 ccb.cdm.match_buf_len = bufsize;
6132 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
6133 if (ccb.cdm.matches == NULL) {
6134 warnx("can't malloc memory for matches");
6138 ccb.cdm.num_matches = 0;
6139 ccb.cdm.num_patterns = 2;
6140 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
6141 ccb.cdm.num_patterns;
6143 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
6144 if (patterns == NULL) {
6145 warnx("can't malloc memory for patterns");
6150 ccb.cdm.patterns = patterns;
6151 bzero(patterns, ccb.cdm.pattern_buf_len);
6153 patterns[0].type = DEV_MATCH_DEVICE;
6154 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
6155 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
6156 patterns[1].type = DEV_MATCH_PERIPH;
6157 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
6158 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
6161 * We do the ioctl multiple times if necessary, in case there are
6162 * more than 100 nodes in the EDT.
6167 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
6168 warn("error sending CAMIOCOMMAND ioctl");
6173 if ((ccb.ccb_h.status != CAM_REQ_CMP)
6174 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
6175 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
6176 warnx("got CAM error %#x, CDM error %d\n",
6177 ccb.ccb_h.status, ccb.cdm.status);
6182 for (i = 0; i < ccb.cdm.num_matches; i++) {
6183 switch (ccb.cdm.matches[i].type) {
6184 case DEV_MATCH_DEVICE: {
6185 struct device_match_result *dev_result;
6188 &ccb.cdm.matches[i].result.device_result;
6190 if (dev_result->flags &
6191 DEV_RESULT_UNCONFIGURED) {
6197 item = malloc(sizeof(*item));
6199 warn("%s: unable to allocate %zd bytes",
6200 __func__, sizeof(*item));
6204 bzero(item, sizeof(*item));
6205 bcopy(dev_result, &item->dev_match,
6206 sizeof(*dev_result));
6207 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
6210 if (getdevid(item) != 0) {
6216 case DEV_MATCH_PERIPH: {
6217 struct periph_match_result *periph_result;
6220 &ccb.cdm.matches[i].result.periph_result;
6222 if (skip_device != 0)
6224 item->num_periphs++;
6225 item->periph_matches = realloc(
6226 item->periph_matches,
6228 sizeof(struct periph_match_result));
6229 if (item->periph_matches == NULL) {
6230 warn("%s: error allocating periph "
6235 bcopy(periph_result, &item->periph_matches[
6236 item->num_periphs - 1],
6237 sizeof(*periph_result));
6241 fprintf(stderr, "%s: unexpected match "
6242 "type %d\n", __func__,
6243 ccb.cdm.matches[i].type);
6246 break; /*NOTREACHED*/
6249 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
6250 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
6258 free(ccb.cdm.matches);
6261 freebusdevlist(devlist);
6267 freebusdevlist(struct cam_devlist *devlist)
6269 struct cam_devitem *item, *item2;
6271 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
6272 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
6274 free(item->device_id);
6275 free(item->periph_matches);
6280 static struct cam_devitem *
6281 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
6283 struct cam_devitem *item;
6285 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
6289 * XXX KDM look for LUN IDs as well?
6291 item_addr = scsi_get_devid(item->device_id,
6292 item->device_id_len,
6293 scsi_devid_is_sas_target);
6294 if (item_addr == NULL)
6297 if (scsi_8btou64(item_addr) == sasaddr)
6305 smpphylist(struct cam_device *device, int argc, char **argv,
6306 char *combinedopt, int retry_count, int timeout)
6308 struct smp_report_general_request *rgrequest = NULL;
6309 struct smp_report_general_response *rgresponse = NULL;
6310 struct smp_discover_request *disrequest = NULL;
6311 struct smp_discover_response *disresponse = NULL;
6312 struct cam_devlist devlist;
6314 int long_response = 0;
6321 * Note that at the moment we don't support sending SMP CCBs to
6322 * devices that aren't probed by CAM.
6324 ccb = cam_getccb(device);
6326 warnx("%s: error allocating CCB", __func__);
6330 bzero(&(&ccb->ccb_h)[1],
6331 sizeof(union ccb) - sizeof(struct ccb_hdr));
6332 STAILQ_INIT(&devlist.dev_queue);
6334 rgrequest = malloc(sizeof(*rgrequest));
6335 if (rgrequest == NULL) {
6336 warn("%s: unable to allocate %zd bytes", __func__,
6337 sizeof(*rgrequest));
6342 rgresponse = malloc(sizeof(*rgresponse));
6343 if (rgresponse == NULL) {
6344 warn("%s: unable to allocate %zd bytes", __func__,
6345 sizeof(*rgresponse));
6350 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6363 smp_report_general(&ccb->smpio,
6367 /*request_len*/ sizeof(*rgrequest),
6368 (uint8_t *)rgresponse,
6369 /*response_len*/ sizeof(*rgresponse),
6370 /*long_response*/ long_response,
6373 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6375 if (((retval = cam_send_ccb(device, ccb)) < 0)
6376 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
6377 const char warnstr[] = "error sending command";
6384 if (arglist & CAM_ARG_VERBOSE) {
6385 cam_error_print(device, ccb, CAM_ESF_ALL,
6386 CAM_EPF_ALL, stderr);
6392 num_phys = rgresponse->num_phys;
6394 if (num_phys == 0) {
6396 fprintf(stdout, "%s: No Phys reported\n", __func__);
6401 devlist.path_id = device->path_id;
6403 retval = buildbusdevlist(&devlist);
6408 fprintf(stdout, "%d PHYs:\n", num_phys);
6409 fprintf(stdout, "PHY Attached SAS Address\n");
6412 disrequest = malloc(sizeof(*disrequest));
6413 if (disrequest == NULL) {
6414 warn("%s: unable to allocate %zd bytes", __func__,
6415 sizeof(*disrequest));
6420 disresponse = malloc(sizeof(*disresponse));
6421 if (disresponse == NULL) {
6422 warn("%s: unable to allocate %zd bytes", __func__,
6423 sizeof(*disresponse));
6428 for (i = 0; i < num_phys; i++) {
6429 struct cam_devitem *item;
6430 struct device_match_result *dev_match;
6431 char vendor[16], product[48], revision[16];
6435 bzero(&(&ccb->ccb_h)[1],
6436 sizeof(union ccb) - sizeof(struct ccb_hdr));
6438 ccb->ccb_h.status = CAM_REQ_INPROG;
6439 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6441 smp_discover(&ccb->smpio,
6445 sizeof(*disrequest),
6446 (uint8_t *)disresponse,
6447 sizeof(*disresponse),
6449 /*ignore_zone_group*/ 0,
6453 if (((retval = cam_send_ccb(device, ccb)) < 0)
6454 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
6455 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
6456 const char warnstr[] = "error sending command";
6463 if (arglist & CAM_ARG_VERBOSE) {
6464 cam_error_print(device, ccb, CAM_ESF_ALL,
6465 CAM_EPF_ALL, stderr);
6471 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
6473 fprintf(stdout, "%3d <vacant>\n", i);
6477 item = findsasdevice(&devlist,
6478 scsi_8btou64(disresponse->attached_sas_address));
6481 || (item != NULL)) {
6482 fprintf(stdout, "%3d 0x%016jx", i,
6483 (uintmax_t)scsi_8btou64(
6484 disresponse->attached_sas_address));
6486 fprintf(stdout, "\n");
6489 } else if (quiet != 0)
6492 dev_match = &item->dev_match;
6494 if (dev_match->protocol == PROTO_SCSI) {
6495 cam_strvis(vendor, dev_match->inq_data.vendor,
6496 sizeof(dev_match->inq_data.vendor),
6498 cam_strvis(product, dev_match->inq_data.product,
6499 sizeof(dev_match->inq_data.product),
6501 cam_strvis(revision, dev_match->inq_data.revision,
6502 sizeof(dev_match->inq_data.revision),
6504 sprintf(tmpstr, "<%s %s %s>", vendor, product,
6506 } else if ((dev_match->protocol == PROTO_ATA)
6507 || (dev_match->protocol == PROTO_SATAPM)) {
6508 cam_strvis(product, dev_match->ident_data.model,
6509 sizeof(dev_match->ident_data.model),
6511 cam_strvis(revision, dev_match->ident_data.revision,
6512 sizeof(dev_match->ident_data.revision),
6514 sprintf(tmpstr, "<%s %s>", product, revision);
6516 sprintf(tmpstr, "<>");
6518 fprintf(stdout, " %-33s ", tmpstr);
6521 * If we have 0 periphs, that's a bug...
6523 if (item->num_periphs == 0) {
6524 fprintf(stdout, "\n");
6528 fprintf(stdout, "(");
6529 for (j = 0; j < item->num_periphs; j++) {
6531 fprintf(stdout, ",");
6533 fprintf(stdout, "%s%d",
6534 item->periph_matches[j].periph_name,
6535 item->periph_matches[j].unit_number);
6538 fprintf(stdout, ")\n");
6552 freebusdevlist(&devlist);
6558 atapm(struct cam_device *device, int argc, char **argv,
6559 char *combinedopt, int retry_count, int timeout)
6567 ccb = cam_getccb(device);
6570 warnx("%s: error allocating ccb", __func__);
6574 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6583 if (strcmp(argv[1], "idle") == 0) {
6585 cmd = ATA_IDLE_IMMEDIATE;
6588 } else if (strcmp(argv[1], "standby") == 0) {
6590 cmd = ATA_STANDBY_IMMEDIATE;
6592 cmd = ATA_STANDBY_CMD;
6600 else if (t <= (240 * 5))
6602 else if (t <= (252 * 5))
6603 /* special encoding for 21 minutes */
6605 else if (t <= (11 * 30 * 60))
6606 sc = (t - 1) / (30 * 60) + 241;
6610 cam_fill_ataio(&ccb->ataio,
6613 /*flags*/CAM_DIR_NONE,
6617 timeout ? timeout : 30 * 1000);
6618 ata_28bit_cmd(&ccb->ataio, cmd, 0, 0, sc);
6620 /* Disable freezing the device queue */
6621 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6623 if (arglist & CAM_ARG_ERR_RECOVER)
6624 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6626 if (cam_send_ccb(device, ccb) < 0) {
6627 warn("error sending command");
6629 if (arglist & CAM_ARG_VERBOSE)
6630 cam_error_print(device, ccb, CAM_ESF_ALL,
6631 CAM_EPF_ALL, stderr);
6637 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6638 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6647 #endif /* MINIMALISTIC */
6650 usage(int printlong)
6653 fprintf(printlong ? stdout : stderr,
6654 "usage: camcontrol <command> [device id][generic args][command args]\n"
6655 " camcontrol devlist [-v]\n"
6656 #ifndef MINIMALISTIC
6657 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
6658 " camcontrol tur [dev_id][generic args]\n"
6659 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
6660 " camcontrol identify [dev_id][generic args] [-v]\n"
6661 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
6662 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
6664 " camcontrol start [dev_id][generic args]\n"
6665 " camcontrol stop [dev_id][generic args]\n"
6666 " camcontrol load [dev_id][generic args]\n"
6667 " camcontrol eject [dev_id][generic args]\n"
6668 #endif /* MINIMALISTIC */
6669 " camcontrol rescan <all | bus[:target:lun]>\n"
6670 " camcontrol reset <all | bus[:target:lun]>\n"
6671 #ifndef MINIMALISTIC
6672 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
6673 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
6674 " [-P pagectl][-e | -b][-d]\n"
6675 " camcontrol cmd [dev_id][generic args]\n"
6676 " <-a cmd [args] | -c cmd [args]>\n"
6677 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
6678 " camcontrol smpcmd [dev_id][generic args]\n"
6679 " <-r len fmt [args]> <-R len fmt [args]>\n"
6680 " camcontrol smprg [dev_id][generic args][-l]\n"
6681 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
6682 " [-o operation][-d name][-m rate][-M rate]\n"
6683 " [-T pp_timeout][-a enable|disable]\n"
6684 " [-A enable|disable][-s enable|disable]\n"
6685 " [-S enable|disable]\n"
6686 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
6687 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
6688 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
6689 " <all|bus[:target[:lun]]|off>\n"
6690 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
6691 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
6692 " [-D <enable|disable>][-M mode][-O offset]\n"
6693 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
6694 " [-U][-W bus_width]\n"
6695 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
6696 " camcontrol idle [dev_id][generic args][-t time]\n"
6697 " camcontrol standby [dev_id][generic args][-t time]\n"
6698 " camcontrol sleep [dev_id][generic args]\n"
6699 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-y][-s]\n"
6700 " camcontrol security [dev_id][generic args]\n"
6701 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
6702 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
6703 " [-U <user|master>] [-y]\n"
6704 #endif /* MINIMALISTIC */
6705 " camcontrol help\n");
6708 #ifndef MINIMALISTIC
6710 "Specify one of the following options:\n"
6711 "devlist list all CAM devices\n"
6712 "periphlist list all CAM peripheral drivers attached to a device\n"
6713 "tur send a test unit ready to the named device\n"
6714 "inquiry send a SCSI inquiry command to the named device\n"
6715 "identify send a ATA identify command to the named device\n"
6716 "reportluns send a SCSI report luns command to the device\n"
6717 "readcap send a SCSI read capacity command to the device\n"
6718 "start send a Start Unit command to the device\n"
6719 "stop send a Stop Unit command to the device\n"
6720 "load send a Start Unit command to the device with the load bit set\n"
6721 "eject send a Stop Unit command to the device with the eject bit set\n"
6722 "rescan rescan all busses, the given bus, or bus:target:lun\n"
6723 "reset reset all busses, the given bus, or bus:target:lun\n"
6724 "defects read the defect list of the specified device\n"
6725 "modepage display or edit (-e) the given mode page\n"
6726 "cmd send the given SCSI command, may need -i or -o as well\n"
6727 "smpcmd send the given SMP command, requires -o and -i\n"
6728 "smprg send the SMP Report General command\n"
6729 "smppc send the SMP PHY Control command, requires -p\n"
6730 "smpphylist display phys attached to a SAS expander\n"
6731 "smpmaninfo send the SMP Report Manufacturer Info command\n"
6732 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
6733 "tags report or set the number of transaction slots for a device\n"
6734 "negotiate report or set device negotiation parameters\n"
6735 "format send the SCSI FORMAT UNIT command to the named device\n"
6736 "idle send the ATA IDLE command to the named device\n"
6737 "standby send the ATA STANDBY command to the named device\n"
6738 "sleep send the ATA SLEEP command to the named device\n"
6739 "fwdownload program firmware of the named device with the given image"
6740 "security report or send ATA security commands to the named device\n"
6741 "help this message\n"
6742 "Device Identifiers:\n"
6743 "bus:target specify the bus and target, lun defaults to 0\n"
6744 "bus:target:lun specify the bus, target and lun\n"
6745 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
6746 "Generic arguments:\n"
6747 "-v be verbose, print out sense information\n"
6748 "-t timeout command timeout in seconds, overrides default timeout\n"
6749 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
6750 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
6751 "-E have the kernel attempt to perform SCSI error recovery\n"
6752 "-C count specify the SCSI command retry count (needs -E to work)\n"
6753 "modepage arguments:\n"
6754 "-l list all available mode pages\n"
6755 "-m page specify the mode page to view or edit\n"
6756 "-e edit the specified mode page\n"
6757 "-b force view to binary mode\n"
6758 "-d disable block descriptors for mode sense\n"
6759 "-P pgctl page control field 0-3\n"
6760 "defects arguments:\n"
6761 "-f format specify defect list format (block, bfi or phys)\n"
6762 "-G get the grown defect list\n"
6763 "-P get the permanent defect list\n"
6764 "inquiry arguments:\n"
6765 "-D get the standard inquiry data\n"
6766 "-S get the serial number\n"
6767 "-R get the transfer rate, etc.\n"
6768 "reportluns arguments:\n"
6769 "-c only report a count of available LUNs\n"
6770 "-l only print out luns, and not a count\n"
6771 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
6772 "readcap arguments\n"
6773 "-b only report the blocksize\n"
6774 "-h human readable device size, base 2\n"
6775 "-H human readable device size, base 10\n"
6776 "-N print the number of blocks instead of last block\n"
6777 "-q quiet, print numbers only\n"
6778 "-s only report the last block/device size\n"
6780 "-c cdb [args] specify the SCSI CDB\n"
6781 "-i len fmt specify input data and input data format\n"
6782 "-o len fmt [args] specify output data and output data fmt\n"
6783 "smpcmd arguments:\n"
6784 "-r len fmt [args] specify the SMP command to be sent\n"
6785 "-R len fmt [args] specify SMP response format\n"
6786 "smprg arguments:\n"
6787 "-l specify the long response format\n"
6788 "smppc arguments:\n"
6789 "-p phy specify the PHY to operate on\n"
6790 "-l specify the long request/response format\n"
6791 "-o operation specify the phy control operation\n"
6792 "-d name set the attached device name\n"
6793 "-m rate set the minimum physical link rate\n"
6794 "-M rate set the maximum physical link rate\n"
6795 "-T pp_timeout set the partial pathway timeout value\n"
6796 "-a enable|disable enable or disable SATA slumber\n"
6797 "-A enable|disable enable or disable SATA partial phy power\n"
6798 "-s enable|disable enable or disable SAS slumber\n"
6799 "-S enable|disable enable or disable SAS partial phy power\n"
6800 "smpphylist arguments:\n"
6801 "-l specify the long response format\n"
6802 "-q only print phys with attached devices\n"
6803 "smpmaninfo arguments:\n"
6804 "-l specify the long response format\n"
6805 "debug arguments:\n"
6806 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
6807 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
6808 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
6809 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
6811 "-N tags specify the number of tags to use for this device\n"
6812 "-q be quiet, don't report the number of tags\n"
6813 "-v report a number of tag-related parameters\n"
6814 "negotiate arguments:\n"
6815 "-a send a test unit ready after negotiation\n"
6816 "-c report/set current negotiation settings\n"
6817 "-D <arg> \"enable\" or \"disable\" disconnection\n"
6818 "-M mode set ATA mode\n"
6819 "-O offset set command delay offset\n"
6820 "-q be quiet, don't report anything\n"
6821 "-R syncrate synchronization rate in MHz\n"
6822 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
6823 "-U report/set user negotiation settings\n"
6824 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
6825 "-v also print a Path Inquiry CCB for the controller\n"
6826 "format arguments:\n"
6827 "-q be quiet, don't print status messages\n"
6828 "-r run in report only mode\n"
6829 "-w don't send immediate format command\n"
6830 "-y don't ask any questions\n"
6831 "idle/standby arguments:\n"
6832 "-t <arg> number of seconds before respective state.\n"
6833 "fwdownload arguments:\n"
6834 "-f fw_image path to firmware image file\n"
6835 "-y don't ask any questions\n"
6836 "-s run in simulation mode\n"
6837 "-v print info for every firmware segment sent to device\n"
6838 "security arguments:\n"
6839 "-d pwd disable security using the given password for the selected\n"
6841 "-e pwd erase the device using the given pwd for the selected user\n"
6842 "-f freeze the security configuration of the specified device\n"
6843 "-h pwd enhanced erase the device using the given pwd for the\n"
6845 "-k pwd unlock the device using the given pwd for the selected\n"
6847 "-l <high|maximum> specifies which security level to set: high or maximum\n"
6848 "-q be quiet, do not print any status messages\n"
6849 "-s pwd password the device (enable security) using the given\n"
6850 " pwd for the selected user\n"
6851 "-T timeout overrides the timeout (seconds) used for erase operation\n"
6852 "-U <user|master> specifies which user to set: user or master\n"
6853 "-y don't ask any questions\n"
6855 #endif /* MINIMALISTIC */
6859 main(int argc, char **argv)
6862 char *device = NULL;
6864 struct cam_device *cam_dev = NULL;
6865 int timeout = 0, retry_count = 1;
6866 camcontrol_optret optreturn;
6868 const char *mainopt = "C:En:t:u:v";
6869 const char *subopt = NULL;
6870 char combinedopt[256];
6871 int error = 0, optstart = 2;
6873 #ifndef MINIMALISTIC
6874 int bus, target, lun;
6875 #endif /* MINIMALISTIC */
6877 cmdlist = CAM_CMD_NONE;
6878 arglist = CAM_ARG_NONE;
6886 * Get the base option.
6888 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
6890 if (optreturn == CC_OR_AMBIGUOUS) {
6891 warnx("ambiguous option %s", argv[1]);
6894 } else if (optreturn == CC_OR_NOT_FOUND) {
6895 warnx("option %s not found", argv[1]);
6901 * Ahh, getopt(3) is a pain.
6903 * This is a gross hack. There really aren't many other good
6904 * options (excuse the pun) for parsing options in a situation like
6905 * this. getopt is kinda braindead, so you end up having to run
6906 * through the options twice, and give each invocation of getopt
6907 * the option string for the other invocation.
6909 * You would think that you could just have two groups of options.
6910 * The first group would get parsed by the first invocation of
6911 * getopt, and the second group would get parsed by the second
6912 * invocation of getopt. It doesn't quite work out that way. When
6913 * the first invocation of getopt finishes, it leaves optind pointing
6914 * to the argument _after_ the first argument in the second group.
6915 * So when the second invocation of getopt comes around, it doesn't
6916 * recognize the first argument it gets and then bails out.
6918 * A nice alternative would be to have a flag for getopt that says
6919 * "just keep parsing arguments even when you encounter an unknown
6920 * argument", but there isn't one. So there's no real clean way to
6921 * easily parse two sets of arguments without having one invocation
6922 * of getopt know about the other.
6924 * Without this hack, the first invocation of getopt would work as
6925 * long as the generic arguments are first, but the second invocation
6926 * (in the subfunction) would fail in one of two ways. In the case
6927 * where you don't set optreset, it would fail because optind may be
6928 * pointing to the argument after the one it should be pointing at.
6929 * In the case where you do set optreset, and reset optind, it would
6930 * fail because getopt would run into the first set of options, which
6931 * it doesn't understand.
6933 * All of this would "sort of" work if you could somehow figure out
6934 * whether optind had been incremented one option too far. The
6935 * mechanics of that, however, are more daunting than just giving
6936 * both invocations all of the expect options for either invocation.
6938 * Needless to say, I wouldn't mind if someone invented a better
6939 * (non-GPL!) command line parsing interface than getopt. I
6940 * wouldn't mind if someone added more knobs to getopt to make it
6941 * work better. Who knows, I may talk myself into doing it someday,
6942 * if the standards weenies let me. As it is, it just leads to
6943 * hackery like this and causes people to avoid it in some cases.
6945 * KDM, September 8th, 1998
6948 sprintf(combinedopt, "%s%s", mainopt, subopt);
6950 sprintf(combinedopt, "%s", mainopt);
6953 * For these options we do not parse optional device arguments and
6954 * we do not open a passthrough device.
6956 if ((cmdlist == CAM_CMD_RESCAN)
6957 || (cmdlist == CAM_CMD_RESET)
6958 || (cmdlist == CAM_CMD_DEVTREE)
6959 || (cmdlist == CAM_CMD_USAGE)
6960 || (cmdlist == CAM_CMD_DEBUG))
6963 #ifndef MINIMALISTIC
6965 && (argc > 2 && argv[2][0] != '-')) {
6969 if (isdigit(argv[2][0])) {
6970 /* device specified as bus:target[:lun] */
6971 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
6973 errx(1, "numeric device specification must "
6974 "be either bus:target, or "
6976 /* default to 0 if lun was not specified */
6977 if ((arglist & CAM_ARG_LUN) == 0) {
6979 arglist |= CAM_ARG_LUN;
6983 if (cam_get_device(argv[2], name, sizeof name, &unit)
6985 errx(1, "%s", cam_errbuf);
6986 device = strdup(name);
6987 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
6991 #endif /* MINIMALISTIC */
6993 * Start getopt processing at argv[2/3], since we've already
6994 * accepted argv[1..2] as the command name, and as a possible
7000 * Now we run through the argument list looking for generic
7001 * options, and ignoring options that possibly belong to
7004 while ((c = getopt(argc, argv, combinedopt))!= -1){
7007 retry_count = strtol(optarg, NULL, 0);
7008 if (retry_count < 0)
7009 errx(1, "retry count %d is < 0",
7011 arglist |= CAM_ARG_RETRIES;
7014 arglist |= CAM_ARG_ERR_RECOVER;
7017 arglist |= CAM_ARG_DEVICE;
7019 while (isspace(*tstr) && (*tstr != '\0'))
7021 device = (char *)strdup(tstr);
7024 timeout = strtol(optarg, NULL, 0);
7026 errx(1, "invalid timeout %d", timeout);
7027 /* Convert the timeout from seconds to ms */
7029 arglist |= CAM_ARG_TIMEOUT;
7032 arglist |= CAM_ARG_UNIT;
7033 unit = strtol(optarg, NULL, 0);
7036 arglist |= CAM_ARG_VERBOSE;
7043 #ifndef MINIMALISTIC
7045 * For most commands we'll want to open the passthrough device
7046 * associated with the specified device. In the case of the rescan
7047 * commands, we don't use a passthrough device at all, just the
7048 * transport layer device.
7051 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
7052 && (((arglist & CAM_ARG_DEVICE) == 0)
7053 || ((arglist & CAM_ARG_UNIT) == 0))) {
7054 errx(1, "subcommand \"%s\" requires a valid device "
7055 "identifier", argv[1]);
7058 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
7059 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
7060 cam_open_spec_device(device,unit,O_RDWR,NULL)))
7062 errx(1,"%s", cam_errbuf);
7064 #endif /* MINIMALISTIC */
7067 * Reset optind to 2, and reset getopt, so these routines can parse
7068 * the arguments again.
7074 #ifndef MINIMALISTIC
7075 case CAM_CMD_DEVLIST:
7076 error = getdevlist(cam_dev);
7078 #endif /* MINIMALISTIC */
7079 case CAM_CMD_DEVTREE:
7080 error = getdevtree();
7082 #ifndef MINIMALISTIC
7084 error = testunitready(cam_dev, retry_count, timeout, 0);
7086 case CAM_CMD_INQUIRY:
7087 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
7088 retry_count, timeout);
7090 case CAM_CMD_IDENTIFY:
7091 error = ataidentify(cam_dev, retry_count, timeout);
7093 case CAM_CMD_STARTSTOP:
7094 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
7095 arglist & CAM_ARG_EJECT, retry_count,
7098 #endif /* MINIMALISTIC */
7099 case CAM_CMD_RESCAN:
7100 error = dorescan_or_reset(argc, argv, 1);
7103 error = dorescan_or_reset(argc, argv, 0);
7105 #ifndef MINIMALISTIC
7106 case CAM_CMD_READ_DEFECTS:
7107 error = readdefects(cam_dev, argc, argv, combinedopt,
7108 retry_count, timeout);
7110 case CAM_CMD_MODE_PAGE:
7111 modepage(cam_dev, argc, argv, combinedopt,
7112 retry_count, timeout);
7114 case CAM_CMD_SCSI_CMD:
7115 error = scsicmd(cam_dev, argc, argv, combinedopt,
7116 retry_count, timeout);
7118 case CAM_CMD_SMP_CMD:
7119 error = smpcmd(cam_dev, argc, argv, combinedopt,
7120 retry_count, timeout);
7122 case CAM_CMD_SMP_RG:
7123 error = smpreportgeneral(cam_dev, argc, argv,
7124 combinedopt, retry_count,
7127 case CAM_CMD_SMP_PC:
7128 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
7129 retry_count, timeout);
7131 case CAM_CMD_SMP_PHYLIST:
7132 error = smpphylist(cam_dev, argc, argv, combinedopt,
7133 retry_count, timeout);
7135 case CAM_CMD_SMP_MANINFO:
7136 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
7137 retry_count, timeout);
7140 error = camdebug(argc, argv, combinedopt);
7143 error = tagcontrol(cam_dev, argc, argv, combinedopt);
7146 error = ratecontrol(cam_dev, retry_count, timeout,
7147 argc, argv, combinedopt);
7149 case CAM_CMD_FORMAT:
7150 error = scsiformat(cam_dev, argc, argv,
7151 combinedopt, retry_count, timeout);
7153 case CAM_CMD_REPORTLUNS:
7154 error = scsireportluns(cam_dev, argc, argv,
7155 combinedopt, retry_count,
7158 case CAM_CMD_READCAP:
7159 error = scsireadcapacity(cam_dev, argc, argv,
7160 combinedopt, retry_count,
7164 case CAM_CMD_STANDBY:
7166 error = atapm(cam_dev, argc, argv,
7167 combinedopt, retry_count, timeout);
7169 case CAM_CMD_SECURITY:
7170 error = atasecurity(cam_dev, retry_count, timeout,
7171 argc, argv, combinedopt);
7173 case CAM_CMD_DOWNLOAD_FW:
7174 error = fwdownload(cam_dev, argc, argv, combinedopt,
7175 arglist & CAM_ARG_VERBOSE, retry_count, timeout,
7176 get_disk_type(cam_dev));
7178 #endif /* MINIMALISTIC */
7188 if (cam_dev != NULL)
7189 cam_close_device(cam_dev);