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>
36 #include <sys/endian.h>
55 #include <cam/cam_debug.h>
56 #include <cam/cam_ccb.h>
57 #include <cam/scsi/scsi_all.h>
58 #include <cam/scsi/scsi_da.h>
59 #include <cam/scsi/scsi_pass.h>
60 #include <cam/scsi/scsi_message.h>
61 #include <cam/scsi/smp_all.h>
62 #include <cam/ata/ata_all.h>
64 #include "camcontrol.h"
67 CAM_CMD_NONE = 0x00000000,
68 CAM_CMD_DEVLIST = 0x00000001,
69 CAM_CMD_TUR = 0x00000002,
70 CAM_CMD_INQUIRY = 0x00000003,
71 CAM_CMD_STARTSTOP = 0x00000004,
72 CAM_CMD_RESCAN = 0x00000005,
73 CAM_CMD_READ_DEFECTS = 0x00000006,
74 CAM_CMD_MODE_PAGE = 0x00000007,
75 CAM_CMD_SCSI_CMD = 0x00000008,
76 CAM_CMD_DEVTREE = 0x00000009,
77 CAM_CMD_USAGE = 0x0000000a,
78 CAM_CMD_DEBUG = 0x0000000b,
79 CAM_CMD_RESET = 0x0000000c,
80 CAM_CMD_FORMAT = 0x0000000d,
81 CAM_CMD_TAG = 0x0000000e,
82 CAM_CMD_RATE = 0x0000000f,
83 CAM_CMD_DETACH = 0x00000010,
84 CAM_CMD_REPORTLUNS = 0x00000011,
85 CAM_CMD_READCAP = 0x00000012,
86 CAM_CMD_IDENTIFY = 0x00000013,
87 CAM_CMD_IDLE = 0x00000014,
88 CAM_CMD_STANDBY = 0x00000015,
89 CAM_CMD_SLEEP = 0x00000016,
90 CAM_CMD_SMP_CMD = 0x00000017,
91 CAM_CMD_SMP_RG = 0x00000018,
92 CAM_CMD_SMP_PC = 0x00000019,
93 CAM_CMD_SMP_PHYLIST = 0x0000001a,
94 CAM_CMD_SMP_MANINFO = 0x0000001b,
95 CAM_CMD_DOWNLOAD_FW = 0x0000001c,
96 CAM_CMD_SECURITY = 0x0000001d,
97 CAM_CMD_HPA = 0x0000001e,
98 CAM_CMD_SANITIZE = 0x0000001f,
99 CAM_CMD_PERSIST = 0x00000020,
100 CAM_CMD_APM = 0x00000021,
101 CAM_CMD_AAM = 0x00000022,
102 CAM_CMD_ATTRIB = 0x00000023,
103 CAM_CMD_OPCODES = 0x00000024,
104 CAM_CMD_REPROBE = 0x00000025
108 CAM_ARG_NONE = 0x00000000,
109 CAM_ARG_VERBOSE = 0x00000001,
110 CAM_ARG_DEVICE = 0x00000002,
111 CAM_ARG_BUS = 0x00000004,
112 CAM_ARG_TARGET = 0x00000008,
113 CAM_ARG_LUN = 0x00000010,
114 CAM_ARG_EJECT = 0x00000020,
115 CAM_ARG_UNIT = 0x00000040,
116 CAM_ARG_FORMAT_BLOCK = 0x00000080,
117 CAM_ARG_FORMAT_BFI = 0x00000100,
118 CAM_ARG_FORMAT_PHYS = 0x00000200,
119 CAM_ARG_PLIST = 0x00000400,
120 CAM_ARG_GLIST = 0x00000800,
121 CAM_ARG_GET_SERIAL = 0x00001000,
122 CAM_ARG_GET_STDINQ = 0x00002000,
123 CAM_ARG_GET_XFERRATE = 0x00004000,
124 CAM_ARG_INQ_MASK = 0x00007000,
125 CAM_ARG_TIMEOUT = 0x00020000,
126 CAM_ARG_CMD_IN = 0x00040000,
127 CAM_ARG_CMD_OUT = 0x00080000,
128 CAM_ARG_ERR_RECOVER = 0x00200000,
129 CAM_ARG_RETRIES = 0x00400000,
130 CAM_ARG_START_UNIT = 0x00800000,
131 CAM_ARG_DEBUG_INFO = 0x01000000,
132 CAM_ARG_DEBUG_TRACE = 0x02000000,
133 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
134 CAM_ARG_DEBUG_CDB = 0x08000000,
135 CAM_ARG_DEBUG_XPT = 0x10000000,
136 CAM_ARG_DEBUG_PERIPH = 0x20000000,
137 CAM_ARG_DEBUG_PROBE = 0x40000000,
140 struct camcontrol_opts {
148 struct ata_res_pass16 {
149 u_int16_t reserved[5];
152 u_int8_t sector_count_exp;
153 u_int8_t sector_count;
154 u_int8_t lba_low_exp;
156 u_int8_t lba_mid_exp;
158 u_int8_t lba_high_exp;
164 struct ata_set_max_pwd
167 u_int8_t password[32];
168 u_int16_t reserved2[239];
171 static struct scsi_nv task_attrs[] = {
172 { "simple", MSG_SIMPLE_Q_TAG },
173 { "head", MSG_HEAD_OF_Q_TAG },
174 { "ordered", MSG_ORDERED_Q_TAG },
175 { "iwr", MSG_IGN_WIDE_RESIDUE },
176 { "aca", MSG_ACA_TASK }
179 static const char scsicmd_opts[] = "a:c:dfi:o:r";
180 static const char readdefect_opts[] = "f:GPqsS:X";
181 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
182 static const char smprg_opts[] = "l";
183 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
184 static const char smpphylist_opts[] = "lq";
188 static struct camcontrol_opts option_table[] = {
190 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
191 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
192 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
193 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
194 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
195 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
196 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
197 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
198 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
199 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
200 #endif /* MINIMALISTIC */
201 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
202 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
204 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
205 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
206 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
207 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
208 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
209 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
210 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
211 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
212 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
213 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
214 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
215 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
216 #endif /* MINIMALISTIC */
217 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
219 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
220 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
221 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
222 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
223 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
224 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
225 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
226 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
227 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
228 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
229 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
230 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
231 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
232 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
233 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
234 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
235 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
236 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
237 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
238 #endif /* MINIMALISTIC */
239 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
240 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
241 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
246 struct device_match_result dev_match;
248 struct periph_match_result *periph_matches;
249 struct scsi_vpd_device_id *device_id;
251 STAILQ_ENTRY(cam_devitem) links;
255 STAILQ_HEAD(, cam_devitem) dev_queue;
259 static cam_cmdmask cmdlist;
260 static cam_argmask arglist;
262 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
263 uint32_t *cmdnum, cam_argmask *argnum,
264 const char **subopt);
266 static int getdevlist(struct cam_device *device);
267 #endif /* MINIMALISTIC */
268 static int getdevtree(int argc, char **argv, char *combinedopt);
270 static int testunitready(struct cam_device *device, int task_attr,
271 int retry_count, int timeout, int quiet);
272 static int scsistart(struct cam_device *device, int startstop, int loadeject,
273 int task_attr, int retry_count, int timeout);
274 static int scsiinquiry(struct cam_device *device, int task_attr,
275 int retry_count, int timeout);
276 static int scsiserial(struct cam_device *device, int task_attr,
277 int retry_count, int timeout);
278 #endif /* MINIMALISTIC */
279 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
280 lun_id_t *lun, cam_argmask *arglst);
281 static int dorescan_or_reset(int argc, char **argv, int rescan);
282 static int rescan_or_reset_bus(path_id_t bus, int rescan);
283 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
284 lun_id_t lun, int scan);
286 static int readdefects(struct cam_device *device, int argc, char **argv,
287 char *combinedopt, int task_attr, int retry_count,
289 static void modepage(struct cam_device *device, int argc, char **argv,
290 char *combinedopt, int task_attr, int retry_count,
292 static int scsicmd(struct cam_device *device, int argc, char **argv,
293 char *combinedopt, int task_attr, int retry_count,
295 static int smpcmd(struct cam_device *device, int argc, char **argv,
296 char *combinedopt, int retry_count, int timeout);
297 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
298 char *combinedopt, int retry_count, int timeout);
299 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
300 char *combinedopt, int retry_count, int timeout);
301 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
302 char *combinedopt, int retry_count, int timeout);
303 static int getdevid(struct cam_devitem *item);
304 static int buildbusdevlist(struct cam_devlist *devlist);
305 static void freebusdevlist(struct cam_devlist *devlist);
306 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
308 static int smpphylist(struct cam_device *device, int argc, char **argv,
309 char *combinedopt, int retry_count, int timeout);
310 static int tagcontrol(struct cam_device *device, int argc, char **argv,
312 static void cts_print(struct cam_device *device,
313 struct ccb_trans_settings *cts);
314 static void cpi_print(struct ccb_pathinq *cpi);
315 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
316 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
317 static int get_print_cts(struct cam_device *device, int user_settings,
318 int quiet, struct ccb_trans_settings *cts);
319 static int ratecontrol(struct cam_device *device, int task_attr,
320 int retry_count, int timeout, int argc, char **argv,
322 static int scsiformat(struct cam_device *device, int argc, char **argv,
323 char *combinedopt, int task_attr, int retry_count,
325 static int scsisanitize(struct cam_device *device, int argc, char **argv,
326 char *combinedopt, int task_attr, int retry_count,
328 static int scsireportluns(struct cam_device *device, int argc, char **argv,
329 char *combinedopt, int task_attr, int retry_count,
331 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
332 char *combinedopt, int task_attr, int retry_count,
334 static int atapm(struct cam_device *device, int argc, char **argv,
335 char *combinedopt, int retry_count, int timeout);
336 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
337 int argc, char **argv, char *combinedopt);
338 static int atahpa(struct cam_device *device, int retry_count, int timeout,
339 int argc, char **argv, char *combinedopt);
340 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
341 int sa_set, int req_sa, uint8_t *buf,
343 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
345 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
346 char *combinedopt, int task_attr, int retry_count,
347 int timeout, int verbose);
348 static int scsireprobe(struct cam_device *device);
350 #endif /* MINIMALISTIC */
352 #define min(a,b) (((a)<(b))?(a):(b))
355 #define max(a,b) (((a)>(b))?(a):(b))
359 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
360 cam_argmask *argnum, const char **subopt)
362 struct camcontrol_opts *opts;
365 for (opts = table; (opts != NULL) && (opts->optname != NULL);
367 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
368 *cmdnum = opts->cmdnum;
369 *argnum = opts->argnum;
370 *subopt = opts->subopt;
371 if (++num_matches > 1)
372 return(CC_OR_AMBIGUOUS);
379 return(CC_OR_NOT_FOUND);
384 getdevlist(struct cam_device *device)
390 ccb = cam_getccb(device);
392 ccb->ccb_h.func_code = XPT_GDEVLIST;
393 ccb->ccb_h.flags = CAM_DIR_NONE;
394 ccb->ccb_h.retry_count = 1;
396 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
397 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
398 if (cam_send_ccb(device, ccb) < 0) {
399 perror("error getting device list");
406 switch (ccb->cgdl.status) {
407 case CAM_GDEVLIST_MORE_DEVS:
408 strcpy(status, "MORE");
410 case CAM_GDEVLIST_LAST_DEVICE:
411 strcpy(status, "LAST");
413 case CAM_GDEVLIST_LIST_CHANGED:
414 strcpy(status, "CHANGED");
416 case CAM_GDEVLIST_ERROR:
417 strcpy(status, "ERROR");
422 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
423 ccb->cgdl.periph_name,
424 ccb->cgdl.unit_number,
425 ccb->cgdl.generation,
430 * If the list has changed, we need to start over from the
433 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
441 #endif /* MINIMALISTIC */
444 getdevtree(int argc, char **argv, char *combinedopt)
455 while ((c = getopt(argc, argv, combinedopt)) != -1) {
458 if ((arglist & CAM_ARG_VERBOSE) == 0)
466 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
467 warn("couldn't open %s", XPT_DEVICE);
471 bzero(&ccb, sizeof(union ccb));
473 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
474 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
475 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
477 ccb.ccb_h.func_code = XPT_DEV_MATCH;
478 bufsize = sizeof(struct dev_match_result) * 100;
479 ccb.cdm.match_buf_len = bufsize;
480 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
481 if (ccb.cdm.matches == NULL) {
482 warnx("can't malloc memory for matches");
486 ccb.cdm.num_matches = 0;
489 * We fetch all nodes, since we display most of them in the default
490 * case, and all in the verbose case.
492 ccb.cdm.num_patterns = 0;
493 ccb.cdm.pattern_buf_len = 0;
496 * We do the ioctl multiple times if necessary, in case there are
497 * more than 100 nodes in the EDT.
500 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
501 warn("error sending CAMIOCOMMAND ioctl");
506 if ((ccb.ccb_h.status != CAM_REQ_CMP)
507 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
508 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
509 warnx("got CAM error %#x, CDM error %d\n",
510 ccb.ccb_h.status, ccb.cdm.status);
515 for (i = 0; i < ccb.cdm.num_matches; i++) {
516 switch (ccb.cdm.matches[i].type) {
517 case DEV_MATCH_BUS: {
518 struct bus_match_result *bus_result;
521 * Only print the bus information if the
522 * user turns on the verbose flag.
524 if ((busonly == 0) &&
525 (arglist & CAM_ARG_VERBOSE) == 0)
529 &ccb.cdm.matches[i].result.bus_result;
532 fprintf(stdout, ")\n");
536 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
538 bus_result->dev_name,
539 bus_result->unit_number,
541 (busonly ? "" : ":"));
544 case DEV_MATCH_DEVICE: {
545 struct device_match_result *dev_result;
546 char vendor[16], product[48], revision[16];
547 char fw[5], tmpstr[256];
553 &ccb.cdm.matches[i].result.device_result;
555 if ((dev_result->flags
556 & DEV_RESULT_UNCONFIGURED)
557 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
563 if (dev_result->protocol == PROTO_SCSI) {
564 cam_strvis(vendor, dev_result->inq_data.vendor,
565 sizeof(dev_result->inq_data.vendor),
568 dev_result->inq_data.product,
569 sizeof(dev_result->inq_data.product),
572 dev_result->inq_data.revision,
573 sizeof(dev_result->inq_data.revision),
575 sprintf(tmpstr, "<%s %s %s>", vendor, product,
577 } else if (dev_result->protocol == PROTO_ATA ||
578 dev_result->protocol == PROTO_SATAPM) {
580 dev_result->ident_data.model,
581 sizeof(dev_result->ident_data.model),
584 dev_result->ident_data.revision,
585 sizeof(dev_result->ident_data.revision),
587 sprintf(tmpstr, "<%s %s>", product,
589 } else if (dev_result->protocol == PROTO_SEMB) {
590 struct sep_identify_data *sid;
592 sid = (struct sep_identify_data *)
593 &dev_result->ident_data;
594 cam_strvis(vendor, sid->vendor_id,
595 sizeof(sid->vendor_id),
597 cam_strvis(product, sid->product_id,
598 sizeof(sid->product_id),
600 cam_strvis(revision, sid->product_rev,
601 sizeof(sid->product_rev),
603 cam_strvis(fw, sid->firmware_rev,
604 sizeof(sid->firmware_rev),
606 sprintf(tmpstr, "<%s %s %s %s>",
607 vendor, product, revision, fw);
609 sprintf(tmpstr, "<>");
612 fprintf(stdout, ")\n");
616 fprintf(stdout, "%-33s at scbus%d "
617 "target %d lun %jx (",
620 dev_result->target_id,
621 (uintmax_t)dev_result->target_lun);
627 case DEV_MATCH_PERIPH: {
628 struct periph_match_result *periph_result;
631 &ccb.cdm.matches[i].result.periph_result;
633 if (busonly || skip_device != 0)
637 fprintf(stdout, ",");
639 fprintf(stdout, "%s%d",
640 periph_result->periph_name,
641 periph_result->unit_number);
647 fprintf(stdout, "unknown match type\n");
652 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
653 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
656 fprintf(stdout, ")\n");
665 testunitready(struct cam_device *device, int task_attr, int retry_count,
666 int timeout, int quiet)
671 ccb = cam_getccb(device);
673 scsi_test_unit_ready(&ccb->csio,
674 /* retries */ retry_count,
676 /* tag_action */ task_attr,
677 /* sense_len */ SSD_FULL_SIZE,
678 /* timeout */ timeout ? timeout : 5000);
680 /* Disable freezing the device queue */
681 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
683 if (arglist & CAM_ARG_ERR_RECOVER)
684 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
686 if (cam_send_ccb(device, ccb) < 0) {
688 perror("error sending test unit ready");
690 if (arglist & CAM_ARG_VERBOSE) {
691 cam_error_print(device, ccb, CAM_ESF_ALL,
692 CAM_EPF_ALL, stderr);
699 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
701 fprintf(stdout, "Unit is ready\n");
704 fprintf(stdout, "Unit is not ready\n");
707 if (arglist & CAM_ARG_VERBOSE) {
708 cam_error_print(device, ccb, CAM_ESF_ALL,
709 CAM_EPF_ALL, stderr);
719 scsistart(struct cam_device *device, int startstop, int loadeject,
720 int task_attr, int retry_count, int timeout)
725 ccb = cam_getccb(device);
728 * If we're stopping, send an ordered tag so the drive in question
729 * will finish any previously queued writes before stopping. If
730 * the device isn't capable of tagged queueing, or if tagged
731 * queueing is turned off, the tag action is a no-op. We override
732 * the default simple tag, although this also has the effect of
733 * overriding the user's wishes if he wanted to specify a simple
737 && (task_attr == MSG_SIMPLE_Q_TAG))
738 task_attr = MSG_ORDERED_Q_TAG;
740 scsi_start_stop(&ccb->csio,
741 /* retries */ retry_count,
743 /* tag_action */ task_attr,
744 /* start/stop */ startstop,
745 /* load_eject */ loadeject,
747 /* sense_len */ SSD_FULL_SIZE,
748 /* timeout */ timeout ? timeout : 120000);
750 /* Disable freezing the device queue */
751 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
753 if (arglist & CAM_ARG_ERR_RECOVER)
754 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
756 if (cam_send_ccb(device, ccb) < 0) {
757 perror("error sending start unit");
759 if (arglist & CAM_ARG_VERBOSE) {
760 cam_error_print(device, ccb, CAM_ESF_ALL,
761 CAM_EPF_ALL, stderr);
768 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
770 fprintf(stdout, "Unit started successfully");
772 fprintf(stdout,", Media loaded\n");
774 fprintf(stdout,"\n");
776 fprintf(stdout, "Unit stopped successfully");
778 fprintf(stdout, ", Media ejected\n");
780 fprintf(stdout, "\n");
786 "Error received from start unit command\n");
789 "Error received from stop unit command\n");
791 if (arglist & CAM_ARG_VERBOSE) {
792 cam_error_print(device, ccb, CAM_ESF_ALL,
793 CAM_EPF_ALL, stderr);
803 scsidoinquiry(struct cam_device *device, int argc, char **argv,
804 char *combinedopt, int task_attr, int retry_count, int timeout)
809 while ((c = getopt(argc, argv, combinedopt)) != -1) {
812 arglist |= CAM_ARG_GET_STDINQ;
815 arglist |= CAM_ARG_GET_XFERRATE;
818 arglist |= CAM_ARG_GET_SERIAL;
826 * If the user didn't specify any inquiry options, he wants all of
829 if ((arglist & CAM_ARG_INQ_MASK) == 0)
830 arglist |= CAM_ARG_INQ_MASK;
832 if (arglist & CAM_ARG_GET_STDINQ)
833 error = scsiinquiry(device, task_attr, retry_count, timeout);
838 if (arglist & CAM_ARG_GET_SERIAL)
839 scsiserial(device, task_attr, retry_count, timeout);
841 if (arglist & CAM_ARG_GET_XFERRATE)
842 error = camxferrate(device);
848 scsiinquiry(struct cam_device *device, int task_attr, int retry_count,
852 struct scsi_inquiry_data *inq_buf;
855 ccb = cam_getccb(device);
858 warnx("couldn't allocate CCB");
862 /* cam_getccb cleans up the header, caller has to zero the payload */
863 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
865 inq_buf = (struct scsi_inquiry_data *)malloc(
866 sizeof(struct scsi_inquiry_data));
868 if (inq_buf == NULL) {
870 warnx("can't malloc memory for inquiry\n");
873 bzero(inq_buf, sizeof(*inq_buf));
876 * Note that although the size of the inquiry buffer is the full
877 * 256 bytes specified in the SCSI spec, we only tell the device
878 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
879 * two reasons for this:
881 * - The SCSI spec says that when a length field is only 1 byte,
882 * a value of 0 will be interpreted as 256. Therefore
883 * scsi_inquiry() will convert an inq_len (which is passed in as
884 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
885 * to 0. Evidently, very few devices meet the spec in that
886 * regard. Some devices, like many Seagate disks, take the 0 as
887 * 0, and don't return any data. One Pioneer DVD-R drive
888 * returns more data than the command asked for.
890 * So, since there are numerous devices that just don't work
891 * right with the full inquiry size, we don't send the full size.
893 * - The second reason not to use the full inquiry data length is
894 * that we don't need it here. The only reason we issue a
895 * standard inquiry is to get the vendor name, device name,
896 * and revision so scsi_print_inquiry() can print them.
898 * If, at some point in the future, more inquiry data is needed for
899 * some reason, this code should use a procedure similar to the
900 * probe code. i.e., issue a short inquiry, and determine from
901 * the additional length passed back from the device how much
902 * inquiry data the device supports. Once the amount the device
903 * supports is determined, issue an inquiry for that amount and no
908 scsi_inquiry(&ccb->csio,
909 /* retries */ retry_count,
911 /* tag_action */ task_attr,
912 /* inq_buf */ (u_int8_t *)inq_buf,
913 /* inq_len */ SHORT_INQUIRY_LENGTH,
916 /* sense_len */ SSD_FULL_SIZE,
917 /* timeout */ timeout ? timeout : 5000);
919 /* Disable freezing the device queue */
920 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
922 if (arglist & CAM_ARG_ERR_RECOVER)
923 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
925 if (cam_send_ccb(device, ccb) < 0) {
926 perror("error sending SCSI inquiry");
928 if (arglist & CAM_ARG_VERBOSE) {
929 cam_error_print(device, ccb, CAM_ESF_ALL,
930 CAM_EPF_ALL, stderr);
937 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
940 if (arglist & CAM_ARG_VERBOSE) {
941 cam_error_print(device, ccb, CAM_ESF_ALL,
942 CAM_EPF_ALL, stderr);
953 fprintf(stdout, "%s%d: ", device->device_name,
954 device->dev_unit_num);
955 scsi_print_inquiry(inq_buf);
963 scsiserial(struct cam_device *device, int task_attr, int retry_count,
967 struct scsi_vpd_unit_serial_number *serial_buf;
968 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
971 ccb = cam_getccb(device);
974 warnx("couldn't allocate CCB");
978 /* cam_getccb cleans up the header, caller has to zero the payload */
979 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
981 serial_buf = (struct scsi_vpd_unit_serial_number *)
982 malloc(sizeof(*serial_buf));
984 if (serial_buf == NULL) {
986 warnx("can't malloc memory for serial number");
990 scsi_inquiry(&ccb->csio,
991 /*retries*/ retry_count,
993 /* tag_action */ task_attr,
994 /* inq_buf */ (u_int8_t *)serial_buf,
995 /* inq_len */ sizeof(*serial_buf),
997 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
998 /* sense_len */ SSD_FULL_SIZE,
999 /* timeout */ timeout ? timeout : 5000);
1001 /* Disable freezing the device queue */
1002 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1004 if (arglist & CAM_ARG_ERR_RECOVER)
1005 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1007 if (cam_send_ccb(device, ccb) < 0) {
1008 warn("error getting serial number");
1010 if (arglist & CAM_ARG_VERBOSE) {
1011 cam_error_print(device, ccb, CAM_ESF_ALL,
1012 CAM_EPF_ALL, stderr);
1020 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1023 if (arglist & CAM_ARG_VERBOSE) {
1024 cam_error_print(device, ccb, CAM_ESF_ALL,
1025 CAM_EPF_ALL, stderr);
1036 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1037 serial_num[serial_buf->length] = '\0';
1039 if ((arglist & CAM_ARG_GET_STDINQ)
1040 || (arglist & CAM_ARG_GET_XFERRATE))
1041 fprintf(stdout, "%s%d: Serial Number ",
1042 device->device_name, device->dev_unit_num);
1044 fprintf(stdout, "%.60s\n", serial_num);
1052 camxferrate(struct cam_device *device)
1054 struct ccb_pathinq cpi;
1056 u_int32_t speed = 0;
1061 if ((retval = get_cpi(device, &cpi)) != 0)
1064 ccb = cam_getccb(device);
1067 warnx("couldn't allocate CCB");
1071 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
1073 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1074 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1076 if (((retval = cam_send_ccb(device, ccb)) < 0)
1077 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1078 const char error_string[] = "error getting transfer settings";
1083 warnx(error_string);
1085 if (arglist & CAM_ARG_VERBOSE)
1086 cam_error_print(device, ccb, CAM_ESF_ALL,
1087 CAM_EPF_ALL, stderr);
1091 goto xferrate_bailout;
1095 speed = cpi.base_transfer_speed;
1097 if (ccb->cts.transport == XPORT_SPI) {
1098 struct ccb_trans_settings_spi *spi =
1099 &ccb->cts.xport_specific.spi;
1101 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1102 freq = scsi_calc_syncsrate(spi->sync_period);
1105 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1106 speed *= (0x01 << spi->bus_width);
1108 } else if (ccb->cts.transport == XPORT_FC) {
1109 struct ccb_trans_settings_fc *fc =
1110 &ccb->cts.xport_specific.fc;
1112 if (fc->valid & CTS_FC_VALID_SPEED)
1113 speed = fc->bitrate;
1114 } else if (ccb->cts.transport == XPORT_SAS) {
1115 struct ccb_trans_settings_sas *sas =
1116 &ccb->cts.xport_specific.sas;
1118 if (sas->valid & CTS_SAS_VALID_SPEED)
1119 speed = sas->bitrate;
1120 } else if (ccb->cts.transport == XPORT_ATA) {
1121 struct ccb_trans_settings_pata *pata =
1122 &ccb->cts.xport_specific.ata;
1124 if (pata->valid & CTS_ATA_VALID_MODE)
1125 speed = ata_mode2speed(pata->mode);
1126 } else if (ccb->cts.transport == XPORT_SATA) {
1127 struct ccb_trans_settings_sata *sata =
1128 &ccb->cts.xport_specific.sata;
1130 if (sata->valid & CTS_SATA_VALID_REVISION)
1131 speed = ata_revision2speed(sata->revision);
1136 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1137 device->device_name, device->dev_unit_num,
1140 fprintf(stdout, "%s%d: %dKB/s transfers",
1141 device->device_name, device->dev_unit_num,
1145 if (ccb->cts.transport == XPORT_SPI) {
1146 struct ccb_trans_settings_spi *spi =
1147 &ccb->cts.xport_specific.spi;
1149 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1150 && (spi->sync_offset != 0))
1151 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1152 freq % 1000, spi->sync_offset);
1154 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1155 && (spi->bus_width > 0)) {
1156 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1157 && (spi->sync_offset != 0)) {
1158 fprintf(stdout, ", ");
1160 fprintf(stdout, " (");
1162 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1163 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1164 && (spi->sync_offset != 0)) {
1165 fprintf(stdout, ")");
1167 } else if (ccb->cts.transport == XPORT_ATA) {
1168 struct ccb_trans_settings_pata *pata =
1169 &ccb->cts.xport_specific.ata;
1172 if (pata->valid & CTS_ATA_VALID_MODE)
1173 printf("%s, ", ata_mode2string(pata->mode));
1174 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1175 printf("ATAPI %dbytes, ", pata->atapi);
1176 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1177 printf("PIO %dbytes", pata->bytecount);
1179 } else if (ccb->cts.transport == XPORT_SATA) {
1180 struct ccb_trans_settings_sata *sata =
1181 &ccb->cts.xport_specific.sata;
1184 if (sata->valid & CTS_SATA_VALID_REVISION)
1185 printf("SATA %d.x, ", sata->revision);
1188 if (sata->valid & CTS_SATA_VALID_MODE)
1189 printf("%s, ", ata_mode2string(sata->mode));
1190 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1191 printf("ATAPI %dbytes, ", sata->atapi);
1192 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1193 printf("PIO %dbytes", sata->bytecount);
1197 if (ccb->cts.protocol == PROTO_SCSI) {
1198 struct ccb_trans_settings_scsi *scsi =
1199 &ccb->cts.proto_specific.scsi;
1200 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1201 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1202 fprintf(stdout, ", Command Queueing Enabled");
1207 fprintf(stdout, "\n");
1217 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1219 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1220 ((u_int32_t)parm->lba_size_2 << 16);
1222 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1223 ((u_int64_t)parm->lba_size48_2 << 16) |
1224 ((u_int64_t)parm->lba_size48_3 << 32) |
1225 ((u_int64_t)parm->lba_size48_4 << 48);
1229 "Support Enabled Value\n");
1232 printf("Host Protected Area (HPA) ");
1233 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1234 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1235 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1238 printf("HPA - Security ");
1239 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1249 atasata(struct ata_params *parm)
1253 if (parm->satacapabilities != 0xffff &&
1254 parm->satacapabilities != 0x0000)
1261 atacapprint(struct ata_params *parm)
1263 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1264 ((u_int32_t)parm->lba_size_2 << 16);
1266 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1267 ((u_int64_t)parm->lba_size48_2 << 16) |
1268 ((u_int64_t)parm->lba_size48_3 << 32) |
1269 ((u_int64_t)parm->lba_size48_4 << 48);
1272 printf("protocol ");
1273 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1274 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1275 if (parm->satacapabilities & ATA_SATA_GEN3)
1276 printf(" SATA 3.x\n");
1277 else if (parm->satacapabilities & ATA_SATA_GEN2)
1278 printf(" SATA 2.x\n");
1279 else if (parm->satacapabilities & ATA_SATA_GEN1)
1280 printf(" SATA 1.x\n");
1286 printf("device model %.40s\n", parm->model);
1287 printf("firmware revision %.8s\n", parm->revision);
1288 printf("serial number %.20s\n", parm->serial);
1289 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1290 printf("WWN %04x%04x%04x%04x\n",
1291 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1293 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1294 printf("media serial number %.30s\n",
1295 parm->media_serial);
1298 printf("cylinders %d\n", parm->cylinders);
1299 printf("heads %d\n", parm->heads);
1300 printf("sectors/track %d\n", parm->sectors);
1301 printf("sector size logical %u, physical %lu, offset %lu\n",
1302 ata_logical_sector_size(parm),
1303 (unsigned long)ata_physical_sector_size(parm),
1304 (unsigned long)ata_logical_sector_offset(parm));
1306 if (parm->config == ATA_PROTO_CFA ||
1307 (parm->support.command2 & ATA_SUPPORT_CFA))
1308 printf("CFA supported\n");
1310 printf("LBA%ssupported ",
1311 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1313 printf("%d sectors\n", lbasize);
1317 printf("LBA48%ssupported ",
1318 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1320 printf("%ju sectors\n", (uintmax_t)lbasize48);
1324 printf("PIO supported PIO");
1325 switch (ata_max_pmode(parm)) {
1341 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1342 printf(" w/o IORDY");
1345 printf("DMA%ssupported ",
1346 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1347 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1348 if (parm->mwdmamodes & 0xff) {
1350 if (parm->mwdmamodes & 0x04)
1352 else if (parm->mwdmamodes & 0x02)
1354 else if (parm->mwdmamodes & 0x01)
1358 if ((parm->atavalid & ATA_FLAG_88) &&
1359 (parm->udmamodes & 0xff)) {
1361 if (parm->udmamodes & 0x40)
1363 else if (parm->udmamodes & 0x20)
1365 else if (parm->udmamodes & 0x10)
1367 else if (parm->udmamodes & 0x08)
1369 else if (parm->udmamodes & 0x04)
1371 else if (parm->udmamodes & 0x02)
1373 else if (parm->udmamodes & 0x01)
1380 if (parm->media_rotation_rate == 1) {
1381 printf("media RPM non-rotating\n");
1382 } else if (parm->media_rotation_rate >= 0x0401 &&
1383 parm->media_rotation_rate <= 0xFFFE) {
1384 printf("media RPM %d\n",
1385 parm->media_rotation_rate);
1389 "Support Enabled Value Vendor\n");
1390 printf("read ahead %s %s\n",
1391 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1392 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1393 printf("write cache %s %s\n",
1394 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1395 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1396 printf("flush cache %s %s\n",
1397 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1398 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1399 printf("overlap %s\n",
1400 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1401 printf("Tagged Command Queuing (TCQ) %s %s",
1402 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1403 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1404 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1405 printf(" %d tags\n",
1406 ATA_QUEUE_LEN(parm->queue) + 1);
1409 printf("Native Command Queuing (NCQ) ");
1410 if (parm->satacapabilities != 0xffff &&
1411 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1412 printf("yes %d tags\n",
1413 ATA_QUEUE_LEN(parm->queue) + 1);
1417 printf("NCQ Queue Management %s\n", atasata(parm) &&
1418 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1420 printf("NCQ Streaming %s\n", atasata(parm) &&
1421 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1423 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1424 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1427 printf("SMART %s %s\n",
1428 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1429 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1430 printf("microcode download %s %s\n",
1431 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1432 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1433 printf("security %s %s\n",
1434 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1435 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1436 printf("power management %s %s\n",
1437 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1438 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1439 printf("advanced power management %s %s",
1440 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1441 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1442 if (parm->support.command2 & ATA_SUPPORT_APM) {
1443 printf(" %d/0x%02X\n",
1444 parm->apm_value & 0xff, parm->apm_value & 0xff);
1447 printf("automatic acoustic management %s %s",
1448 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1449 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1450 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1451 printf(" %d/0x%02X %d/0x%02X\n",
1452 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1453 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1454 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1455 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1458 printf("media status notification %s %s\n",
1459 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1460 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1461 printf("power-up in Standby %s %s\n",
1462 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1463 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1464 printf("write-read-verify %s %s",
1465 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1466 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1467 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1468 printf(" %d/0x%x\n",
1469 parm->wrv_mode, parm->wrv_mode);
1472 printf("unload %s %s\n",
1473 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1474 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1475 printf("general purpose logging %s %s\n",
1476 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1477 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1478 printf("free-fall %s %s\n",
1479 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1480 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1481 printf("Data Set Management (DSM/TRIM) ");
1482 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1484 printf("DSM - max 512byte blocks ");
1485 if (parm->max_dsm_blocks == 0x00)
1486 printf("yes not specified\n");
1489 parm->max_dsm_blocks);
1491 printf("DSM - deterministic read ");
1492 if (parm->support3 & ATA_SUPPORT_DRAT) {
1493 if (parm->support3 & ATA_SUPPORT_RZAT)
1494 printf("yes zeroed\n");
1496 printf("yes any value\n");
1506 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1508 struct ata_pass_16 *ata_pass_16;
1509 struct ata_cmd ata_cmd;
1511 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1512 ata_cmd.command = ata_pass_16->command;
1513 ata_cmd.control = ata_pass_16->control;
1514 ata_cmd.features = ata_pass_16->features;
1516 if (arglist & CAM_ARG_VERBOSE) {
1517 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1518 ata_op_string(&ata_cmd),
1519 ccb->csio.ccb_h.timeout);
1522 /* Disable freezing the device queue */
1523 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1525 if (arglist & CAM_ARG_ERR_RECOVER)
1526 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1528 if (cam_send_ccb(device, ccb) < 0) {
1529 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1530 warn("error sending ATA %s via pass_16",
1531 ata_op_string(&ata_cmd));
1534 if (arglist & CAM_ARG_VERBOSE) {
1535 cam_error_print(device, ccb, CAM_ESF_ALL,
1536 CAM_EPF_ALL, stderr);
1542 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1543 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1544 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1545 warnx("ATA %s via pass_16 failed",
1546 ata_op_string(&ata_cmd));
1548 if (arglist & CAM_ARG_VERBOSE) {
1549 cam_error_print(device, ccb, CAM_ESF_ALL,
1550 CAM_EPF_ALL, stderr);
1561 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1563 if (arglist & CAM_ARG_VERBOSE) {
1564 warnx("sending ATA %s with timeout of %u msecs",
1565 ata_op_string(&(ccb->ataio.cmd)),
1566 ccb->ataio.ccb_h.timeout);
1569 /* Disable freezing the device queue */
1570 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1572 if (arglist & CAM_ARG_ERR_RECOVER)
1573 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1575 if (cam_send_ccb(device, ccb) < 0) {
1576 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1577 warn("error sending ATA %s",
1578 ata_op_string(&(ccb->ataio.cmd)));
1581 if (arglist & CAM_ARG_VERBOSE) {
1582 cam_error_print(device, ccb, CAM_ESF_ALL,
1583 CAM_EPF_ALL, stderr);
1589 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1590 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1591 warnx("ATA %s failed: %d",
1592 ata_op_string(&(ccb->ataio.cmd)), quiet);
1595 if (arglist & CAM_ARG_VERBOSE) {
1596 cam_error_print(device, ccb, CAM_ESF_ALL,
1597 CAM_EPF_ALL, stderr);
1607 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1608 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1609 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1610 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1611 u_int16_t dxfer_len, int timeout, int quiet)
1613 if (data_ptr != NULL) {
1614 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1615 AP_FLAG_TLEN_SECT_CNT;
1616 if (flags & CAM_DIR_OUT)
1617 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1619 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1621 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1624 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1626 scsi_ata_pass_16(&ccb->csio,
1640 /*sense_len*/SSD_FULL_SIZE,
1643 return scsi_cam_pass_16_send(device, ccb, quiet);
1647 ata_try_pass_16(struct cam_device *device)
1649 struct ccb_pathinq cpi;
1651 if (get_cpi(device, &cpi) != 0) {
1652 warnx("couldn't get CPI");
1656 if (cpi.protocol == PROTO_SCSI) {
1657 /* possibly compatible with pass_16 */
1661 /* likely not compatible with pass_16 */
1666 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1667 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1668 u_int8_t command, u_int8_t features, u_int32_t lba,
1669 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1670 int timeout, int quiet)
1674 switch (ata_try_pass_16(device)) {
1678 /* Try using SCSI Passthrough */
1679 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1680 0, tag_action, command, features, lba,
1681 sector_count, data_ptr, dxfer_len,
1685 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1686 cam_fill_ataio(&ccb->ataio,
1695 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1696 return ata_cam_send(device, ccb, quiet);
1700 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1701 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1702 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1703 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1704 u_int16_t dxfer_len, int timeout, int force48bit)
1708 retval = ata_try_pass_16(device);
1715 /* Try using SCSI Passthrough */
1716 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1717 ata_flags, tag_action, command, features,
1718 lba, sector_count, data_ptr, dxfer_len,
1721 if (ata_flags & AP_FLAG_CHK_COND) {
1722 /* Decode ata_res from sense data */
1723 struct ata_res_pass16 *res_pass16;
1724 struct ata_res *res;
1728 /* sense_data is 4 byte aligned */
1729 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1730 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1731 ptr[i] = le16toh(ptr[i]);
1733 /* sense_data is 4 byte aligned */
1734 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1735 &ccb->csio.sense_data;
1736 res = &ccb->ataio.res;
1737 res->flags = res_pass16->flags;
1738 res->status = res_pass16->status;
1739 res->error = res_pass16->error;
1740 res->lba_low = res_pass16->lba_low;
1741 res->lba_mid = res_pass16->lba_mid;
1742 res->lba_high = res_pass16->lba_high;
1743 res->device = res_pass16->device;
1744 res->lba_low_exp = res_pass16->lba_low_exp;
1745 res->lba_mid_exp = res_pass16->lba_mid_exp;
1746 res->lba_high_exp = res_pass16->lba_high_exp;
1747 res->sector_count = res_pass16->sector_count;
1748 res->sector_count_exp = res_pass16->sector_count_exp;
1754 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1755 cam_fill_ataio(&ccb->ataio,
1764 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1765 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1767 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1769 if (ata_flags & AP_FLAG_CHK_COND)
1770 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1772 return ata_cam_send(device, ccb, 0);
1776 dump_data(uint16_t *ptr, uint32_t len)
1780 for (i = 0; i < len / 2; i++) {
1782 printf(" %3d: ", i);
1783 printf("%04hx ", ptr[i]);
1792 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1793 int is48bit, u_int64_t *hpasize)
1795 struct ata_res *res;
1797 res = &ccb->ataio.res;
1798 if (res->status & ATA_STATUS_ERROR) {
1799 if (arglist & CAM_ARG_VERBOSE) {
1800 cam_error_print(device, ccb, CAM_ESF_ALL,
1801 CAM_EPF_ALL, stderr);
1802 printf("error = 0x%02x, sector_count = 0x%04x, "
1803 "device = 0x%02x, status = 0x%02x\n",
1804 res->error, res->sector_count,
1805 res->device, res->status);
1808 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1809 warnx("Max address has already been set since "
1810 "last power-on or hardware reset");
1816 if (arglist & CAM_ARG_VERBOSE) {
1817 fprintf(stdout, "%s%d: Raw native max data:\n",
1818 device->device_name, device->dev_unit_num);
1819 /* res is 4 byte aligned */
1820 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1822 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1823 "status = 0x%02x\n", res->error, res->sector_count,
1824 res->device, res->status);
1827 if (hpasize != NULL) {
1829 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1830 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1831 ((res->lba_high << 16) | (res->lba_mid << 8) |
1834 *hpasize = (((res->device & 0x0f) << 24) |
1835 (res->lba_high << 16) | (res->lba_mid << 8) |
1844 ata_read_native_max(struct cam_device *device, int retry_count,
1845 u_int32_t timeout, union ccb *ccb,
1846 struct ata_params *parm, u_int64_t *hpasize)
1852 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1853 protocol = AP_PROTO_NON_DATA;
1856 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1857 protocol |= AP_EXTEND;
1859 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1862 error = ata_do_cmd(device,
1865 /*flags*/CAM_DIR_NONE,
1866 /*protocol*/protocol,
1867 /*ata_flags*/AP_FLAG_CHK_COND,
1868 /*tag_action*/MSG_SIMPLE_Q_TAG,
1875 timeout ? timeout : 1000,
1881 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
1885 atahpa_set_max(struct cam_device *device, int retry_count,
1886 u_int32_t timeout, union ccb *ccb,
1887 int is48bit, u_int64_t maxsize, int persist)
1893 protocol = AP_PROTO_NON_DATA;
1896 cmd = ATA_SET_MAX_ADDRESS48;
1897 protocol |= AP_EXTEND;
1899 cmd = ATA_SET_MAX_ADDRESS;
1902 /* lba's are zero indexed so the max lba is requested max - 1 */
1906 error = ata_do_cmd(device,
1909 /*flags*/CAM_DIR_NONE,
1910 /*protocol*/protocol,
1911 /*ata_flags*/AP_FLAG_CHK_COND,
1912 /*tag_action*/MSG_SIMPLE_Q_TAG,
1914 /*features*/ATA_HPA_FEAT_MAX_ADDR,
1916 /*sector_count*/persist,
1919 timeout ? timeout : 1000,
1925 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1929 atahpa_password(struct cam_device *device, int retry_count,
1930 u_int32_t timeout, union ccb *ccb,
1931 int is48bit, struct ata_set_max_pwd *pwd)
1937 protocol = AP_PROTO_PIO_OUT;
1938 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1940 error = ata_do_cmd(device,
1943 /*flags*/CAM_DIR_OUT,
1944 /*protocol*/protocol,
1945 /*ata_flags*/AP_FLAG_CHK_COND,
1946 /*tag_action*/MSG_SIMPLE_Q_TAG,
1948 /*features*/ATA_HPA_FEAT_SET_PWD,
1951 /*data_ptr*/(u_int8_t*)pwd,
1952 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1953 timeout ? timeout : 1000,
1959 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1963 atahpa_lock(struct cam_device *device, int retry_count,
1964 u_int32_t timeout, union ccb *ccb, int is48bit)
1970 protocol = AP_PROTO_NON_DATA;
1971 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1973 error = ata_do_cmd(device,
1976 /*flags*/CAM_DIR_NONE,
1977 /*protocol*/protocol,
1978 /*ata_flags*/AP_FLAG_CHK_COND,
1979 /*tag_action*/MSG_SIMPLE_Q_TAG,
1981 /*features*/ATA_HPA_FEAT_LOCK,
1986 timeout ? timeout : 1000,
1992 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1996 atahpa_unlock(struct cam_device *device, int retry_count,
1997 u_int32_t timeout, union ccb *ccb,
1998 int is48bit, struct ata_set_max_pwd *pwd)
2004 protocol = AP_PROTO_PIO_OUT;
2005 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2007 error = ata_do_cmd(device,
2010 /*flags*/CAM_DIR_OUT,
2011 /*protocol*/protocol,
2012 /*ata_flags*/AP_FLAG_CHK_COND,
2013 /*tag_action*/MSG_SIMPLE_Q_TAG,
2015 /*features*/ATA_HPA_FEAT_UNLOCK,
2018 /*data_ptr*/(u_int8_t*)pwd,
2019 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2020 timeout ? timeout : 1000,
2026 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2030 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2031 u_int32_t timeout, union ccb *ccb, int is48bit)
2037 protocol = AP_PROTO_NON_DATA;
2038 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2040 error = ata_do_cmd(device,
2043 /*flags*/CAM_DIR_NONE,
2044 /*protocol*/protocol,
2045 /*ata_flags*/AP_FLAG_CHK_COND,
2046 /*tag_action*/MSG_SIMPLE_Q_TAG,
2048 /*features*/ATA_HPA_FEAT_FREEZE,
2053 timeout ? timeout : 1000,
2059 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2064 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2065 union ccb *ccb, struct ata_params** ident_bufp)
2067 struct ata_params *ident_buf;
2068 struct ccb_pathinq cpi;
2069 struct ccb_getdev cgd;
2072 u_int8_t command, retry_command;
2074 if (get_cpi(device, &cpi) != 0) {
2075 warnx("couldn't get CPI");
2079 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2080 if (cpi.protocol == PROTO_ATA) {
2081 if (get_cgd(device, &cgd) != 0) {
2082 warnx("couldn't get CGD");
2086 command = (cgd.protocol == PROTO_ATA) ?
2087 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2090 /* We don't know which for sure so try both */
2091 command = ATA_ATA_IDENTIFY;
2092 retry_command = ATA_ATAPI_IDENTIFY;
2095 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2097 warnx("can't calloc memory for identify\n");
2101 error = ata_do_28bit_cmd(device,
2103 /*retries*/retry_count,
2104 /*flags*/CAM_DIR_IN,
2105 /*protocol*/AP_PROTO_PIO_IN,
2106 /*tag_action*/MSG_SIMPLE_Q_TAG,
2110 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2111 /*data_ptr*/(u_int8_t *)ptr,
2112 /*dxfer_len*/sizeof(struct ata_params),
2113 /*timeout*/timeout ? timeout : 30 * 1000,
2117 if (retry_command == 0) {
2121 error = ata_do_28bit_cmd(device,
2123 /*retries*/retry_count,
2124 /*flags*/CAM_DIR_IN,
2125 /*protocol*/AP_PROTO_PIO_IN,
2126 /*tag_action*/MSG_SIMPLE_Q_TAG,
2127 /*command*/retry_command,
2130 /*sector_count*/(u_int8_t)
2131 sizeof(struct ata_params),
2132 /*data_ptr*/(u_int8_t *)ptr,
2133 /*dxfer_len*/sizeof(struct ata_params),
2134 /*timeout*/timeout ? timeout : 30 * 1000,
2144 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2145 ptr[i] = le16toh(ptr[i]);
2150 if (arglist & CAM_ARG_VERBOSE) {
2151 fprintf(stdout, "%s%d: Raw identify data:\n",
2152 device->device_name, device->dev_unit_num);
2153 dump_data(ptr, sizeof(struct ata_params));
2156 /* check for invalid (all zero) response */
2158 warnx("Invalid identify response detected");
2163 ident_buf = (struct ata_params *)ptr;
2164 if (strncmp(ident_buf->model, "FX", 2) &&
2165 strncmp(ident_buf->model, "NEC", 3) &&
2166 strncmp(ident_buf->model, "Pioneer", 7) &&
2167 strncmp(ident_buf->model, "SHARP", 5)) {
2168 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2169 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2170 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2171 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2173 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2174 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2175 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2176 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2177 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2178 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2179 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2180 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2181 sizeof(ident_buf->media_serial));
2183 *ident_bufp = ident_buf;
2190 ataidentify(struct cam_device *device, int retry_count, int timeout)
2193 struct ata_params *ident_buf;
2196 if ((ccb = cam_getccb(device)) == NULL) {
2197 warnx("couldn't allocate CCB");
2201 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2206 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2207 if (ata_read_native_max(device, retry_count, timeout, ccb,
2208 ident_buf, &hpasize) != 0) {
2216 printf("%s%d: ", device->device_name, device->dev_unit_num);
2217 ata_print_ident(ident_buf);
2218 camxferrate(device);
2219 atacapprint(ident_buf);
2220 atahpa_print(ident_buf, hpasize, 0);
2227 #endif /* MINIMALISTIC */
2230 #ifndef MINIMALISTIC
2232 ATA_SECURITY_ACTION_PRINT,
2233 ATA_SECURITY_ACTION_FREEZE,
2234 ATA_SECURITY_ACTION_UNLOCK,
2235 ATA_SECURITY_ACTION_DISABLE,
2236 ATA_SECURITY_ACTION_ERASE,
2237 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2238 ATA_SECURITY_ACTION_SET_PASSWORD
2242 atasecurity_print_time(u_int16_t tw)
2246 printf("unspecified");
2248 printf("> 508 min");
2250 printf("%i min", 2 * tw);
2254 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2258 return 2 * 3600 * 1000; /* default: two hours */
2259 else if (timeout > 255)
2260 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2262 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2267 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2271 bzero(&cmd, sizeof(cmd));
2272 cmd.command = command;
2273 printf("Issuing %s", ata_op_string(&cmd));
2276 char pass[sizeof(pwd->password)+1];
2278 /* pwd->password may not be null terminated */
2279 pass[sizeof(pwd->password)] = '\0';
2280 strncpy(pass, pwd->password, sizeof(pwd->password));
2281 printf(" password='%s', user='%s'",
2283 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2286 if (command == ATA_SECURITY_SET_PASSWORD) {
2287 printf(", mode='%s'",
2288 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2289 "maximum" : "high");
2297 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2298 int retry_count, u_int32_t timeout, int quiet)
2302 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2304 return ata_do_28bit_cmd(device,
2307 /*flags*/CAM_DIR_NONE,
2308 /*protocol*/AP_PROTO_NON_DATA,
2309 /*tag_action*/MSG_SIMPLE_Q_TAG,
2310 /*command*/ATA_SECURITY_FREEZE_LOCK,
2321 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2322 int retry_count, u_int32_t timeout,
2323 struct ata_security_password *pwd, int quiet)
2327 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2329 return ata_do_28bit_cmd(device,
2332 /*flags*/CAM_DIR_OUT,
2333 /*protocol*/AP_PROTO_PIO_OUT,
2334 /*tag_action*/MSG_SIMPLE_Q_TAG,
2335 /*command*/ATA_SECURITY_UNLOCK,
2339 /*data_ptr*/(u_int8_t *)pwd,
2340 /*dxfer_len*/sizeof(*pwd),
2346 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2347 int retry_count, u_int32_t timeout,
2348 struct ata_security_password *pwd, int quiet)
2352 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2353 return ata_do_28bit_cmd(device,
2356 /*flags*/CAM_DIR_OUT,
2357 /*protocol*/AP_PROTO_PIO_OUT,
2358 /*tag_action*/MSG_SIMPLE_Q_TAG,
2359 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2363 /*data_ptr*/(u_int8_t *)pwd,
2364 /*dxfer_len*/sizeof(*pwd),
2371 atasecurity_erase_confirm(struct cam_device *device,
2372 struct ata_params* ident_buf)
2375 printf("\nYou are about to ERASE ALL DATA from the following"
2376 " device:\n%s%d,%s%d: ", device->device_name,
2377 device->dev_unit_num, device->given_dev_name,
2378 device->given_unit_number);
2379 ata_print_ident(ident_buf);
2383 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2385 if (fgets(str, sizeof(str), stdin) != NULL) {
2386 if (strncasecmp(str, "yes", 3) == 0) {
2388 } else if (strncasecmp(str, "no", 2) == 0) {
2391 printf("Please answer \"yes\" or "
2402 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2403 int retry_count, u_int32_t timeout,
2404 u_int32_t erase_timeout,
2405 struct ata_security_password *pwd, int quiet)
2410 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2412 error = ata_do_28bit_cmd(device,
2415 /*flags*/CAM_DIR_NONE,
2416 /*protocol*/AP_PROTO_NON_DATA,
2417 /*tag_action*/MSG_SIMPLE_Q_TAG,
2418 /*command*/ATA_SECURITY_ERASE_PREPARE,
2431 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2433 error = ata_do_28bit_cmd(device,
2436 /*flags*/CAM_DIR_OUT,
2437 /*protocol*/AP_PROTO_PIO_OUT,
2438 /*tag_action*/MSG_SIMPLE_Q_TAG,
2439 /*command*/ATA_SECURITY_ERASE_UNIT,
2443 /*data_ptr*/(u_int8_t *)pwd,
2444 /*dxfer_len*/sizeof(*pwd),
2445 /*timeout*/erase_timeout,
2448 if (error == 0 && quiet == 0)
2449 printf("\nErase Complete\n");
2455 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2456 int retry_count, u_int32_t timeout,
2457 struct ata_security_password *pwd, int quiet)
2461 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2463 return ata_do_28bit_cmd(device,
2466 /*flags*/CAM_DIR_OUT,
2467 /*protocol*/AP_PROTO_PIO_OUT,
2468 /*tag_action*/MSG_SIMPLE_Q_TAG,
2469 /*command*/ATA_SECURITY_SET_PASSWORD,
2473 /*data_ptr*/(u_int8_t *)pwd,
2474 /*dxfer_len*/sizeof(*pwd),
2480 atasecurity_print(struct ata_params *parm)
2483 printf("\nSecurity Option Value\n");
2484 if (arglist & CAM_ARG_VERBOSE) {
2485 printf("status %04x\n",
2486 parm->security_status);
2488 printf("supported %s\n",
2489 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2490 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2492 printf("enabled %s\n",
2493 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2494 printf("drive locked %s\n",
2495 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2496 printf("security config frozen %s\n",
2497 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2498 printf("count expired %s\n",
2499 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2500 printf("security level %s\n",
2501 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2502 printf("enhanced erase supported %s\n",
2503 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2504 printf("erase time ");
2505 atasecurity_print_time(parm->erase_time);
2507 printf("enhanced erase time ");
2508 atasecurity_print_time(parm->enhanced_erase_time);
2510 printf("master password rev %04x%s\n",
2511 parm->master_passwd_revision,
2512 parm->master_passwd_revision == 0x0000 ||
2513 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2517 * Validates and copies the password in optarg to the passed buffer.
2518 * If the password in optarg is the same length as the buffer then
2519 * the data will still be copied but no null termination will occur.
2522 ata_getpwd(u_int8_t *passwd, int max, char opt)
2526 len = strlen(optarg);
2528 warnx("-%c password is too long", opt);
2530 } else if (len == 0) {
2531 warnx("-%c password is missing", opt);
2533 } else if (optarg[0] == '-'){
2534 warnx("-%c password starts with '-' (generic arg?)", opt);
2536 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2537 warnx("-%c password conflicts with existing password from -%c",
2542 /* Callers pass in a buffer which does NOT need to be terminated */
2543 strncpy(passwd, optarg, max);
2550 ATA_HPA_ACTION_PRINT,
2551 ATA_HPA_ACTION_SET_MAX,
2552 ATA_HPA_ACTION_SET_PWD,
2553 ATA_HPA_ACTION_LOCK,
2554 ATA_HPA_ACTION_UNLOCK,
2555 ATA_HPA_ACTION_FREEZE_LOCK
2559 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2560 u_int64_t maxsize, int persist)
2562 printf("\nYou are about to configure HPA to limit the user accessible\n"
2563 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2564 persist ? "persistently" : "temporarily",
2565 device->device_name, device->dev_unit_num,
2566 device->given_dev_name, device->given_unit_number);
2567 ata_print_ident(ident_buf);
2571 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2573 if (NULL != fgets(str, sizeof(str), stdin)) {
2574 if (0 == strncasecmp(str, "yes", 3)) {
2576 } else if (0 == strncasecmp(str, "no", 2)) {
2579 printf("Please answer \"yes\" or "
2590 atahpa(struct cam_device *device, int retry_count, int timeout,
2591 int argc, char **argv, char *combinedopt)
2594 struct ata_params *ident_buf;
2595 struct ccb_getdev cgd;
2596 struct ata_set_max_pwd pwd;
2597 int error, confirm, quiet, c, action, actions, setpwd, persist;
2598 int security, is48bit, pwdsize;
2599 u_int64_t hpasize, maxsize;
2609 memset(&pwd, 0, sizeof(pwd));
2611 /* default action is to print hpa information */
2612 action = ATA_HPA_ACTION_PRINT;
2613 pwdsize = sizeof(pwd.password);
2615 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2618 action = ATA_HPA_ACTION_SET_MAX;
2619 maxsize = strtoumax(optarg, NULL, 0);
2624 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2626 action = ATA_HPA_ACTION_SET_PWD;
2632 action = ATA_HPA_ACTION_LOCK;
2638 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2640 action = ATA_HPA_ACTION_UNLOCK;
2646 action = ATA_HPA_ACTION_FREEZE_LOCK;
2666 warnx("too many hpa actions specified");
2670 if (get_cgd(device, &cgd) != 0) {
2671 warnx("couldn't get CGD");
2675 ccb = cam_getccb(device);
2677 warnx("couldn't allocate CCB");
2681 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2688 printf("%s%d: ", device->device_name, device->dev_unit_num);
2689 ata_print_ident(ident_buf);
2690 camxferrate(device);
2693 if (action == ATA_HPA_ACTION_PRINT) {
2694 error = ata_read_native_max(device, retry_count, timeout, ccb,
2695 ident_buf, &hpasize);
2697 atahpa_print(ident_buf, hpasize, 1);
2704 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2705 warnx("HPA is not supported by this device");
2711 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2712 warnx("HPA Security is not supported by this device");
2718 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2721 * The ATA spec requires:
2722 * 1. Read native max addr is called directly before set max addr
2723 * 2. Read native max addr is NOT called before any other set max call
2726 case ATA_HPA_ACTION_SET_MAX:
2728 atahpa_set_confirm(device, ident_buf, maxsize,
2735 error = ata_read_native_max(device, retry_count, timeout,
2736 ccb, ident_buf, &hpasize);
2738 error = atahpa_set_max(device, retry_count, timeout,
2739 ccb, is48bit, maxsize, persist);
2741 /* redo identify to get new lba values */
2742 error = ata_do_identify(device, retry_count,
2745 atahpa_print(ident_buf, hpasize, 1);
2750 case ATA_HPA_ACTION_SET_PWD:
2751 error = atahpa_password(device, retry_count, timeout,
2752 ccb, is48bit, &pwd);
2754 printf("HPA password has been set\n");
2757 case ATA_HPA_ACTION_LOCK:
2758 error = atahpa_lock(device, retry_count, timeout,
2761 printf("HPA has been locked\n");
2764 case ATA_HPA_ACTION_UNLOCK:
2765 error = atahpa_unlock(device, retry_count, timeout,
2766 ccb, is48bit, &pwd);
2768 printf("HPA has been unlocked\n");
2771 case ATA_HPA_ACTION_FREEZE_LOCK:
2772 error = atahpa_freeze_lock(device, retry_count, timeout,
2775 printf("HPA has been frozen\n");
2779 errx(1, "Option currently not supported");
2789 atasecurity(struct cam_device *device, int retry_count, int timeout,
2790 int argc, char **argv, char *combinedopt)
2793 struct ata_params *ident_buf;
2794 int error, confirm, quiet, c, action, actions, setpwd;
2795 int security_enabled, erase_timeout, pwdsize;
2796 struct ata_security_password pwd;
2804 memset(&pwd, 0, sizeof(pwd));
2806 /* default action is to print security information */
2807 action = ATA_SECURITY_ACTION_PRINT;
2809 /* user is master by default as its safer that way */
2810 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2811 pwdsize = sizeof(pwd.password);
2813 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2816 action = ATA_SECURITY_ACTION_FREEZE;
2821 if (strcasecmp(optarg, "user") == 0) {
2822 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2823 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2824 } else if (strcasecmp(optarg, "master") == 0) {
2825 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2826 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2828 warnx("-U argument '%s' is invalid (must be "
2829 "'user' or 'master')", optarg);
2835 if (strcasecmp(optarg, "high") == 0) {
2836 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2837 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2838 } else if (strcasecmp(optarg, "maximum") == 0) {
2839 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2840 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2842 warnx("-l argument '%s' is unknown (must be "
2843 "'high' or 'maximum')", optarg);
2849 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2851 action = ATA_SECURITY_ACTION_UNLOCK;
2856 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2858 action = ATA_SECURITY_ACTION_DISABLE;
2863 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2865 action = ATA_SECURITY_ACTION_ERASE;
2870 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2872 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2873 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2878 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2881 if (action == ATA_SECURITY_ACTION_PRINT)
2882 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2884 * Don't increment action as this can be combined
2885 * with other actions.
2898 erase_timeout = atoi(optarg) * 1000;
2904 warnx("too many security actions specified");
2908 if ((ccb = cam_getccb(device)) == NULL) {
2909 warnx("couldn't allocate CCB");
2913 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2920 printf("%s%d: ", device->device_name, device->dev_unit_num);
2921 ata_print_ident(ident_buf);
2922 camxferrate(device);
2925 if (action == ATA_SECURITY_ACTION_PRINT) {
2926 atasecurity_print(ident_buf);
2932 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2933 warnx("Security not supported");
2939 /* default timeout 15 seconds the same as linux hdparm */
2940 timeout = timeout ? timeout : 15 * 1000;
2942 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2944 /* first set the password if requested */
2946 /* confirm we can erase before setting the password if erasing */
2948 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2949 action == ATA_SECURITY_ACTION_ERASE) &&
2950 atasecurity_erase_confirm(device, ident_buf) == 0) {
2956 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2957 pwd.revision = ident_buf->master_passwd_revision;
2958 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2959 --pwd.revision == 0) {
2960 pwd.revision = 0xfffe;
2963 error = atasecurity_set_password(device, ccb, retry_count,
2964 timeout, &pwd, quiet);
2970 security_enabled = 1;
2974 case ATA_SECURITY_ACTION_FREEZE:
2975 error = atasecurity_freeze(device, ccb, retry_count,
2979 case ATA_SECURITY_ACTION_UNLOCK:
2980 if (security_enabled) {
2981 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2982 error = atasecurity_unlock(device, ccb,
2983 retry_count, timeout, &pwd, quiet);
2985 warnx("Can't unlock, drive is not locked");
2989 warnx("Can't unlock, security is disabled");
2994 case ATA_SECURITY_ACTION_DISABLE:
2995 if (security_enabled) {
2996 /* First unlock the drive if its locked */
2997 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2998 error = atasecurity_unlock(device, ccb,
3006 error = atasecurity_disable(device,
3014 warnx("Can't disable security (already disabled)");
3019 case ATA_SECURITY_ACTION_ERASE:
3020 if (security_enabled) {
3021 if (erase_timeout == 0) {
3022 erase_timeout = atasecurity_erase_timeout_msecs(
3023 ident_buf->erase_time);
3026 error = atasecurity_erase(device, ccb, retry_count,
3027 timeout, erase_timeout, &pwd,
3030 warnx("Can't secure erase (security is disabled)");
3035 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3036 if (security_enabled) {
3037 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3038 if (erase_timeout == 0) {
3040 atasecurity_erase_timeout_msecs(
3041 ident_buf->enhanced_erase_time);
3044 error = atasecurity_erase(device, ccb,
3045 retry_count, timeout,
3046 erase_timeout, &pwd,
3049 warnx("Enhanced erase is not supported");
3053 warnx("Can't secure erase (enhanced), "
3054 "(security is disabled)");
3065 #endif /* MINIMALISTIC */
3068 * Parse out a bus, or a bus, target and lun in the following
3074 * Returns the number of parsed components, or 0.
3077 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3078 cam_argmask *arglst)
3083 while (isspace(*tstr) && (*tstr != '\0'))
3086 tmpstr = (char *)strtok(tstr, ":");
3087 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3088 *bus = strtol(tmpstr, NULL, 0);
3089 *arglst |= CAM_ARG_BUS;
3091 tmpstr = (char *)strtok(NULL, ":");
3092 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3093 *target = strtol(tmpstr, NULL, 0);
3094 *arglst |= CAM_ARG_TARGET;
3096 tmpstr = (char *)strtok(NULL, ":");
3097 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3098 *lun = strtol(tmpstr, NULL, 0);
3099 *arglst |= CAM_ARG_LUN;
3109 dorescan_or_reset(int argc, char **argv, int rescan)
3111 static const char must[] =
3112 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3114 path_id_t bus = CAM_BUS_WILDCARD;
3115 target_id_t target = CAM_TARGET_WILDCARD;
3116 lun_id_t lun = CAM_LUN_WILDCARD;
3120 warnx(must, rescan? "rescan" : "reset");
3124 tstr = argv[optind];
3125 while (isspace(*tstr) && (*tstr != '\0'))
3127 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3128 arglist |= CAM_ARG_BUS;
3129 else if (isdigit(*tstr)) {
3130 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3131 if (rv != 1 && rv != 3) {
3132 warnx(must, rescan? "rescan" : "reset");
3142 * Note that resetting or rescanning a device used to
3143 * require a bus or bus:target:lun. This is because the
3144 * device in question may not exist and you're trying to
3145 * get the controller to rescan to find it. It may also be
3146 * because the device is hung / unresponsive, and opening
3147 * an unresponsive device is not desireable.
3149 * It can be more convenient to reference a device by
3150 * peripheral name and unit number, though, and it is
3151 * possible to get the bus:target:lun for devices that
3152 * currently exist in the EDT. So this can work for
3153 * devices that we want to reset, or devices that exist
3154 * that we want to rescan, but not devices that do not
3157 * So, we are careful here to look up the bus/target/lun
3158 * for the device the user wants to operate on, specified
3159 * by peripheral instance (e.g. da0, pass32) without
3160 * actually opening that device. The process is similar to
3161 * what cam_lookup_pass() does, except that we don't
3162 * actually open the passthrough driver instance in the end.
3165 if (cam_get_device(tstr, name, sizeof(name), &unit) == -1) {
3166 warnx("%s", cam_errbuf);
3171 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3172 warn("Unable to open %s", XPT_DEVICE);
3177 bzero(&ccb, sizeof(ccb));
3180 * The function code isn't strictly necessary for the
3181 * GETPASSTHRU ioctl.
3183 ccb.ccb_h.func_code = XPT_GDEVLIST;
3186 * These two are necessary for the GETPASSTHRU ioctl to
3189 strlcpy(ccb.cgdl.periph_name, name,
3190 sizeof(ccb.cgdl.periph_name));
3191 ccb.cgdl.unit_number = unit;
3194 * Attempt to get the passthrough device. This ioctl will
3195 * fail if the device name is null, if the device doesn't
3196 * exist, or if the passthrough driver isn't in the kernel.
3198 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3199 warn("Unable to find bus:target:lun for device %s%d",
3205 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3206 const struct cam_status_entry *entry;
3208 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3209 warnx("Unable to find bus:target_lun for device %s%d, "
3210 "CAM status: %s (%#x)", name, unit,
3211 entry ? entry->status_text : "Unknown",
3219 * The kernel fills in the bus/target/lun. We don't
3220 * need the passthrough device name and unit number since
3221 * we aren't going to open it.
3223 bus = ccb.ccb_h.path_id;
3224 target = ccb.ccb_h.target_id;
3225 lun = ccb.ccb_h.target_lun;
3227 arglist |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3232 if ((arglist & CAM_ARG_BUS)
3233 && (arglist & CAM_ARG_TARGET)
3234 && (arglist & CAM_ARG_LUN))
3235 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3237 error = rescan_or_reset_bus(bus, rescan);
3245 rescan_or_reset_bus(path_id_t bus, int rescan)
3247 union ccb *ccb = NULL, *matchccb = NULL;
3248 int fd = -1, retval;
3253 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3254 warnx("error opening transport layer device %s", XPT_DEVICE);
3255 warn("%s", XPT_DEVICE);
3259 ccb = malloc(sizeof(*ccb));
3261 warn("failed to allocate CCB");
3265 bzero(ccb, sizeof(*ccb));
3267 if (bus != CAM_BUS_WILDCARD) {
3268 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3269 ccb->ccb_h.path_id = bus;
3270 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3271 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3272 ccb->crcn.flags = CAM_FLAG_NONE;
3274 /* run this at a low priority */
3275 ccb->ccb_h.pinfo.priority = 5;
3277 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3278 warn("CAMIOCOMMAND ioctl failed");
3283 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3284 fprintf(stdout, "%s of bus %d was successful\n",
3285 rescan ? "Re-scan" : "Reset", bus);
3287 fprintf(stdout, "%s of bus %d returned error %#x\n",
3288 rescan ? "Re-scan" : "Reset", bus,
3289 ccb->ccb_h.status & CAM_STATUS_MASK);
3298 * The right way to handle this is to modify the xpt so that it can
3299 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3300 * that isn't implemented, so instead we enumerate the busses and
3301 * send the rescan or reset to those busses in the case where the
3302 * given bus is -1 (wildcard). We don't send a rescan or reset
3303 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3304 * no-op, sending a rescan to the xpt bus would result in a status of
3307 matchccb = malloc(sizeof(*matchccb));
3308 if (matchccb == NULL) {
3309 warn("failed to allocate CCB");
3313 bzero(matchccb, sizeof(*matchccb));
3314 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3315 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3316 bufsize = sizeof(struct dev_match_result) * 20;
3317 matchccb->cdm.match_buf_len = bufsize;
3318 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3319 if (matchccb->cdm.matches == NULL) {
3320 warnx("can't malloc memory for matches");
3324 matchccb->cdm.num_matches = 0;
3326 matchccb->cdm.num_patterns = 1;
3327 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3329 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3330 matchccb->cdm.pattern_buf_len);
3331 if (matchccb->cdm.patterns == NULL) {
3332 warnx("can't malloc memory for patterns");
3336 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3337 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3342 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3343 warn("CAMIOCOMMAND ioctl failed");
3348 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3349 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3350 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3351 warnx("got CAM error %#x, CDM error %d\n",
3352 matchccb->ccb_h.status, matchccb->cdm.status);
3357 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3358 struct bus_match_result *bus_result;
3360 /* This shouldn't happen. */
3361 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3364 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3367 * We don't want to rescan or reset the xpt bus.
3370 if (bus_result->path_id == CAM_XPT_PATH_ID)
3373 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3375 ccb->ccb_h.path_id = bus_result->path_id;
3376 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3377 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3378 ccb->crcn.flags = CAM_FLAG_NONE;
3380 /* run this at a low priority */
3381 ccb->ccb_h.pinfo.priority = 5;
3383 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3384 warn("CAMIOCOMMAND ioctl failed");
3389 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3390 fprintf(stdout, "%s of bus %d was successful\n",
3391 rescan? "Re-scan" : "Reset",
3392 bus_result->path_id);
3395 * Don't bail out just yet, maybe the other
3396 * rescan or reset commands will complete
3399 fprintf(stderr, "%s of bus %d returned error "
3400 "%#x\n", rescan? "Re-scan" : "Reset",
3401 bus_result->path_id,
3402 ccb->ccb_h.status & CAM_STATUS_MASK);
3406 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3407 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3414 if (matchccb != NULL) {
3415 free(matchccb->cdm.patterns);
3416 free(matchccb->cdm.matches);
3425 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3428 struct cam_device *device;
3433 if (bus == CAM_BUS_WILDCARD) {
3434 warnx("invalid bus number %d", bus);
3438 if (target == CAM_TARGET_WILDCARD) {
3439 warnx("invalid target number %d", target);
3443 if (lun == CAM_LUN_WILDCARD) {
3444 warnx("invalid lun number %jx", (uintmax_t)lun);
3450 bzero(&ccb, sizeof(union ccb));
3453 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3454 warnx("error opening transport layer device %s\n",
3456 warn("%s", XPT_DEVICE);
3460 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3461 if (device == NULL) {
3462 warnx("%s", cam_errbuf);
3467 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3468 ccb.ccb_h.path_id = bus;
3469 ccb.ccb_h.target_id = target;
3470 ccb.ccb_h.target_lun = lun;
3471 ccb.ccb_h.timeout = 5000;
3472 ccb.crcn.flags = CAM_FLAG_NONE;
3474 /* run this at a low priority */
3475 ccb.ccb_h.pinfo.priority = 5;
3478 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3479 warn("CAMIOCOMMAND ioctl failed");
3484 if (cam_send_ccb(device, &ccb) < 0) {
3485 warn("error sending XPT_RESET_DEV CCB");
3486 cam_close_device(device);
3494 cam_close_device(device);
3497 * An error code of CAM_BDR_SENT is normal for a BDR request.
3499 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3501 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3502 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3503 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3506 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3507 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3508 ccb.ccb_h.status & CAM_STATUS_MASK);
3513 #ifndef MINIMALISTIC
3515 static struct scsi_nv defect_list_type_map[] = {
3516 { "block", SRDD10_BLOCK_FORMAT },
3517 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3518 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3519 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3520 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3521 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3525 readdefects(struct cam_device *device, int argc, char **argv,
3526 char *combinedopt, int task_attr, int retry_count, int timeout)
3528 union ccb *ccb = NULL;
3529 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3530 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3531 size_t hdr_size = 0, entry_size = 0;
3534 u_int8_t *defect_list = NULL;
3535 u_int8_t list_format = 0;
3536 int list_type_set = 0;
3537 u_int32_t dlist_length = 0;
3538 u_int32_t returned_length = 0, valid_len = 0;
3539 u_int32_t num_returned = 0, num_valid = 0;
3540 u_int32_t max_possible_size = 0, hdr_max = 0;
3541 u_int32_t starting_offset = 0;
3542 u_int8_t returned_format, returned_type;
3544 int summary = 0, quiet = 0;
3546 int lists_specified = 0;
3547 int get_length = 1, first_pass = 1;
3550 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3554 scsi_nv_status status;
3557 status = scsi_get_nv(defect_list_type_map,
3558 sizeof(defect_list_type_map) /
3559 sizeof(defect_list_type_map[0]), optarg,
3560 &entry_num, SCSI_NV_FLAG_IG_CASE);
3562 if (status == SCSI_NV_FOUND) {
3563 list_format = defect_list_type_map[
3567 warnx("%s: %s %s option %s", __func__,
3568 (status == SCSI_NV_AMBIGUOUS) ?
3569 "ambiguous" : "invalid", "defect list type",
3572 goto defect_bailout;
3577 arglist |= CAM_ARG_GLIST;
3580 arglist |= CAM_ARG_PLIST;
3591 starting_offset = strtoul(optarg, &endptr, 0);
3592 if (*endptr != '\0') {
3594 warnx("invalid starting offset %s", optarg);
3595 goto defect_bailout;
3607 if (list_type_set == 0) {
3609 warnx("no defect list format specified");
3610 goto defect_bailout;
3613 if (arglist & CAM_ARG_PLIST) {
3614 list_format |= SRDD10_PLIST;
3618 if (arglist & CAM_ARG_GLIST) {
3619 list_format |= SRDD10_GLIST;
3624 * This implies a summary, and was the previous behavior.
3626 if (lists_specified == 0)
3629 ccb = cam_getccb(device);
3634 * We start off asking for just the header to determine how much
3635 * defect data is available. Some Hitachi drives return an error
3636 * if you ask for more data than the drive has. Once we know the
3637 * length, we retry the command with the returned length.
3639 if (use_12byte == 0)
3640 dlist_length = sizeof(*hdr10);
3642 dlist_length = sizeof(*hdr12);
3645 if (defect_list != NULL) {
3649 defect_list = malloc(dlist_length);
3650 if (defect_list == NULL) {
3651 warnx("can't malloc memory for defect list");
3653 goto defect_bailout;
3657 bzero(defect_list, dlist_length);
3660 * cam_getccb() zeros the CCB header only. So we need to zero the
3661 * payload portion of the ccb.
3663 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3665 scsi_read_defects(&ccb->csio,
3666 /*retries*/ retry_count,
3668 /*tag_action*/ task_attr,
3669 /*list_format*/ list_format,
3670 /*addr_desc_index*/ starting_offset,
3671 /*data_ptr*/ defect_list,
3672 /*dxfer_len*/ dlist_length,
3673 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3674 /*sense_len*/ SSD_FULL_SIZE,
3675 /*timeout*/ timeout ? timeout : 5000);
3677 /* Disable freezing the device queue */
3678 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3680 if (cam_send_ccb(device, ccb) < 0) {
3681 perror("error reading defect list");
3683 if (arglist & CAM_ARG_VERBOSE) {
3684 cam_error_print(device, ccb, CAM_ESF_ALL,
3685 CAM_EPF_ALL, stderr);
3689 goto defect_bailout;
3692 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3694 if (use_12byte == 0) {
3695 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3696 hdr_size = sizeof(*hdr10);
3697 hdr_max = SRDDH10_MAX_LENGTH;
3699 if (valid_len >= hdr_size) {
3700 returned_length = scsi_2btoul(hdr10->length);
3701 returned_format = hdr10->format;
3703 returned_length = 0;
3704 returned_format = 0;
3707 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3708 hdr_size = sizeof(*hdr12);
3709 hdr_max = SRDDH12_MAX_LENGTH;
3711 if (valid_len >= hdr_size) {
3712 returned_length = scsi_4btoul(hdr12->length);
3713 returned_format = hdr12->format;
3715 returned_length = 0;
3716 returned_format = 0;
3720 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3721 switch (returned_type) {
3722 case SRDD10_BLOCK_FORMAT:
3723 entry_size = sizeof(struct scsi_defect_desc_block);
3725 case SRDD10_LONG_BLOCK_FORMAT:
3726 entry_size = sizeof(struct scsi_defect_desc_long_block);
3728 case SRDD10_EXT_PHYS_FORMAT:
3729 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3730 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3732 case SRDD10_EXT_BFI_FORMAT:
3733 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3734 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3737 warnx("Unknown defect format 0x%x\n", returned_type);
3739 goto defect_bailout;
3743 max_possible_size = (hdr_max / entry_size) * entry_size;
3744 num_returned = returned_length / entry_size;
3745 num_valid = min(returned_length, valid_len - hdr_size);
3746 num_valid /= entry_size;
3748 if (get_length != 0) {
3751 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3752 CAM_SCSI_STATUS_ERROR) {
3753 struct scsi_sense_data *sense;
3754 int error_code, sense_key, asc, ascq;
3756 sense = &ccb->csio.sense_data;
3757 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3758 ccb->csio.sense_resid, &error_code, &sense_key,
3759 &asc, &ascq, /*show_errors*/ 1);
3762 * If the drive is reporting that it just doesn't
3763 * support the defect list format, go ahead and use
3764 * the length it reported. Otherwise, the length
3765 * may not be valid, so use the maximum.
3767 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3768 && (asc == 0x1c) && (ascq == 0x00)
3769 && (returned_length > 0)) {
3770 if ((use_12byte == 0)
3771 && (returned_length >= max_possible_size)) {
3776 dlist_length = returned_length + hdr_size;
3777 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3778 && (asc == 0x1f) && (ascq == 0x00)
3779 && (returned_length > 0)) {
3780 /* Partial defect list transfer */
3782 * Hitachi drives return this error
3783 * along with a partial defect list if they
3784 * have more defects than the 10 byte
3785 * command can support. Retry with the 12
3788 if (use_12byte == 0) {
3793 dlist_length = returned_length + hdr_size;
3794 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
3795 && (asc == 0x24) && (ascq == 0x00)) {
3796 /* Invalid field in CDB */
3798 * SBC-3 says that if the drive has more
3799 * defects than can be reported with the
3800 * 10 byte command, it should return this
3801 * error and no data. Retry with the 12
3804 if (use_12byte == 0) {
3809 dlist_length = returned_length + hdr_size;
3812 * If we got a SCSI error and no valid length,
3813 * just use the 10 byte maximum. The 12
3814 * byte maximum is too large.
3816 if (returned_length == 0)
3817 dlist_length = SRDD10_MAX_LENGTH;
3819 if ((use_12byte == 0)
3820 && (returned_length >=
3821 max_possible_size)) {
3826 dlist_length = returned_length +
3830 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3833 warnx("Error reading defect header");
3834 if (arglist & CAM_ARG_VERBOSE)
3835 cam_error_print(device, ccb, CAM_ESF_ALL,
3836 CAM_EPF_ALL, stderr);
3837 goto defect_bailout;
3839 if ((use_12byte == 0)
3840 && (returned_length >= max_possible_size)) {
3845 dlist_length = returned_length + hdr_size;
3848 fprintf(stdout, "%u", num_returned);
3850 fprintf(stdout, " defect%s",
3851 (num_returned != 1) ? "s" : "");
3853 fprintf(stdout, "\n");
3855 goto defect_bailout;
3859 * We always limit the list length to the 10-byte maximum
3860 * length (0xffff). The reason is that some controllers
3861 * can't handle larger I/Os, and we can transfer the entire
3862 * 10 byte list in one shot. For drives that support the 12
3863 * byte read defects command, we'll step through the list
3864 * by specifying a starting offset. For drives that don't
3865 * support the 12 byte command's starting offset, we'll
3866 * just display the first 64K.
3868 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3874 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3875 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3876 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3877 struct scsi_sense_data *sense;
3878 int error_code, sense_key, asc, ascq;
3880 sense = &ccb->csio.sense_data;
3881 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3882 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3883 &ascq, /*show_errors*/ 1);
3886 * According to the SCSI spec, if the disk doesn't support
3887 * the requested format, it will generally return a sense
3888 * key of RECOVERED ERROR, and an additional sense code
3889 * of "DEFECT LIST NOT FOUND". HGST drives also return
3890 * Primary/Grown defect list not found errors. So just
3891 * check for an ASC of 0x1c.
3893 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3895 const char *format_str;
3897 format_str = scsi_nv_to_str(defect_list_type_map,
3898 sizeof(defect_list_type_map) /
3899 sizeof(defect_list_type_map[0]),
3900 list_format & SRDD10_DLIST_FORMAT_MASK);
3901 warnx("requested defect format %s not available",
3902 format_str ? format_str : "unknown");
3904 format_str = scsi_nv_to_str(defect_list_type_map,
3905 sizeof(defect_list_type_map) /
3906 sizeof(defect_list_type_map[0]), returned_type);
3907 if (format_str != NULL) {
3908 warnx("Device returned %s format",
3912 warnx("Device returned unknown defect"
3913 " data format %#x", returned_type);
3914 goto defect_bailout;
3918 warnx("Error returned from read defect data command");
3919 if (arglist & CAM_ARG_VERBOSE)
3920 cam_error_print(device, ccb, CAM_ESF_ALL,
3921 CAM_EPF_ALL, stderr);
3922 goto defect_bailout;
3924 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3926 warnx("Error returned from read defect data command");
3927 if (arglist & CAM_ARG_VERBOSE)
3928 cam_error_print(device, ccb, CAM_ESF_ALL,
3929 CAM_EPF_ALL, stderr);
3930 goto defect_bailout;
3933 if (first_pass != 0) {
3934 fprintf(stderr, "Got %d defect", num_returned);
3936 if ((lists_specified == 0) || (num_returned == 0)) {
3937 fprintf(stderr, "s.\n");
3938 goto defect_bailout;
3939 } else if (num_returned == 1)
3940 fprintf(stderr, ":\n");
3942 fprintf(stderr, "s:\n");
3948 * XXX KDM I should probably clean up the printout format for the
3951 switch (returned_type) {
3952 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3953 case SRDD10_EXT_PHYS_FORMAT:
3955 struct scsi_defect_desc_phys_sector *dlist;
3957 dlist = (struct scsi_defect_desc_phys_sector *)
3958 (defect_list + hdr_size);
3960 for (i = 0; i < num_valid; i++) {
3963 sector = scsi_4btoul(dlist[i].sector);
3964 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
3965 mads = (sector & SDD_EXT_PHYS_MADS) ?
3967 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
3969 if (hex_format == 0)
3970 fprintf(stdout, "%d:%d:%d%s",
3971 scsi_3btoul(dlist[i].cylinder),
3973 scsi_4btoul(dlist[i].sector),
3974 mads ? " - " : "\n");
3976 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3977 scsi_3btoul(dlist[i].cylinder),
3979 scsi_4btoul(dlist[i].sector),
3980 mads ? " - " : "\n");
3983 if (num_valid < num_returned) {
3984 starting_offset += num_valid;
3989 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3990 case SRDD10_EXT_BFI_FORMAT:
3992 struct scsi_defect_desc_bytes_from_index *dlist;
3994 dlist = (struct scsi_defect_desc_bytes_from_index *)
3995 (defect_list + hdr_size);
3997 for (i = 0; i < num_valid; i++) {
4000 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4001 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4002 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4003 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4005 if (hex_format == 0)
4006 fprintf(stdout, "%d:%d:%d%s",
4007 scsi_3btoul(dlist[i].cylinder),
4009 scsi_4btoul(dlist[i].bytes_from_index),
4010 mads ? " - " : "\n");
4012 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4013 scsi_3btoul(dlist[i].cylinder),
4015 scsi_4btoul(dlist[i].bytes_from_index),
4016 mads ? " - " : "\n");
4020 if (num_valid < num_returned) {
4021 starting_offset += num_valid;
4026 case SRDDH10_BLOCK_FORMAT:
4028 struct scsi_defect_desc_block *dlist;
4030 dlist = (struct scsi_defect_desc_block *)
4031 (defect_list + hdr_size);
4033 for (i = 0; i < num_valid; i++) {
4034 if (hex_format == 0)
4035 fprintf(stdout, "%u\n",
4036 scsi_4btoul(dlist[i].address));
4038 fprintf(stdout, "0x%x\n",
4039 scsi_4btoul(dlist[i].address));
4042 if (num_valid < num_returned) {
4043 starting_offset += num_valid;
4049 case SRDD10_LONG_BLOCK_FORMAT:
4051 struct scsi_defect_desc_long_block *dlist;
4053 dlist = (struct scsi_defect_desc_long_block *)
4054 (defect_list + hdr_size);
4056 for (i = 0; i < num_valid; i++) {
4057 if (hex_format == 0)
4058 fprintf(stdout, "%ju\n",
4059 (uintmax_t)scsi_8btou64(
4062 fprintf(stdout, "0x%jx\n",
4063 (uintmax_t)scsi_8btou64(
4067 if (num_valid < num_returned) {
4068 starting_offset += num_valid;
4074 fprintf(stderr, "Unknown defect format 0x%x\n",
4081 if (defect_list != NULL)
4089 #endif /* MINIMALISTIC */
4093 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4097 ccb = cam_getccb(device);
4103 #ifndef MINIMALISTIC
4105 mode_sense(struct cam_device *device, int dbd, int pc, int page, int subpage,
4106 int task_attr, int retry_count, int timeout, u_int8_t *data,
4112 ccb = cam_getccb(device);
4115 errx(1, "mode_sense: couldn't allocate CCB");
4117 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4119 scsi_mode_sense_subpage(&ccb->csio,
4120 /* retries */ retry_count,
4122 /* tag_action */ task_attr,
4126 /* subpage */ subpage,
4127 /* param_buf */ data,
4128 /* param_len */ datalen,
4129 /* minimum_cmd_size */ 0,
4130 /* sense_len */ SSD_FULL_SIZE,
4131 /* timeout */ timeout ? timeout : 5000);
4133 if (arglist & CAM_ARG_ERR_RECOVER)
4134 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4136 /* Disable freezing the device queue */
4137 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4139 if (((retval = cam_send_ccb(device, ccb)) < 0)
4140 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4141 if (arglist & CAM_ARG_VERBOSE) {
4142 cam_error_print(device, ccb, CAM_ESF_ALL,
4143 CAM_EPF_ALL, stderr);
4146 cam_close_device(device);
4148 err(1, "error sending mode sense command");
4150 errx(1, "error sending mode sense command");
4157 mode_select(struct cam_device *device, int save_pages, int task_attr,
4158 int retry_count, int timeout, u_int8_t *data, int datalen)
4163 ccb = cam_getccb(device);
4166 errx(1, "mode_select: couldn't allocate CCB");
4168 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4170 scsi_mode_select(&ccb->csio,
4171 /* retries */ retry_count,
4173 /* tag_action */ task_attr,
4174 /* scsi_page_fmt */ 1,
4175 /* save_pages */ save_pages,
4176 /* param_buf */ data,
4177 /* param_len */ datalen,
4178 /* sense_len */ SSD_FULL_SIZE,
4179 /* timeout */ timeout ? timeout : 5000);
4181 if (arglist & CAM_ARG_ERR_RECOVER)
4182 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4184 /* Disable freezing the device queue */
4185 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4187 if (((retval = cam_send_ccb(device, ccb)) < 0)
4188 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4189 if (arglist & CAM_ARG_VERBOSE) {
4190 cam_error_print(device, ccb, CAM_ESF_ALL,
4191 CAM_EPF_ALL, stderr);
4194 cam_close_device(device);
4197 err(1, "error sending mode select command");
4199 errx(1, "error sending mode select command");
4207 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4208 int task_attr, int retry_count, int timeout)
4211 int c, page = -1, subpage = -1, pc = 0;
4212 int binary = 0, dbd = 0, edit = 0, list = 0;
4214 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4229 str_subpage = optarg;
4230 strsep(&str_subpage, ",");
4231 page = strtol(optarg, NULL, 0);
4233 subpage = strtol(str_subpage, NULL, 0);
4237 errx(1, "invalid mode page %d", page);
4239 errx(1, "invalid mode subpage %d", subpage);
4242 pc = strtol(optarg, NULL, 0);
4243 if ((pc < 0) || (pc > 3))
4244 errx(1, "invalid page control field %d", pc);
4251 if (page == -1 && list == 0)
4252 errx(1, "you must specify a mode page!");
4255 mode_list(device, dbd, pc, list > 1, task_attr, retry_count,
4258 mode_edit(device, dbd, pc, page, subpage, edit, binary,
4259 task_attr, retry_count, timeout);
4264 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4265 int task_attr, int retry_count, int timeout)
4268 u_int32_t flags = CAM_DIR_NONE;
4269 u_int8_t *data_ptr = NULL;
4271 u_int8_t atacmd[12];
4272 struct get_hook hook;
4273 int c, data_bytes = 0, valid_bytes;
4279 char *datastr = NULL, *tstr, *resstr = NULL;
4281 int fd_data = 0, fd_res = 0;
4284 ccb = cam_getccb(device);
4287 warnx("scsicmd: error allocating ccb");
4291 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4293 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4297 while (isspace(*tstr) && (*tstr != '\0'))
4299 hook.argc = argc - optind;
4300 hook.argv = argv + optind;
4302 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4305 * Increment optind by the number of arguments the
4306 * encoding routine processed. After each call to
4307 * getopt(3), optind points to the argument that
4308 * getopt should process _next_. In this case,
4309 * that means it points to the first command string
4310 * argument, if there is one. Once we increment
4311 * this, it should point to either the next command
4312 * line argument, or it should be past the end of
4319 while (isspace(*tstr) && (*tstr != '\0'))
4321 hook.argc = argc - optind;
4322 hook.argv = argv + optind;
4324 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4327 * Increment optind by the number of arguments the
4328 * encoding routine processed. After each call to
4329 * getopt(3), optind points to the argument that
4330 * getopt should process _next_. In this case,
4331 * that means it points to the first command string
4332 * argument, if there is one. Once we increment
4333 * this, it should point to either the next command
4334 * line argument, or it should be past the end of
4346 if (arglist & CAM_ARG_CMD_OUT) {
4347 warnx("command must either be "
4348 "read or write, not both");
4350 goto scsicmd_bailout;
4352 arglist |= CAM_ARG_CMD_IN;
4354 data_bytes = strtol(optarg, NULL, 0);
4355 if (data_bytes <= 0) {
4356 warnx("invalid number of input bytes %d",
4359 goto scsicmd_bailout;
4361 hook.argc = argc - optind;
4362 hook.argv = argv + optind;
4365 datastr = cget(&hook, NULL);
4367 * If the user supplied "-" instead of a format, he
4368 * wants the data to be written to stdout.
4370 if ((datastr != NULL)
4371 && (datastr[0] == '-'))
4374 data_ptr = (u_int8_t *)malloc(data_bytes);
4375 if (data_ptr == NULL) {
4376 warnx("can't malloc memory for data_ptr");
4378 goto scsicmd_bailout;
4382 if (arglist & CAM_ARG_CMD_IN) {
4383 warnx("command must either be "
4384 "read or write, not both");
4386 goto scsicmd_bailout;
4388 arglist |= CAM_ARG_CMD_OUT;
4389 flags = CAM_DIR_OUT;
4390 data_bytes = strtol(optarg, NULL, 0);
4391 if (data_bytes <= 0) {
4392 warnx("invalid number of output bytes %d",
4395 goto scsicmd_bailout;
4397 hook.argc = argc - optind;
4398 hook.argv = argv + optind;
4400 datastr = cget(&hook, NULL);
4401 data_ptr = (u_int8_t *)malloc(data_bytes);
4402 if (data_ptr == NULL) {
4403 warnx("can't malloc memory for data_ptr");
4405 goto scsicmd_bailout;
4407 bzero(data_ptr, data_bytes);
4409 * If the user supplied "-" instead of a format, he
4410 * wants the data to be read from stdin.
4412 if ((datastr != NULL)
4413 && (datastr[0] == '-'))
4416 buff_encode_visit(data_ptr, data_bytes, datastr,
4422 hook.argc = argc - optind;
4423 hook.argv = argv + optind;
4425 resstr = cget(&hook, NULL);
4426 if ((resstr != NULL) && (resstr[0] == '-'))
4436 * If fd_data is set, and we're writing to the device, we need to
4437 * read the data the user wants written from stdin.
4439 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4441 int amt_to_read = data_bytes;
4442 u_int8_t *buf_ptr = data_ptr;
4444 for (amt_read = 0; amt_to_read > 0;
4445 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4446 if (amt_read == -1) {
4447 warn("error reading data from stdin");
4449 goto scsicmd_bailout;
4451 amt_to_read -= amt_read;
4452 buf_ptr += amt_read;
4456 if (arglist & CAM_ARG_ERR_RECOVER)
4457 flags |= CAM_PASS_ERR_RECOVER;
4459 /* Disable freezing the device queue */
4460 flags |= CAM_DEV_QFRZDIS;
4464 * This is taken from the SCSI-3 draft spec.
4465 * (T10/1157D revision 0.3)
4466 * The top 3 bits of an opcode are the group code.
4467 * The next 5 bits are the command code.
4468 * Group 0: six byte commands
4469 * Group 1: ten byte commands
4470 * Group 2: ten byte commands
4472 * Group 4: sixteen byte commands
4473 * Group 5: twelve byte commands
4474 * Group 6: vendor specific
4475 * Group 7: vendor specific
4477 switch((cdb[0] >> 5) & 0x7) {
4488 /* computed by buff_encode_visit */
4499 * We should probably use csio_build_visit or something like that
4500 * here, but it's easier to encode arguments as you go. The
4501 * alternative would be skipping the CDB argument and then encoding
4502 * it here, since we've got the data buffer argument by now.
4504 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4506 cam_fill_csio(&ccb->csio,
4507 /*retries*/ retry_count,
4510 /*tag_action*/ task_attr,
4511 /*data_ptr*/ data_ptr,
4512 /*dxfer_len*/ data_bytes,
4513 /*sense_len*/ SSD_FULL_SIZE,
4514 /*cdb_len*/ cdb_len,
4515 /*timeout*/ timeout ? timeout : 5000);
4518 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4520 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4522 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4524 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4526 cam_fill_ataio(&ccb->ataio,
4527 /*retries*/ retry_count,
4531 /*data_ptr*/ data_ptr,
4532 /*dxfer_len*/ data_bytes,
4533 /*timeout*/ timeout ? timeout : 5000);
4536 if (((retval = cam_send_ccb(device, ccb)) < 0)
4537 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4538 const char warnstr[] = "error sending command";
4545 if (arglist & CAM_ARG_VERBOSE) {
4546 cam_error_print(device, ccb, CAM_ESF_ALL,
4547 CAM_EPF_ALL, stderr);
4551 goto scsicmd_bailout;
4554 if (atacmd_len && need_res) {
4556 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4558 fprintf(stdout, "\n");
4561 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4562 ccb->ataio.res.status,
4563 ccb->ataio.res.error,
4564 ccb->ataio.res.lba_low,
4565 ccb->ataio.res.lba_mid,
4566 ccb->ataio.res.lba_high,
4567 ccb->ataio.res.device,
4568 ccb->ataio.res.lba_low_exp,
4569 ccb->ataio.res.lba_mid_exp,
4570 ccb->ataio.res.lba_high_exp,
4571 ccb->ataio.res.sector_count,
4572 ccb->ataio.res.sector_count_exp);
4578 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4580 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4581 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4582 && (arglist & CAM_ARG_CMD_IN)
4583 && (valid_bytes > 0)) {
4585 buff_decode_visit(data_ptr, valid_bytes, datastr,
4587 fprintf(stdout, "\n");
4589 ssize_t amt_written;
4590 int amt_to_write = valid_bytes;
4591 u_int8_t *buf_ptr = data_ptr;
4593 for (amt_written = 0; (amt_to_write > 0) &&
4594 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4595 amt_to_write -= amt_written;
4596 buf_ptr += amt_written;
4598 if (amt_written == -1) {
4599 warn("error writing data to stdout");
4601 goto scsicmd_bailout;
4602 } else if ((amt_written == 0)
4603 && (amt_to_write > 0)) {
4604 warnx("only wrote %u bytes out of %u",
4605 valid_bytes - amt_to_write, valid_bytes);
4612 if ((data_bytes > 0) && (data_ptr != NULL))
4621 camdebug(int argc, char **argv, char *combinedopt)
4624 path_id_t bus = CAM_BUS_WILDCARD;
4625 target_id_t target = CAM_TARGET_WILDCARD;
4626 lun_id_t lun = CAM_LUN_WILDCARD;
4627 char *tstr, *tmpstr = NULL;
4631 bzero(&ccb, sizeof(union ccb));
4633 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4636 arglist |= CAM_ARG_DEBUG_INFO;
4637 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4640 arglist |= CAM_ARG_DEBUG_PERIPH;
4641 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4644 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4645 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4648 arglist |= CAM_ARG_DEBUG_TRACE;
4649 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4652 arglist |= CAM_ARG_DEBUG_XPT;
4653 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4656 arglist |= CAM_ARG_DEBUG_CDB;
4657 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4660 arglist |= CAM_ARG_DEBUG_PROBE;
4661 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4668 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4669 warnx("error opening transport layer device %s", XPT_DEVICE);
4670 warn("%s", XPT_DEVICE);
4677 warnx("you must specify \"off\", \"all\" or a bus,");
4678 warnx("bus:target, or bus:target:lun");
4685 while (isspace(*tstr) && (*tstr != '\0'))
4688 if (strncmp(tstr, "off", 3) == 0) {
4689 ccb.cdbg.flags = CAM_DEBUG_NONE;
4690 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4691 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4692 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4693 } else if (strncmp(tstr, "all", 3) != 0) {
4694 tmpstr = (char *)strtok(tstr, ":");
4695 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4696 bus = strtol(tmpstr, NULL, 0);
4697 arglist |= CAM_ARG_BUS;
4698 tmpstr = (char *)strtok(NULL, ":");
4699 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4700 target = strtol(tmpstr, NULL, 0);
4701 arglist |= CAM_ARG_TARGET;
4702 tmpstr = (char *)strtok(NULL, ":");
4703 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4704 lun = strtol(tmpstr, NULL, 0);
4705 arglist |= CAM_ARG_LUN;
4710 warnx("you must specify \"all\", \"off\", or a bus,");
4711 warnx("bus:target, or bus:target:lun to debug");
4717 ccb.ccb_h.func_code = XPT_DEBUG;
4718 ccb.ccb_h.path_id = bus;
4719 ccb.ccb_h.target_id = target;
4720 ccb.ccb_h.target_lun = lun;
4722 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4723 warn("CAMIOCOMMAND ioctl failed");
4728 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4729 CAM_FUNC_NOTAVAIL) {
4730 warnx("CAM debugging not available");
4731 warnx("you need to put options CAMDEBUG in"
4732 " your kernel config file!");
4734 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4736 warnx("XPT_DEBUG CCB failed with status %#x",
4740 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4742 "Debugging turned off\n");
4745 "Debugging enabled for "
4747 bus, target, (uintmax_t)lun);
4758 tagcontrol(struct cam_device *device, int argc, char **argv,
4768 ccb = cam_getccb(device);
4771 warnx("tagcontrol: error allocating ccb");
4775 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4778 numtags = strtol(optarg, NULL, 0);
4780 warnx("tag count %d is < 0", numtags);
4782 goto tagcontrol_bailout;
4793 cam_path_string(device, pathstr, sizeof(pathstr));
4796 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
4797 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4798 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4799 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4800 ccb->crs.openings = numtags;
4803 if (cam_send_ccb(device, ccb) < 0) {
4804 perror("error sending XPT_REL_SIMQ CCB");
4806 goto tagcontrol_bailout;
4809 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4810 warnx("XPT_REL_SIMQ CCB failed");
4811 cam_error_print(device, ccb, CAM_ESF_ALL,
4812 CAM_EPF_ALL, stderr);
4814 goto tagcontrol_bailout;
4819 fprintf(stdout, "%stagged openings now %d\n",
4820 pathstr, ccb->crs.openings);
4823 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
4825 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4827 if (cam_send_ccb(device, ccb) < 0) {
4828 perror("error sending XPT_GDEV_STATS CCB");
4830 goto tagcontrol_bailout;
4833 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4834 warnx("XPT_GDEV_STATS CCB failed");
4835 cam_error_print(device, ccb, CAM_ESF_ALL,
4836 CAM_EPF_ALL, stderr);
4838 goto tagcontrol_bailout;
4841 if (arglist & CAM_ARG_VERBOSE) {
4842 fprintf(stdout, "%s", pathstr);
4843 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4844 fprintf(stdout, "%s", pathstr);
4845 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4846 fprintf(stdout, "%s", pathstr);
4847 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
4848 fprintf(stdout, "%s", pathstr);
4849 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
4850 fprintf(stdout, "%s", pathstr);
4851 fprintf(stdout, "held %d\n", ccb->cgds.held);
4852 fprintf(stdout, "%s", pathstr);
4853 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4854 fprintf(stdout, "%s", pathstr);
4855 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4858 fprintf(stdout, "%s", pathstr);
4859 fprintf(stdout, "device openings: ");
4861 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4862 ccb->cgds.dev_active);
4872 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4876 cam_path_string(device, pathstr, sizeof(pathstr));
4878 if (cts->transport == XPORT_SPI) {
4879 struct ccb_trans_settings_spi *spi =
4880 &cts->xport_specific.spi;
4882 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4884 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4887 if (spi->sync_offset != 0) {
4890 freq = scsi_calc_syncsrate(spi->sync_period);
4891 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4892 pathstr, freq / 1000, freq % 1000);
4896 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4897 fprintf(stdout, "%soffset: %d\n", pathstr,
4901 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4902 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4903 (0x01 << spi->bus_width) * 8);
4906 if (spi->valid & CTS_SPI_VALID_DISC) {
4907 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4908 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4909 "enabled" : "disabled");
4912 if (cts->transport == XPORT_FC) {
4913 struct ccb_trans_settings_fc *fc =
4914 &cts->xport_specific.fc;
4916 if (fc->valid & CTS_FC_VALID_WWNN)
4917 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
4918 (long long) fc->wwnn);
4919 if (fc->valid & CTS_FC_VALID_WWPN)
4920 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
4921 (long long) fc->wwpn);
4922 if (fc->valid & CTS_FC_VALID_PORT)
4923 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
4924 if (fc->valid & CTS_FC_VALID_SPEED)
4925 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4926 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4928 if (cts->transport == XPORT_SAS) {
4929 struct ccb_trans_settings_sas *sas =
4930 &cts->xport_specific.sas;
4932 if (sas->valid & CTS_SAS_VALID_SPEED)
4933 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4934 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4936 if (cts->transport == XPORT_ATA) {
4937 struct ccb_trans_settings_pata *pata =
4938 &cts->xport_specific.ata;
4940 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4941 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4942 ata_mode2string(pata->mode));
4944 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4945 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4948 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4949 fprintf(stdout, "%sPIO transaction length: %d\n",
4950 pathstr, pata->bytecount);
4953 if (cts->transport == XPORT_SATA) {
4954 struct ccb_trans_settings_sata *sata =
4955 &cts->xport_specific.sata;
4957 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4958 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4961 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4962 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4963 ata_mode2string(sata->mode));
4965 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4966 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4969 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4970 fprintf(stdout, "%sPIO transaction length: %d\n",
4971 pathstr, sata->bytecount);
4973 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4974 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4977 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4978 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4981 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4982 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4986 if (cts->protocol == PROTO_ATA) {
4987 struct ccb_trans_settings_ata *ata=
4988 &cts->proto_specific.ata;
4990 if (ata->valid & CTS_ATA_VALID_TQ) {
4991 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4992 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4993 "enabled" : "disabled");
4996 if (cts->protocol == PROTO_SCSI) {
4997 struct ccb_trans_settings_scsi *scsi=
4998 &cts->proto_specific.scsi;
5000 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5001 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5002 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5003 "enabled" : "disabled");
5010 * Get a path inquiry CCB for the specified device.
5013 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5018 ccb = cam_getccb(device);
5020 warnx("get_cpi: couldn't allocate CCB");
5023 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5024 ccb->ccb_h.func_code = XPT_PATH_INQ;
5025 if (cam_send_ccb(device, ccb) < 0) {
5026 warn("get_cpi: error sending Path Inquiry CCB");
5027 if (arglist & CAM_ARG_VERBOSE)
5028 cam_error_print(device, ccb, CAM_ESF_ALL,
5029 CAM_EPF_ALL, stderr);
5031 goto get_cpi_bailout;
5033 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5034 if (arglist & CAM_ARG_VERBOSE)
5035 cam_error_print(device, ccb, CAM_ESF_ALL,
5036 CAM_EPF_ALL, stderr);
5038 goto get_cpi_bailout;
5040 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5048 * Get a get device CCB for the specified device.
5051 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5056 ccb = cam_getccb(device);
5058 warnx("get_cgd: couldn't allocate CCB");
5061 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5062 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5063 if (cam_send_ccb(device, ccb) < 0) {
5064 warn("get_cgd: error sending Path Inquiry CCB");
5065 if (arglist & CAM_ARG_VERBOSE)
5066 cam_error_print(device, ccb, CAM_ESF_ALL,
5067 CAM_EPF_ALL, stderr);
5069 goto get_cgd_bailout;
5071 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5072 if (arglist & CAM_ARG_VERBOSE)
5073 cam_error_print(device, ccb, CAM_ESF_ALL,
5074 CAM_EPF_ALL, stderr);
5076 goto get_cgd_bailout;
5078 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5086 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5090 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5091 int timeout, int verbosemode)
5093 union ccb *ccb = NULL;
5094 struct scsi_vpd_supported_page_list sup_pages;
5098 ccb = cam_getccb(dev);
5100 warn("Unable to allocate CCB");
5105 /* cam_getccb cleans up the header, caller has to zero the payload */
5106 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5108 bzero(&sup_pages, sizeof(sup_pages));
5110 scsi_inquiry(&ccb->csio,
5111 /*retries*/ retry_count,
5113 /* tag_action */ MSG_SIMPLE_Q_TAG,
5114 /* inq_buf */ (u_int8_t *)&sup_pages,
5115 /* inq_len */ sizeof(sup_pages),
5117 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5118 /* sense_len */ SSD_FULL_SIZE,
5119 /* timeout */ timeout ? timeout : 5000);
5121 /* Disable freezing the device queue */
5122 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5124 if (retry_count != 0)
5125 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5127 if (cam_send_ccb(dev, ccb) < 0) {
5134 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5135 if (verbosemode != 0)
5136 cam_error_print(dev, ccb, CAM_ESF_ALL,
5137 CAM_EPF_ALL, stderr);
5142 for (i = 0; i < sup_pages.length; i++) {
5143 if (sup_pages.list[i] == page_id) {
5156 * devtype is filled in with the type of device.
5157 * Returns 0 for success, non-zero for failure.
5160 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5161 int verbosemode, camcontrol_devtype *devtype)
5163 struct ccb_getdev cgd;
5166 retval = get_cgd(dev, &cgd);
5170 switch (cgd.protocol) {
5176 *devtype = CC_DT_ATA;
5178 break; /*NOTREACHED*/
5180 *devtype = CC_DT_UNKNOWN;
5182 break; /*NOTREACHED*/
5186 * Check for the ATA Information VPD page (0x89). If this is an
5187 * ATA device behind a SCSI to ATA translation layer, this VPD page
5188 * should be present.
5190 * If that VPD page isn't present, or we get an error back from the
5191 * INQUIRY command, we'll just treat it as a normal SCSI device.
5193 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5194 timeout, verbosemode);
5196 *devtype = CC_DT_ATA_BEHIND_SCSI;
5198 *devtype = CC_DT_SCSI;
5207 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5208 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5209 uint16_t sector_count, uint64_t lba, uint8_t command, uint8_t *data_ptr,
5210 uint16_t dxfer_len, uint8_t sense_len, uint32_t timeout,
5211 int is48bit, camcontrol_devtype devtype)
5213 if (devtype == CC_DT_ATA) {
5214 cam_fill_ataio(&ccb->ataio,
5215 /*retries*/ retry_count,
5218 /*tag_action*/ tag_action,
5219 /*data_ptr*/ data_ptr,
5220 /*dxfer_len*/ dxfer_len,
5221 /*timeout*/ timeout);
5222 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5223 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5226 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5229 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5230 protocol |= AP_EXTEND;
5232 scsi_ata_pass_16(&ccb->csio,
5233 /*retries*/ retry_count,
5236 /*tag_action*/ tag_action,
5237 /*protocol*/ protocol,
5238 /*ata_flags*/ ata_flags,
5239 /*features*/ features,
5240 /*sector_count*/ sector_count,
5242 /*command*/ command,
5244 /*data_ptr*/ data_ptr,
5245 /*dxfer_len*/ dxfer_len,
5246 /*sense_len*/ sense_len,
5247 /*timeout*/ timeout);
5253 cpi_print(struct ccb_pathinq *cpi)
5255 char adapter_str[1024];
5258 snprintf(adapter_str, sizeof(adapter_str),
5259 "%s%d:", cpi->dev_name, cpi->unit_number);
5261 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5264 for (i = 1; i < UINT8_MAX; i = i << 1) {
5267 if ((i & cpi->hba_inquiry) == 0)
5270 fprintf(stdout, "%s supports ", adapter_str);
5274 str = "MDP message";
5277 str = "32 bit wide SCSI";
5280 str = "16 bit wide SCSI";
5283 str = "SDTR message";
5286 str = "linked CDBs";
5289 str = "tag queue messages";
5292 str = "soft reset alternative";
5295 str = "SATA Port Multiplier";
5298 str = "unknown PI bit set";
5301 fprintf(stdout, "%s\n", str);
5304 for (i = 1; i < UINT32_MAX; i = i << 1) {
5307 if ((i & cpi->hba_misc) == 0)
5310 fprintf(stdout, "%s ", adapter_str);
5314 str = "bus scans from high ID to low ID";
5317 str = "removable devices not included in scan";
5319 case PIM_NOINITIATOR:
5320 str = "initiator role not supported";
5322 case PIM_NOBUSRESET:
5323 str = "user has disabled initial BUS RESET or"
5324 " controller is in target/mixed mode";
5327 str = "do not send 6-byte commands";
5330 str = "scan bus sequentially";
5333 str = "unknown PIM bit set";
5336 fprintf(stdout, "%s\n", str);
5339 for (i = 1; i < UINT16_MAX; i = i << 1) {
5342 if ((i & cpi->target_sprt) == 0)
5345 fprintf(stdout, "%s supports ", adapter_str);
5348 str = "target mode processor mode";
5351 str = "target mode phase cog. mode";
5353 case PIT_DISCONNECT:
5354 str = "disconnects in target mode";
5357 str = "terminate I/O message in target mode";
5360 str = "group 6 commands in target mode";
5363 str = "group 7 commands in target mode";
5366 str = "unknown PIT bit set";
5370 fprintf(stdout, "%s\n", str);
5372 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5374 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5376 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5378 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5379 adapter_str, cpi->hpath_id);
5380 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5382 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5383 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5384 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5385 adapter_str, cpi->hba_vendor);
5386 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5387 adapter_str, cpi->hba_device);
5388 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5389 adapter_str, cpi->hba_subvendor);
5390 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5391 adapter_str, cpi->hba_subdevice);
5392 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5393 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5394 if (cpi->base_transfer_speed > 1000)
5395 fprintf(stdout, "%d.%03dMB/sec\n",
5396 cpi->base_transfer_speed / 1000,
5397 cpi->base_transfer_speed % 1000);
5399 fprintf(stdout, "%dKB/sec\n",
5400 (cpi->base_transfer_speed % 1000) * 1000);
5401 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5402 adapter_str, cpi->maxio);
5406 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5407 struct ccb_trans_settings *cts)
5413 ccb = cam_getccb(device);
5416 warnx("get_print_cts: error allocating ccb");
5420 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5422 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5424 if (user_settings == 0)
5425 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5427 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5429 if (cam_send_ccb(device, ccb) < 0) {
5430 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5431 if (arglist & CAM_ARG_VERBOSE)
5432 cam_error_print(device, ccb, CAM_ESF_ALL,
5433 CAM_EPF_ALL, stderr);
5435 goto get_print_cts_bailout;
5438 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5439 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5440 if (arglist & CAM_ARG_VERBOSE)
5441 cam_error_print(device, ccb, CAM_ESF_ALL,
5442 CAM_EPF_ALL, stderr);
5444 goto get_print_cts_bailout;
5448 cts_print(device, &ccb->cts);
5451 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5453 get_print_cts_bailout:
5461 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
5462 int timeout, int argc, char **argv, char *combinedopt)
5466 int user_settings = 0;
5468 int disc_enable = -1, tag_enable = -1;
5471 double syncrate = -1;
5474 int change_settings = 0, send_tur = 0;
5475 struct ccb_pathinq cpi;
5477 ccb = cam_getccb(device);
5479 warnx("ratecontrol: error allocating ccb");
5482 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5491 if (strncasecmp(optarg, "enable", 6) == 0)
5493 else if (strncasecmp(optarg, "disable", 7) == 0)
5496 warnx("-D argument \"%s\" is unknown", optarg);
5498 goto ratecontrol_bailout;
5500 change_settings = 1;
5503 mode = ata_string2mode(optarg);
5505 warnx("unknown mode '%s'", optarg);
5507 goto ratecontrol_bailout;
5509 change_settings = 1;
5512 offset = strtol(optarg, NULL, 0);
5514 warnx("offset value %d is < 0", offset);
5516 goto ratecontrol_bailout;
5518 change_settings = 1;
5524 syncrate = atof(optarg);
5526 warnx("sync rate %f is < 0", syncrate);
5528 goto ratecontrol_bailout;
5530 change_settings = 1;
5533 if (strncasecmp(optarg, "enable", 6) == 0)
5535 else if (strncasecmp(optarg, "disable", 7) == 0)
5538 warnx("-T argument \"%s\" is unknown", optarg);
5540 goto ratecontrol_bailout;
5542 change_settings = 1;
5548 bus_width = strtol(optarg, NULL, 0);
5549 if (bus_width < 0) {
5550 warnx("bus width %d is < 0", bus_width);
5552 goto ratecontrol_bailout;
5554 change_settings = 1;
5560 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5562 * Grab path inquiry information, so we can determine whether
5563 * or not the initiator is capable of the things that the user
5566 ccb->ccb_h.func_code = XPT_PATH_INQ;
5567 if (cam_send_ccb(device, ccb) < 0) {
5568 perror("error sending XPT_PATH_INQ CCB");
5569 if (arglist & CAM_ARG_VERBOSE) {
5570 cam_error_print(device, ccb, CAM_ESF_ALL,
5571 CAM_EPF_ALL, stderr);
5574 goto ratecontrol_bailout;
5576 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5577 warnx("XPT_PATH_INQ CCB failed");
5578 if (arglist & CAM_ARG_VERBOSE) {
5579 cam_error_print(device, ccb, CAM_ESF_ALL,
5580 CAM_EPF_ALL, stderr);
5583 goto ratecontrol_bailout;
5585 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5586 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5588 fprintf(stdout, "%s parameters:\n",
5589 user_settings ? "User" : "Current");
5591 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5593 goto ratecontrol_bailout;
5595 if (arglist & CAM_ARG_VERBOSE)
5598 if (change_settings) {
5599 int didsettings = 0;
5600 struct ccb_trans_settings_spi *spi = NULL;
5601 struct ccb_trans_settings_pata *pata = NULL;
5602 struct ccb_trans_settings_sata *sata = NULL;
5603 struct ccb_trans_settings_ata *ata = NULL;
5604 struct ccb_trans_settings_scsi *scsi = NULL;
5606 if (ccb->cts.transport == XPORT_SPI)
5607 spi = &ccb->cts.xport_specific.spi;
5608 if (ccb->cts.transport == XPORT_ATA)
5609 pata = &ccb->cts.xport_specific.ata;
5610 if (ccb->cts.transport == XPORT_SATA)
5611 sata = &ccb->cts.xport_specific.sata;
5612 if (ccb->cts.protocol == PROTO_ATA)
5613 ata = &ccb->cts.proto_specific.ata;
5614 if (ccb->cts.protocol == PROTO_SCSI)
5615 scsi = &ccb->cts.proto_specific.scsi;
5616 ccb->cts.xport_specific.valid = 0;
5617 ccb->cts.proto_specific.valid = 0;
5618 if (spi && disc_enable != -1) {
5619 spi->valid |= CTS_SPI_VALID_DISC;
5620 if (disc_enable == 0)
5621 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5623 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5626 if (tag_enable != -1) {
5627 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5628 warnx("HBA does not support tagged queueing, "
5629 "so you cannot modify tag settings");
5631 goto ratecontrol_bailout;
5634 ata->valid |= CTS_SCSI_VALID_TQ;
5635 if (tag_enable == 0)
5636 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5638 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5641 scsi->valid |= CTS_SCSI_VALID_TQ;
5642 if (tag_enable == 0)
5643 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5645 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5649 if (spi && offset != -1) {
5650 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5651 warnx("HBA is not capable of changing offset");
5653 goto ratecontrol_bailout;
5655 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5656 spi->sync_offset = offset;
5659 if (spi && syncrate != -1) {
5660 int prelim_sync_period;
5662 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5663 warnx("HBA is not capable of changing "
5666 goto ratecontrol_bailout;
5668 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5670 * The sync rate the user gives us is in MHz.
5671 * We need to translate it into KHz for this
5676 * Next, we calculate a "preliminary" sync period
5677 * in tenths of a nanosecond.
5680 prelim_sync_period = 0;
5682 prelim_sync_period = 10000000 / syncrate;
5684 scsi_calc_syncparam(prelim_sync_period);
5687 if (sata && syncrate != -1) {
5688 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5689 warnx("HBA is not capable of changing "
5692 goto ratecontrol_bailout;
5694 if (!user_settings) {
5695 warnx("You can modify only user rate "
5696 "settings for SATA");
5698 goto ratecontrol_bailout;
5700 sata->revision = ata_speed2revision(syncrate * 100);
5701 if (sata->revision < 0) {
5702 warnx("Invalid rate %f", syncrate);
5704 goto ratecontrol_bailout;
5706 sata->valid |= CTS_SATA_VALID_REVISION;
5709 if ((pata || sata) && mode != -1) {
5710 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5711 warnx("HBA is not capable of changing "
5714 goto ratecontrol_bailout;
5716 if (!user_settings) {
5717 warnx("You can modify only user mode "
5718 "settings for ATA/SATA");
5720 goto ratecontrol_bailout;
5724 pata->valid |= CTS_ATA_VALID_MODE;
5727 sata->valid |= CTS_SATA_VALID_MODE;
5732 * The bus_width argument goes like this:
5736 * Therefore, if you shift the number of bits given on the
5737 * command line right by 4, you should get the correct
5740 if (spi && bus_width != -1) {
5742 * We might as well validate things here with a
5743 * decipherable error message, rather than what
5744 * will probably be an indecipherable error message
5745 * by the time it gets back to us.
5747 if ((bus_width == 16)
5748 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5749 warnx("HBA does not support 16 bit bus width");
5751 goto ratecontrol_bailout;
5752 } else if ((bus_width == 32)
5753 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5754 warnx("HBA does not support 32 bit bus width");
5756 goto ratecontrol_bailout;
5757 } else if ((bus_width != 8)
5758 && (bus_width != 16)
5759 && (bus_width != 32)) {
5760 warnx("Invalid bus width %d", bus_width);
5762 goto ratecontrol_bailout;
5764 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5765 spi->bus_width = bus_width >> 4;
5768 if (didsettings == 0) {
5769 goto ratecontrol_bailout;
5771 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5772 if (cam_send_ccb(device, ccb) < 0) {
5773 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5774 if (arglist & CAM_ARG_VERBOSE) {
5775 cam_error_print(device, ccb, CAM_ESF_ALL,
5776 CAM_EPF_ALL, stderr);
5779 goto ratecontrol_bailout;
5781 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5782 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5783 if (arglist & CAM_ARG_VERBOSE) {
5784 cam_error_print(device, ccb, CAM_ESF_ALL,
5785 CAM_EPF_ALL, stderr);
5788 goto ratecontrol_bailout;
5792 retval = testunitready(device, task_attr, retry_count, timeout,
5793 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5795 * If the TUR didn't succeed, just bail.
5799 fprintf(stderr, "Test Unit Ready failed\n");
5800 goto ratecontrol_bailout;
5803 if ((change_settings || send_tur) && !quiet &&
5804 (ccb->cts.transport == XPORT_ATA ||
5805 ccb->cts.transport == XPORT_SATA || send_tur)) {
5806 fprintf(stdout, "New parameters:\n");
5807 retval = get_print_cts(device, user_settings, 0, NULL);
5810 ratecontrol_bailout:
5816 scsiformat(struct cam_device *device, int argc, char **argv,
5817 char *combinedopt, int task_attr, int retry_count, int timeout)
5821 int ycount = 0, quiet = 0;
5822 int error = 0, retval = 0;
5823 int use_timeout = 10800 * 1000;
5825 struct format_defect_list_header fh;
5826 u_int8_t *data_ptr = NULL;
5827 u_int32_t dxfer_len = 0;
5829 int num_warnings = 0;
5832 ccb = cam_getccb(device);
5835 warnx("scsiformat: error allocating ccb");
5839 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5841 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5862 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5863 "following device:\n");
5865 error = scsidoinquiry(device, argc, argv, combinedopt,
5866 task_attr, retry_count, timeout);
5869 warnx("scsiformat: error sending inquiry");
5870 goto scsiformat_bailout;
5875 if (!get_confirmation()) {
5877 goto scsiformat_bailout;
5882 use_timeout = timeout;
5885 fprintf(stdout, "Current format timeout is %d seconds\n",
5886 use_timeout / 1000);
5890 * If the user hasn't disabled questions and didn't specify a
5891 * timeout on the command line, ask them if they want the current
5895 && (timeout == 0)) {
5897 int new_timeout = 0;
5899 fprintf(stdout, "Enter new timeout in seconds or press\n"
5900 "return to keep the current timeout [%d] ",
5901 use_timeout / 1000);
5903 if (fgets(str, sizeof(str), stdin) != NULL) {
5905 new_timeout = atoi(str);
5908 if (new_timeout != 0) {
5909 use_timeout = new_timeout * 1000;
5910 fprintf(stdout, "Using new timeout value %d\n",
5911 use_timeout / 1000);
5916 * Keep this outside the if block below to silence any unused
5917 * variable warnings.
5919 bzero(&fh, sizeof(fh));
5922 * If we're in immediate mode, we've got to include the format
5925 if (immediate != 0) {
5926 fh.byte2 = FU_DLH_IMMED;
5927 data_ptr = (u_int8_t *)&fh;
5928 dxfer_len = sizeof(fh);
5929 byte2 = FU_FMT_DATA;
5930 } else if (quiet == 0) {
5931 fprintf(stdout, "Formatting...");
5935 scsi_format_unit(&ccb->csio,
5936 /* retries */ retry_count,
5938 /* tag_action */ task_attr,
5941 /* data_ptr */ data_ptr,
5942 /* dxfer_len */ dxfer_len,
5943 /* sense_len */ SSD_FULL_SIZE,
5944 /* timeout */ use_timeout);
5946 /* Disable freezing the device queue */
5947 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5949 if (arglist & CAM_ARG_ERR_RECOVER)
5950 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5952 if (((retval = cam_send_ccb(device, ccb)) < 0)
5953 || ((immediate == 0)
5954 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
5955 const char errstr[] = "error sending format command";
5962 if (arglist & CAM_ARG_VERBOSE) {
5963 cam_error_print(device, ccb, CAM_ESF_ALL,
5964 CAM_EPF_ALL, stderr);
5967 goto scsiformat_bailout;
5971 * If we ran in non-immediate mode, we already checked for errors
5972 * above and printed out any necessary information. If we're in
5973 * immediate mode, we need to loop through and get status
5974 * information periodically.
5976 if (immediate == 0) {
5978 fprintf(stdout, "Format Complete\n");
5980 goto scsiformat_bailout;
5987 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5990 * There's really no need to do error recovery or
5991 * retries here, since we're just going to sit in a
5992 * loop and wait for the device to finish formatting.
5994 scsi_test_unit_ready(&ccb->csio,
5997 /* tag_action */ task_attr,
5998 /* sense_len */ SSD_FULL_SIZE,
5999 /* timeout */ 5000);
6001 /* Disable freezing the device queue */
6002 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6004 retval = cam_send_ccb(device, ccb);
6007 * If we get an error from the ioctl, bail out. SCSI
6008 * errors are expected.
6011 warn("error sending CAMIOCOMMAND ioctl");
6012 if (arglist & CAM_ARG_VERBOSE) {
6013 cam_error_print(device, ccb, CAM_ESF_ALL,
6014 CAM_EPF_ALL, stderr);
6017 goto scsiformat_bailout;
6020 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6022 if ((status != CAM_REQ_CMP)
6023 && (status == CAM_SCSI_STATUS_ERROR)
6024 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6025 struct scsi_sense_data *sense;
6026 int error_code, sense_key, asc, ascq;
6028 sense = &ccb->csio.sense_data;
6029 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6030 ccb->csio.sense_resid, &error_code, &sense_key,
6031 &asc, &ascq, /*show_errors*/ 1);
6034 * According to the SCSI-2 and SCSI-3 specs, a
6035 * drive that is in the middle of a format should
6036 * return NOT READY with an ASC of "logical unit
6037 * not ready, format in progress". The sense key
6038 * specific bytes will then be a progress indicator.
6040 if ((sense_key == SSD_KEY_NOT_READY)
6041 && (asc == 0x04) && (ascq == 0x04)) {
6044 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6045 ccb->csio.sense_resid, sks) == 0)
6048 u_int64_t percentage;
6050 val = scsi_2btoul(&sks[1]);
6051 percentage = 10000ull * val;
6054 "\rFormatting: %ju.%02u %% "
6056 (uintmax_t)(percentage /
6058 (unsigned)((percentage /
6062 } else if ((quiet == 0)
6063 && (++num_warnings <= 1)) {
6064 warnx("Unexpected SCSI Sense Key "
6065 "Specific value returned "
6067 scsi_sense_print(device, &ccb->csio,
6069 warnx("Unable to print status "
6070 "information, but format will "
6072 warnx("will exit when format is "
6077 warnx("Unexpected SCSI error during format");
6078 cam_error_print(device, ccb, CAM_ESF_ALL,
6079 CAM_EPF_ALL, stderr);
6081 goto scsiformat_bailout;
6084 } else if (status != CAM_REQ_CMP) {
6085 warnx("Unexpected CAM status %#x", status);
6086 if (arglist & CAM_ARG_VERBOSE)
6087 cam_error_print(device, ccb, CAM_ESF_ALL,
6088 CAM_EPF_ALL, stderr);
6090 goto scsiformat_bailout;
6093 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6096 fprintf(stdout, "\nFormat Complete\n");
6106 scsisanitize(struct cam_device *device, int argc, char **argv,
6107 char *combinedopt, int task_attr, int retry_count, int timeout)
6110 u_int8_t action = 0;
6112 int ycount = 0, quiet = 0;
6113 int error = 0, retval = 0;
6114 int use_timeout = 10800 * 1000;
6120 const char *pattern = NULL;
6121 u_int8_t *data_ptr = NULL;
6122 u_int32_t dxfer_len = 0;
6124 int num_warnings = 0;
6127 ccb = cam_getccb(device);
6130 warnx("scsisanitize: error allocating ccb");
6134 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6136 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6139 if (strcasecmp(optarg, "overwrite") == 0)
6140 action = SSZ_SERVICE_ACTION_OVERWRITE;
6141 else if (strcasecmp(optarg, "block") == 0)
6142 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6143 else if (strcasecmp(optarg, "crypto") == 0)
6144 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6145 else if (strcasecmp(optarg, "exitfailure") == 0)
6146 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6148 warnx("invalid service operation \"%s\"",
6151 goto scsisanitize_bailout;
6155 passes = strtol(optarg, NULL, 0);
6156 if (passes < 1 || passes > 31) {
6157 warnx("invalid passes value %d", passes);
6159 goto scsisanitize_bailout;
6190 warnx("an action is required");
6192 goto scsisanitize_bailout;
6193 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6194 struct scsi_sanitize_parameter_list *pl;
6198 if (pattern == NULL) {
6199 warnx("overwrite action requires -P argument");
6201 goto scsisanitize_bailout;
6203 fd = open(pattern, O_RDONLY);
6205 warn("cannot open pattern file %s", pattern);
6207 goto scsisanitize_bailout;
6209 if (fstat(fd, &sb) < 0) {
6210 warn("cannot stat pattern file %s", pattern);
6212 goto scsisanitize_bailout;
6215 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6216 warnx("pattern file size exceeds maximum value %d",
6217 SSZPL_MAX_PATTERN_LENGTH);
6219 goto scsisanitize_bailout;
6221 dxfer_len = sizeof(*pl) + sz;
6222 data_ptr = calloc(1, dxfer_len);
6223 if (data_ptr == NULL) {
6224 warnx("cannot allocate parameter list buffer");
6226 goto scsisanitize_bailout;
6229 amt = read(fd, data_ptr + sizeof(*pl), sz);
6231 warn("cannot read pattern file");
6233 goto scsisanitize_bailout;
6234 } else if (amt != sz) {
6235 warnx("short pattern file read");
6237 goto scsisanitize_bailout;
6240 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6246 pl->byte1 |= SSZPL_INVERT;
6247 scsi_ulto2b(sz, pl->length);
6253 else if (invert != 0)
6255 else if (pattern != NULL)
6260 warnx("%s argument only valid with overwrite "
6263 goto scsisanitize_bailout;
6268 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6269 "following device:\n");
6271 error = scsidoinquiry(device, argc, argv, combinedopt,
6272 task_attr, retry_count, timeout);
6275 warnx("scsisanitize: error sending inquiry");
6276 goto scsisanitize_bailout;
6281 if (!get_confirmation()) {
6283 goto scsisanitize_bailout;
6288 use_timeout = timeout;
6291 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6292 use_timeout / 1000);
6296 * If the user hasn't disabled questions and didn't specify a
6297 * timeout on the command line, ask them if they want the current
6301 && (timeout == 0)) {
6303 int new_timeout = 0;
6305 fprintf(stdout, "Enter new timeout in seconds or press\n"
6306 "return to keep the current timeout [%d] ",
6307 use_timeout / 1000);
6309 if (fgets(str, sizeof(str), stdin) != NULL) {
6311 new_timeout = atoi(str);
6314 if (new_timeout != 0) {
6315 use_timeout = new_timeout * 1000;
6316 fprintf(stdout, "Using new timeout value %d\n",
6317 use_timeout / 1000);
6323 byte2 |= SSZ_UNRESTRICTED_EXIT;
6327 scsi_sanitize(&ccb->csio,
6328 /* retries */ retry_count,
6330 /* tag_action */ task_attr,
6333 /* data_ptr */ data_ptr,
6334 /* dxfer_len */ dxfer_len,
6335 /* sense_len */ SSD_FULL_SIZE,
6336 /* timeout */ use_timeout);
6338 /* Disable freezing the device queue */
6339 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6341 if (arglist & CAM_ARG_ERR_RECOVER)
6342 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6344 if (cam_send_ccb(device, ccb) < 0) {
6345 warn("error sending sanitize command");
6347 goto scsisanitize_bailout;
6350 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6351 struct scsi_sense_data *sense;
6352 int error_code, sense_key, asc, ascq;
6354 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6355 CAM_SCSI_STATUS_ERROR) {
6356 sense = &ccb->csio.sense_data;
6357 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6358 ccb->csio.sense_resid, &error_code, &sense_key,
6359 &asc, &ascq, /*show_errors*/ 1);
6361 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6362 asc == 0x20 && ascq == 0x00)
6363 warnx("sanitize is not supported by "
6366 warnx("error sanitizing this device");
6368 warnx("error sanitizing this device");
6370 if (arglist & CAM_ARG_VERBOSE) {
6371 cam_error_print(device, ccb, CAM_ESF_ALL,
6372 CAM_EPF_ALL, stderr);
6375 goto scsisanitize_bailout;
6379 * If we ran in non-immediate mode, we already checked for errors
6380 * above and printed out any necessary information. If we're in
6381 * immediate mode, we need to loop through and get status
6382 * information periodically.
6384 if (immediate == 0) {
6386 fprintf(stdout, "Sanitize Complete\n");
6388 goto scsisanitize_bailout;
6395 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6398 * There's really no need to do error recovery or
6399 * retries here, since we're just going to sit in a
6400 * loop and wait for the device to finish sanitizing.
6402 scsi_test_unit_ready(&ccb->csio,
6405 /* tag_action */ task_attr,
6406 /* sense_len */ SSD_FULL_SIZE,
6407 /* timeout */ 5000);
6409 /* Disable freezing the device queue */
6410 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6412 retval = cam_send_ccb(device, ccb);
6415 * If we get an error from the ioctl, bail out. SCSI
6416 * errors are expected.
6419 warn("error sending CAMIOCOMMAND ioctl");
6420 if (arglist & CAM_ARG_VERBOSE) {
6421 cam_error_print(device, ccb, CAM_ESF_ALL,
6422 CAM_EPF_ALL, stderr);
6425 goto scsisanitize_bailout;
6428 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6430 if ((status != CAM_REQ_CMP)
6431 && (status == CAM_SCSI_STATUS_ERROR)
6432 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6433 struct scsi_sense_data *sense;
6434 int error_code, sense_key, asc, ascq;
6436 sense = &ccb->csio.sense_data;
6437 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6438 ccb->csio.sense_resid, &error_code, &sense_key,
6439 &asc, &ascq, /*show_errors*/ 1);
6442 * According to the SCSI-3 spec, a drive that is in the
6443 * middle of a sanitize should return NOT READY with an
6444 * ASC of "logical unit not ready, sanitize in
6445 * progress". The sense key specific bytes will then
6446 * be a progress indicator.
6448 if ((sense_key == SSD_KEY_NOT_READY)
6449 && (asc == 0x04) && (ascq == 0x1b)) {
6452 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6453 ccb->csio.sense_resid, sks) == 0)
6456 u_int64_t percentage;
6458 val = scsi_2btoul(&sks[1]);
6459 percentage = 10000 * val;
6462 "\rSanitizing: %ju.%02u %% "
6464 (uintmax_t)(percentage /
6466 (unsigned)((percentage /
6470 } else if ((quiet == 0)
6471 && (++num_warnings <= 1)) {
6472 warnx("Unexpected SCSI Sense Key "
6473 "Specific value returned "
6474 "during sanitize:");
6475 scsi_sense_print(device, &ccb->csio,
6477 warnx("Unable to print status "
6478 "information, but sanitze will "
6480 warnx("will exit when sanitize is "
6485 warnx("Unexpected SCSI error during sanitize");
6486 cam_error_print(device, ccb, CAM_ESF_ALL,
6487 CAM_EPF_ALL, stderr);
6489 goto scsisanitize_bailout;
6492 } else if (status != CAM_REQ_CMP) {
6493 warnx("Unexpected CAM status %#x", status);
6494 if (arglist & CAM_ARG_VERBOSE)
6495 cam_error_print(device, ccb, CAM_ESF_ALL,
6496 CAM_EPF_ALL, stderr);
6498 goto scsisanitize_bailout;
6500 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6503 fprintf(stdout, "\nSanitize Complete\n");
6505 scsisanitize_bailout:
6508 if (data_ptr != NULL)
6516 scsireportluns(struct cam_device *device, int argc, char **argv,
6517 char *combinedopt, int task_attr, int retry_count, int timeout)
6520 int c, countonly, lunsonly;
6521 struct scsi_report_luns_data *lundata;
6523 uint8_t report_type;
6524 uint32_t list_len, i, j;
6529 report_type = RPL_REPORT_DEFAULT;
6530 ccb = cam_getccb(device);
6533 warnx("%s: error allocating ccb", __func__);
6537 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6542 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6551 if (strcasecmp(optarg, "default") == 0)
6552 report_type = RPL_REPORT_DEFAULT;
6553 else if (strcasecmp(optarg, "wellknown") == 0)
6554 report_type = RPL_REPORT_WELLKNOWN;
6555 else if (strcasecmp(optarg, "all") == 0)
6556 report_type = RPL_REPORT_ALL;
6558 warnx("%s: invalid report type \"%s\"",
6569 if ((countonly != 0)
6570 && (lunsonly != 0)) {
6571 warnx("%s: you can only specify one of -c or -l", __func__);
6576 * According to SPC-4, the allocation length must be at least 16
6577 * bytes -- enough for the header and one LUN.
6579 alloc_len = sizeof(*lundata) + 8;
6583 lundata = malloc(alloc_len);
6585 if (lundata == NULL) {
6586 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6591 scsi_report_luns(&ccb->csio,
6592 /*retries*/ retry_count,
6594 /*tag_action*/ task_attr,
6595 /*select_report*/ report_type,
6596 /*rpl_buf*/ lundata,
6597 /*alloc_len*/ alloc_len,
6598 /*sense_len*/ SSD_FULL_SIZE,
6599 /*timeout*/ timeout ? timeout : 5000);
6601 /* Disable freezing the device queue */
6602 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6604 if (arglist & CAM_ARG_ERR_RECOVER)
6605 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6607 if (cam_send_ccb(device, ccb) < 0) {
6608 warn("error sending REPORT LUNS command");
6610 if (arglist & CAM_ARG_VERBOSE)
6611 cam_error_print(device, ccb, CAM_ESF_ALL,
6612 CAM_EPF_ALL, stderr);
6618 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6619 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6625 list_len = scsi_4btoul(lundata->length);
6628 * If we need to list the LUNs, and our allocation
6629 * length was too short, reallocate and retry.
6631 if ((countonly == 0)
6632 && (list_len > (alloc_len - sizeof(*lundata)))) {
6633 alloc_len = list_len + sizeof(*lundata);
6639 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6640 ((list_len / 8) > 1) ? "s" : "");
6645 for (i = 0; i < (list_len / 8); i++) {
6649 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6651 fprintf(stdout, ",");
6652 switch (lundata->luns[i].lundata[j] &
6653 RPL_LUNDATA_ATYP_MASK) {
6654 case RPL_LUNDATA_ATYP_PERIPH:
6655 if ((lundata->luns[i].lundata[j] &
6656 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6657 fprintf(stdout, "%d:",
6658 lundata->luns[i].lundata[j] &
6659 RPL_LUNDATA_PERIPH_BUS_MASK);
6661 && ((lundata->luns[i].lundata[j+2] &
6662 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6665 fprintf(stdout, "%d",
6666 lundata->luns[i].lundata[j+1]);
6668 case RPL_LUNDATA_ATYP_FLAT: {
6670 tmplun[0] = lundata->luns[i].lundata[j] &
6671 RPL_LUNDATA_FLAT_LUN_MASK;
6672 tmplun[1] = lundata->luns[i].lundata[j+1];
6674 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6678 case RPL_LUNDATA_ATYP_LUN:
6679 fprintf(stdout, "%d:%d:%d",
6680 (lundata->luns[i].lundata[j+1] &
6681 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6682 lundata->luns[i].lundata[j] &
6683 RPL_LUNDATA_LUN_TARG_MASK,
6684 lundata->luns[i].lundata[j+1] &
6685 RPL_LUNDATA_LUN_LUN_MASK);
6687 case RPL_LUNDATA_ATYP_EXTLUN: {
6688 int field_len_code, eam_code;
6690 eam_code = lundata->luns[i].lundata[j] &
6691 RPL_LUNDATA_EXT_EAM_MASK;
6692 field_len_code = (lundata->luns[i].lundata[j] &
6693 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6695 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6696 && (field_len_code == 0x00)) {
6697 fprintf(stdout, "%d",
6698 lundata->luns[i].lundata[j+1]);
6699 } else if ((eam_code ==
6700 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6701 && (field_len_code == 0x03)) {
6705 * This format takes up all 8 bytes.
6706 * If we aren't starting at offset 0,
6710 fprintf(stdout, "Invalid "
6713 "specified format", j);
6717 bzero(tmp_lun, sizeof(tmp_lun));
6718 bcopy(&lundata->luns[i].lundata[j+1],
6719 &tmp_lun[1], sizeof(tmp_lun) - 1);
6720 fprintf(stdout, "%#jx",
6721 (intmax_t)scsi_8btou64(tmp_lun));
6724 fprintf(stderr, "Unknown Extended LUN"
6725 "Address method %#x, length "
6726 "code %#x", eam_code,
6733 fprintf(stderr, "Unknown LUN address method "
6734 "%#x\n", lundata->luns[i].lundata[0] &
6735 RPL_LUNDATA_ATYP_MASK);
6739 * For the flat addressing method, there are no
6740 * other levels after it.
6745 fprintf(stdout, "\n");
6758 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6759 char *combinedopt, int task_attr, int retry_count, int timeout)
6762 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6763 struct scsi_read_capacity_data rcap;
6764 struct scsi_read_capacity_data_long rcaplong;
6778 ccb = cam_getccb(device);
6781 warnx("%s: error allocating ccb", __func__);
6785 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6787 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6814 if ((blocksizeonly != 0)
6815 && (numblocks != 0)) {
6816 warnx("%s: you can only specify one of -b or -N", __func__);
6821 if ((blocksizeonly != 0)
6822 && (sizeonly != 0)) {
6823 warnx("%s: you can only specify one of -b or -s", __func__);
6830 warnx("%s: you can only specify one of -h/-H or -q", __func__);
6836 && (blocksizeonly != 0)) {
6837 warnx("%s: you can only specify one of -h/-H or -b", __func__);
6842 scsi_read_capacity(&ccb->csio,
6843 /*retries*/ retry_count,
6845 /*tag_action*/ task_attr,
6848 /*timeout*/ timeout ? timeout : 5000);
6850 /* Disable freezing the device queue */
6851 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6853 if (arglist & CAM_ARG_ERR_RECOVER)
6854 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6856 if (cam_send_ccb(device, ccb) < 0) {
6857 warn("error sending READ CAPACITY command");
6859 if (arglist & CAM_ARG_VERBOSE)
6860 cam_error_print(device, ccb, CAM_ESF_ALL,
6861 CAM_EPF_ALL, stderr);
6867 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6868 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6873 maxsector = scsi_4btoul(rcap.addr);
6874 block_len = scsi_4btoul(rcap.length);
6877 * A last block of 2^32-1 means that the true capacity is over 2TB,
6878 * and we need to issue the long READ CAPACITY to get the real
6879 * capacity. Otherwise, we're all set.
6881 if (maxsector != 0xffffffff)
6884 scsi_read_capacity_16(&ccb->csio,
6885 /*retries*/ retry_count,
6887 /*tag_action*/ task_attr,
6891 /*rcap_buf*/ (uint8_t *)&rcaplong,
6892 /*rcap_buf_len*/ sizeof(rcaplong),
6893 /*sense_len*/ SSD_FULL_SIZE,
6894 /*timeout*/ timeout ? timeout : 5000);
6896 /* Disable freezing the device queue */
6897 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6899 if (arglist & CAM_ARG_ERR_RECOVER)
6900 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6902 if (cam_send_ccb(device, ccb) < 0) {
6903 warn("error sending READ CAPACITY (16) command");
6905 if (arglist & CAM_ARG_VERBOSE)
6906 cam_error_print(device, ccb, CAM_ESF_ALL,
6907 CAM_EPF_ALL, stderr);
6913 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6914 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6919 maxsector = scsi_8btou64(rcaplong.addr);
6920 block_len = scsi_4btoul(rcaplong.length);
6923 if (blocksizeonly == 0) {
6925 * Humanize implies !quiet, and also implies numblocks.
6927 if (humanize != 0) {
6932 tmpbytes = (maxsector + 1) * block_len;
6933 ret = humanize_number(tmpstr, sizeof(tmpstr),
6934 tmpbytes, "", HN_AUTOSCALE,
6937 HN_DIVISOR_1000 : 0));
6939 warnx("%s: humanize_number failed!", __func__);
6943 fprintf(stdout, "Device Size: %s%s", tmpstr,
6944 (sizeonly == 0) ? ", " : "\n");
6945 } else if (numblocks != 0) {
6946 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6947 "Blocks: " : "", (uintmax_t)maxsector + 1,
6948 (sizeonly == 0) ? ", " : "\n");
6950 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
6951 "Last Block: " : "", (uintmax_t)maxsector,
6952 (sizeonly == 0) ? ", " : "\n");
6956 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
6957 "Block Length: " : "", block_len, (quiet == 0) ?
6966 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
6967 int retry_count, int timeout)
6971 uint8_t *smp_request = NULL, *smp_response = NULL;
6972 int request_size = 0, response_size = 0;
6973 int fd_request = 0, fd_response = 0;
6974 char *datastr = NULL;
6975 struct get_hook hook;
6980 * Note that at the moment we don't support sending SMP CCBs to
6981 * devices that aren't probed by CAM.
6983 ccb = cam_getccb(device);
6985 warnx("%s: error allocating CCB", __func__);
6989 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
6991 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6994 arglist |= CAM_ARG_CMD_IN;
6995 response_size = strtol(optarg, NULL, 0);
6996 if (response_size <= 0) {
6997 warnx("invalid number of response bytes %d",
7000 goto smpcmd_bailout;
7002 hook.argc = argc - optind;
7003 hook.argv = argv + optind;
7006 datastr = cget(&hook, NULL);
7008 * If the user supplied "-" instead of a format, he
7009 * wants the data to be written to stdout.
7011 if ((datastr != NULL)
7012 && (datastr[0] == '-'))
7015 smp_response = (u_int8_t *)malloc(response_size);
7016 if (smp_response == NULL) {
7017 warn("can't malloc memory for SMP response");
7019 goto smpcmd_bailout;
7023 arglist |= CAM_ARG_CMD_OUT;
7024 request_size = strtol(optarg, NULL, 0);
7025 if (request_size <= 0) {
7026 warnx("invalid number of request bytes %d",
7029 goto smpcmd_bailout;
7031 hook.argc = argc - optind;
7032 hook.argv = argv + optind;
7034 datastr = cget(&hook, NULL);
7035 smp_request = (u_int8_t *)malloc(request_size);
7036 if (smp_request == NULL) {
7037 warn("can't malloc memory for SMP request");
7039 goto smpcmd_bailout;
7041 bzero(smp_request, request_size);
7043 * If the user supplied "-" instead of a format, he
7044 * wants the data to be read from stdin.
7046 if ((datastr != NULL)
7047 && (datastr[0] == '-'))
7050 buff_encode_visit(smp_request, request_size,
7061 * If fd_data is set, and we're writing to the device, we need to
7062 * read the data the user wants written from stdin.
7064 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7066 int amt_to_read = request_size;
7067 u_int8_t *buf_ptr = smp_request;
7069 for (amt_read = 0; amt_to_read > 0;
7070 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7071 if (amt_read == -1) {
7072 warn("error reading data from stdin");
7074 goto smpcmd_bailout;
7076 amt_to_read -= amt_read;
7077 buf_ptr += amt_read;
7081 if (((arglist & CAM_ARG_CMD_IN) == 0)
7082 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7083 warnx("%s: need both the request (-r) and response (-R) "
7084 "arguments", __func__);
7086 goto smpcmd_bailout;
7089 flags |= CAM_DEV_QFRZDIS;
7091 cam_fill_smpio(&ccb->smpio,
7092 /*retries*/ retry_count,
7095 /*smp_request*/ smp_request,
7096 /*smp_request_len*/ request_size,
7097 /*smp_response*/ smp_response,
7098 /*smp_response_len*/ response_size,
7099 /*timeout*/ timeout ? timeout : 5000);
7101 ccb->smpio.flags = SMP_FLAG_NONE;
7103 if (((retval = cam_send_ccb(device, ccb)) < 0)
7104 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7105 const char warnstr[] = "error sending command";
7112 if (arglist & CAM_ARG_VERBOSE) {
7113 cam_error_print(device, ccb, CAM_ESF_ALL,
7114 CAM_EPF_ALL, stderr);
7118 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7119 && (response_size > 0)) {
7120 if (fd_response == 0) {
7121 buff_decode_visit(smp_response, response_size,
7122 datastr, arg_put, NULL);
7123 fprintf(stdout, "\n");
7125 ssize_t amt_written;
7126 int amt_to_write = response_size;
7127 u_int8_t *buf_ptr = smp_response;
7129 for (amt_written = 0; (amt_to_write > 0) &&
7130 (amt_written = write(STDOUT_FILENO, buf_ptr,
7131 amt_to_write)) > 0;){
7132 amt_to_write -= amt_written;
7133 buf_ptr += amt_written;
7135 if (amt_written == -1) {
7136 warn("error writing data to stdout");
7138 goto smpcmd_bailout;
7139 } else if ((amt_written == 0)
7140 && (amt_to_write > 0)) {
7141 warnx("only wrote %u bytes out of %u",
7142 response_size - amt_to_write,
7151 if (smp_request != NULL)
7154 if (smp_response != NULL)
7161 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7162 char *combinedopt, int retry_count, int timeout)
7165 struct smp_report_general_request *request = NULL;
7166 struct smp_report_general_response *response = NULL;
7167 struct sbuf *sb = NULL;
7169 int c, long_response = 0;
7173 * Note that at the moment we don't support sending SMP CCBs to
7174 * devices that aren't probed by CAM.
7176 ccb = cam_getccb(device);
7178 warnx("%s: error allocating CCB", __func__);
7182 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7184 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7193 request = malloc(sizeof(*request));
7194 if (request == NULL) {
7195 warn("%s: unable to allocate %zd bytes", __func__,
7201 response = malloc(sizeof(*response));
7202 if (response == NULL) {
7203 warn("%s: unable to allocate %zd bytes", __func__,
7210 smp_report_general(&ccb->smpio,
7214 /*request_len*/ sizeof(*request),
7215 (uint8_t *)response,
7216 /*response_len*/ sizeof(*response),
7217 /*long_response*/ long_response,
7220 if (((retval = cam_send_ccb(device, ccb)) < 0)
7221 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7222 const char warnstr[] = "error sending command";
7229 if (arglist & CAM_ARG_VERBOSE) {
7230 cam_error_print(device, ccb, CAM_ESF_ALL,
7231 CAM_EPF_ALL, stderr);
7238 * If the device supports the long response bit, try again and see
7239 * if we can get all of the data.
7241 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7242 && (long_response == 0)) {
7243 ccb->ccb_h.status = CAM_REQ_INPROG;
7244 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7250 * XXX KDM detect and decode SMP errors here.
7252 sb = sbuf_new_auto();
7254 warnx("%s: error allocating sbuf", __func__);
7258 smp_report_general_sbuf(response, sizeof(*response), sb);
7260 if (sbuf_finish(sb) != 0) {
7261 warnx("%s: sbuf_finish", __func__);
7265 printf("%s", sbuf_data(sb));
7271 if (request != NULL)
7274 if (response != NULL)
7283 static struct camcontrol_opts phy_ops[] = {
7284 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7285 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7286 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7287 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7288 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7289 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7290 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7291 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7292 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7297 smpphycontrol(struct cam_device *device, int argc, char **argv,
7298 char *combinedopt, int retry_count, int timeout)
7301 struct smp_phy_control_request *request = NULL;
7302 struct smp_phy_control_response *response = NULL;
7303 int long_response = 0;
7306 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7308 uint64_t attached_dev_name = 0;
7309 int dev_name_set = 0;
7310 uint32_t min_plr = 0, max_plr = 0;
7311 uint32_t pp_timeout_val = 0;
7312 int slumber_partial = 0;
7313 int set_pp_timeout_val = 0;
7317 * Note that at the moment we don't support sending SMP CCBs to
7318 * devices that aren't probed by CAM.
7320 ccb = cam_getccb(device);
7322 warnx("%s: error allocating CCB", __func__);
7326 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7328 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7336 if (strcasecmp(optarg, "enable") == 0)
7338 else if (strcasecmp(optarg, "disable") == 0)
7341 warnx("%s: Invalid argument %s", __func__,
7348 slumber_partial |= enable <<
7349 SMP_PC_SAS_SLUMBER_SHIFT;
7352 slumber_partial |= enable <<
7353 SMP_PC_SAS_PARTIAL_SHIFT;
7356 slumber_partial |= enable <<
7357 SMP_PC_SATA_SLUMBER_SHIFT;
7360 slumber_partial |= enable <<
7361 SMP_PC_SATA_PARTIAL_SHIFT;
7364 warnx("%s: programmer error", __func__);
7367 break; /*NOTREACHED*/
7372 attached_dev_name = (uintmax_t)strtoumax(optarg,
7381 * We don't do extensive checking here, so this
7382 * will continue to work when new speeds come out.
7384 min_plr = strtoul(optarg, NULL, 0);
7386 || (min_plr > 0xf)) {
7387 warnx("%s: invalid link rate %x",
7395 * We don't do extensive checking here, so this
7396 * will continue to work when new speeds come out.
7398 max_plr = strtoul(optarg, NULL, 0);
7400 || (max_plr > 0xf)) {
7401 warnx("%s: invalid link rate %x",
7408 camcontrol_optret optreturn;
7409 cam_argmask argnums;
7412 if (phy_op_set != 0) {
7413 warnx("%s: only one phy operation argument "
7414 "(-o) allowed", __func__);
7422 * Allow the user to specify the phy operation
7423 * numerically, as well as with a name. This will
7424 * future-proof it a bit, so options that are added
7425 * in future specs can be used.
7427 if (isdigit(optarg[0])) {
7428 phy_operation = strtoul(optarg, NULL, 0);
7429 if ((phy_operation == 0)
7430 || (phy_operation > 0xff)) {
7431 warnx("%s: invalid phy operation %#x",
7432 __func__, phy_operation);
7438 optreturn = getoption(phy_ops, optarg, &phy_operation,
7441 if (optreturn == CC_OR_AMBIGUOUS) {
7442 warnx("%s: ambiguous option %s", __func__,
7447 } else if (optreturn == CC_OR_NOT_FOUND) {
7448 warnx("%s: option %s not found", __func__,
7460 pp_timeout_val = strtoul(optarg, NULL, 0);
7461 if (pp_timeout_val > 15) {
7462 warnx("%s: invalid partial pathway timeout "
7463 "value %u, need a value less than 16",
7464 __func__, pp_timeout_val);
7468 set_pp_timeout_val = 1;
7476 warnx("%s: a PHY (-p phy) argument is required",__func__);
7481 if (((dev_name_set != 0)
7482 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
7483 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
7484 && (dev_name_set == 0))) {
7485 warnx("%s: -d name and -o setdevname arguments both "
7486 "required to set device name", __func__);
7491 request = malloc(sizeof(*request));
7492 if (request == NULL) {
7493 warn("%s: unable to allocate %zd bytes", __func__,
7499 response = malloc(sizeof(*response));
7500 if (response == NULL) {
7501 warn("%s: unable to allocate %zd bytes", __func__,
7507 smp_phy_control(&ccb->smpio,
7512 (uint8_t *)response,
7515 /*expected_exp_change_count*/ 0,
7518 (set_pp_timeout_val != 0) ? 1 : 0,
7526 if (((retval = cam_send_ccb(device, ccb)) < 0)
7527 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7528 const char warnstr[] = "error sending command";
7535 if (arglist & CAM_ARG_VERBOSE) {
7537 * Use CAM_EPF_NORMAL so we only get one line of
7538 * SMP command decoding.
7540 cam_error_print(device, ccb, CAM_ESF_ALL,
7541 CAM_EPF_NORMAL, stderr);
7547 /* XXX KDM print out something here for success? */
7552 if (request != NULL)
7555 if (response != NULL)
7562 smpmaninfo(struct cam_device *device, int argc, char **argv,
7563 char *combinedopt, int retry_count, int timeout)
7566 struct smp_report_manuf_info_request request;
7567 struct smp_report_manuf_info_response response;
7568 struct sbuf *sb = NULL;
7569 int long_response = 0;
7574 * Note that at the moment we don't support sending SMP CCBs to
7575 * devices that aren't probed by CAM.
7577 ccb = cam_getccb(device);
7579 warnx("%s: error allocating CCB", __func__);
7583 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7585 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7594 bzero(&request, sizeof(request));
7595 bzero(&response, sizeof(response));
7597 smp_report_manuf_info(&ccb->smpio,
7602 (uint8_t *)&response,
7607 if (((retval = cam_send_ccb(device, ccb)) < 0)
7608 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7609 const char warnstr[] = "error sending command";
7616 if (arglist & CAM_ARG_VERBOSE) {
7617 cam_error_print(device, ccb, CAM_ESF_ALL,
7618 CAM_EPF_ALL, stderr);
7624 sb = sbuf_new_auto();
7626 warnx("%s: error allocating sbuf", __func__);
7630 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7632 if (sbuf_finish(sb) != 0) {
7633 warnx("%s: sbuf_finish", __func__);
7637 printf("%s", sbuf_data(sb));
7651 getdevid(struct cam_devitem *item)
7654 union ccb *ccb = NULL;
7656 struct cam_device *dev;
7658 dev = cam_open_btl(item->dev_match.path_id,
7659 item->dev_match.target_id,
7660 item->dev_match.target_lun, O_RDWR, NULL);
7663 warnx("%s", cam_errbuf);
7668 item->device_id_len = 0;
7670 ccb = cam_getccb(dev);
7672 warnx("%s: error allocating CCB", __func__);
7677 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
7680 * On the first try, we just probe for the size of the data, and
7681 * then allocate that much memory and try again.
7684 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7685 ccb->ccb_h.flags = CAM_DIR_IN;
7686 ccb->cdai.flags = CDAI_FLAG_NONE;
7687 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7688 ccb->cdai.bufsiz = item->device_id_len;
7689 if (item->device_id_len != 0)
7690 ccb->cdai.buf = (uint8_t *)item->device_id;
7692 if (cam_send_ccb(dev, ccb) < 0) {
7693 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7698 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7699 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7704 if (item->device_id_len == 0) {
7706 * This is our first time through. Allocate the buffer,
7707 * and then go back to get the data.
7709 if (ccb->cdai.provsiz == 0) {
7710 warnx("%s: invalid .provsiz field returned with "
7711 "XPT_GDEV_ADVINFO CCB", __func__);
7715 item->device_id_len = ccb->cdai.provsiz;
7716 item->device_id = malloc(item->device_id_len);
7717 if (item->device_id == NULL) {
7718 warn("%s: unable to allocate %d bytes", __func__,
7719 item->device_id_len);
7723 ccb->ccb_h.status = CAM_REQ_INPROG;
7729 cam_close_device(dev);
7738 * XXX KDM merge this code with getdevtree()?
7741 buildbusdevlist(struct cam_devlist *devlist)
7744 int bufsize, fd = -1;
7745 struct dev_match_pattern *patterns;
7746 struct cam_devitem *item = NULL;
7747 int skip_device = 0;
7750 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7751 warn("couldn't open %s", XPT_DEVICE);
7755 bzero(&ccb, sizeof(union ccb));
7757 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7758 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7759 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7761 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7762 bufsize = sizeof(struct dev_match_result) * 100;
7763 ccb.cdm.match_buf_len = bufsize;
7764 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7765 if (ccb.cdm.matches == NULL) {
7766 warnx("can't malloc memory for matches");
7770 ccb.cdm.num_matches = 0;
7771 ccb.cdm.num_patterns = 2;
7772 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7773 ccb.cdm.num_patterns;
7775 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7776 if (patterns == NULL) {
7777 warnx("can't malloc memory for patterns");
7782 ccb.cdm.patterns = patterns;
7783 bzero(patterns, ccb.cdm.pattern_buf_len);
7785 patterns[0].type = DEV_MATCH_DEVICE;
7786 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7787 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7788 patterns[1].type = DEV_MATCH_PERIPH;
7789 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7790 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7793 * We do the ioctl multiple times if necessary, in case there are
7794 * more than 100 nodes in the EDT.
7799 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7800 warn("error sending CAMIOCOMMAND ioctl");
7805 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7806 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7807 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7808 warnx("got CAM error %#x, CDM error %d\n",
7809 ccb.ccb_h.status, ccb.cdm.status);
7814 for (i = 0; i < ccb.cdm.num_matches; i++) {
7815 switch (ccb.cdm.matches[i].type) {
7816 case DEV_MATCH_DEVICE: {
7817 struct device_match_result *dev_result;
7820 &ccb.cdm.matches[i].result.device_result;
7822 if (dev_result->flags &
7823 DEV_RESULT_UNCONFIGURED) {
7829 item = malloc(sizeof(*item));
7831 warn("%s: unable to allocate %zd bytes",
7832 __func__, sizeof(*item));
7836 bzero(item, sizeof(*item));
7837 bcopy(dev_result, &item->dev_match,
7838 sizeof(*dev_result));
7839 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
7842 if (getdevid(item) != 0) {
7848 case DEV_MATCH_PERIPH: {
7849 struct periph_match_result *periph_result;
7852 &ccb.cdm.matches[i].result.periph_result;
7854 if (skip_device != 0)
7856 item->num_periphs++;
7857 item->periph_matches = realloc(
7858 item->periph_matches,
7860 sizeof(struct periph_match_result));
7861 if (item->periph_matches == NULL) {
7862 warn("%s: error allocating periph "
7867 bcopy(periph_result, &item->periph_matches[
7868 item->num_periphs - 1],
7869 sizeof(*periph_result));
7873 fprintf(stderr, "%s: unexpected match "
7874 "type %d\n", __func__,
7875 ccb.cdm.matches[i].type);
7878 break; /*NOTREACHED*/
7881 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
7882 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
7890 free(ccb.cdm.matches);
7893 freebusdevlist(devlist);
7899 freebusdevlist(struct cam_devlist *devlist)
7901 struct cam_devitem *item, *item2;
7903 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
7904 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
7906 free(item->device_id);
7907 free(item->periph_matches);
7912 static struct cam_devitem *
7913 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
7915 struct cam_devitem *item;
7917 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
7918 struct scsi_vpd_id_descriptor *idd;
7921 * XXX KDM look for LUN IDs as well?
7923 idd = scsi_get_devid(item->device_id,
7924 item->device_id_len,
7925 scsi_devid_is_sas_target);
7929 if (scsi_8btou64(idd->identifier) == sasaddr)
7937 smpphylist(struct cam_device *device, int argc, char **argv,
7938 char *combinedopt, int retry_count, int timeout)
7940 struct smp_report_general_request *rgrequest = NULL;
7941 struct smp_report_general_response *rgresponse = NULL;
7942 struct smp_discover_request *disrequest = NULL;
7943 struct smp_discover_response *disresponse = NULL;
7944 struct cam_devlist devlist;
7946 int long_response = 0;
7953 * Note that at the moment we don't support sending SMP CCBs to
7954 * devices that aren't probed by CAM.
7956 ccb = cam_getccb(device);
7958 warnx("%s: error allocating CCB", __func__);
7962 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7963 STAILQ_INIT(&devlist.dev_queue);
7965 rgrequest = malloc(sizeof(*rgrequest));
7966 if (rgrequest == NULL) {
7967 warn("%s: unable to allocate %zd bytes", __func__,
7968 sizeof(*rgrequest));
7973 rgresponse = malloc(sizeof(*rgresponse));
7974 if (rgresponse == NULL) {
7975 warn("%s: unable to allocate %zd bytes", __func__,
7976 sizeof(*rgresponse));
7981 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7994 smp_report_general(&ccb->smpio,
7998 /*request_len*/ sizeof(*rgrequest),
7999 (uint8_t *)rgresponse,
8000 /*response_len*/ sizeof(*rgresponse),
8001 /*long_response*/ long_response,
8004 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8006 if (((retval = cam_send_ccb(device, ccb)) < 0)
8007 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8008 const char warnstr[] = "error sending command";
8015 if (arglist & CAM_ARG_VERBOSE) {
8016 cam_error_print(device, ccb, CAM_ESF_ALL,
8017 CAM_EPF_ALL, stderr);
8023 num_phys = rgresponse->num_phys;
8025 if (num_phys == 0) {
8027 fprintf(stdout, "%s: No Phys reported\n", __func__);
8032 devlist.path_id = device->path_id;
8034 retval = buildbusdevlist(&devlist);
8039 fprintf(stdout, "%d PHYs:\n", num_phys);
8040 fprintf(stdout, "PHY Attached SAS Address\n");
8043 disrequest = malloc(sizeof(*disrequest));
8044 if (disrequest == NULL) {
8045 warn("%s: unable to allocate %zd bytes", __func__,
8046 sizeof(*disrequest));
8051 disresponse = malloc(sizeof(*disresponse));
8052 if (disresponse == NULL) {
8053 warn("%s: unable to allocate %zd bytes", __func__,
8054 sizeof(*disresponse));
8059 for (i = 0; i < num_phys; i++) {
8060 struct cam_devitem *item;
8061 struct device_match_result *dev_match;
8062 char vendor[16], product[48], revision[16];
8066 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8068 ccb->ccb_h.status = CAM_REQ_INPROG;
8069 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8071 smp_discover(&ccb->smpio,
8075 sizeof(*disrequest),
8076 (uint8_t *)disresponse,
8077 sizeof(*disresponse),
8079 /*ignore_zone_group*/ 0,
8083 if (((retval = cam_send_ccb(device, ccb)) < 0)
8084 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
8085 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
8086 const char warnstr[] = "error sending command";
8093 if (arglist & CAM_ARG_VERBOSE) {
8094 cam_error_print(device, ccb, CAM_ESF_ALL,
8095 CAM_EPF_ALL, stderr);
8101 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
8103 fprintf(stdout, "%3d <vacant>\n", i);
8107 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
8110 item = findsasdevice(&devlist,
8111 scsi_8btou64(disresponse->attached_sas_address));
8115 || (item != NULL)) {
8116 fprintf(stdout, "%3d 0x%016jx", i,
8117 (uintmax_t)scsi_8btou64(
8118 disresponse->attached_sas_address));
8120 fprintf(stdout, "\n");
8123 } else if (quiet != 0)
8126 dev_match = &item->dev_match;
8128 if (dev_match->protocol == PROTO_SCSI) {
8129 cam_strvis(vendor, dev_match->inq_data.vendor,
8130 sizeof(dev_match->inq_data.vendor),
8132 cam_strvis(product, dev_match->inq_data.product,
8133 sizeof(dev_match->inq_data.product),
8135 cam_strvis(revision, dev_match->inq_data.revision,
8136 sizeof(dev_match->inq_data.revision),
8138 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8140 } else if ((dev_match->protocol == PROTO_ATA)
8141 || (dev_match->protocol == PROTO_SATAPM)) {
8142 cam_strvis(product, dev_match->ident_data.model,
8143 sizeof(dev_match->ident_data.model),
8145 cam_strvis(revision, dev_match->ident_data.revision,
8146 sizeof(dev_match->ident_data.revision),
8148 sprintf(tmpstr, "<%s %s>", product, revision);
8150 sprintf(tmpstr, "<>");
8152 fprintf(stdout, " %-33s ", tmpstr);
8155 * If we have 0 periphs, that's a bug...
8157 if (item->num_periphs == 0) {
8158 fprintf(stdout, "\n");
8162 fprintf(stdout, "(");
8163 for (j = 0; j < item->num_periphs; j++) {
8165 fprintf(stdout, ",");
8167 fprintf(stdout, "%s%d",
8168 item->periph_matches[j].periph_name,
8169 item->periph_matches[j].unit_number);
8172 fprintf(stdout, ")\n");
8186 freebusdevlist(&devlist);
8192 atapm(struct cam_device *device, int argc, char **argv,
8193 char *combinedopt, int retry_count, int timeout)
8201 ccb = cam_getccb(device);
8204 warnx("%s: error allocating ccb", __func__);
8208 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8217 if (strcmp(argv[1], "idle") == 0) {
8219 cmd = ATA_IDLE_IMMEDIATE;
8222 } else if (strcmp(argv[1], "standby") == 0) {
8224 cmd = ATA_STANDBY_IMMEDIATE;
8226 cmd = ATA_STANDBY_CMD;
8234 else if (t <= (240 * 5))
8236 else if (t <= (252 * 5))
8237 /* special encoding for 21 minutes */
8239 else if (t <= (11 * 30 * 60))
8240 sc = (t - 1) / (30 * 60) + 241;
8244 retval = ata_do_28bit_cmd(device,
8246 /*retries*/retry_count,
8247 /*flags*/CAM_DIR_NONE,
8248 /*protocol*/AP_PROTO_NON_DATA,
8249 /*tag_action*/MSG_SIMPLE_Q_TAG,
8256 /*timeout*/timeout ? timeout : 30 * 1000,
8264 ataaxm(struct cam_device *device, int argc, char **argv,
8265 char *combinedopt, int retry_count, int timeout)
8273 ccb = cam_getccb(device);
8276 warnx("%s: error allocating ccb", __func__);
8280 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8290 if (strcmp(argv[1], "apm") == 0) {
8306 retval = ata_do_28bit_cmd(device,
8308 /*retries*/retry_count,
8309 /*flags*/CAM_DIR_NONE,
8310 /*protocol*/AP_PROTO_NON_DATA,
8311 /*tag_action*/MSG_SIMPLE_Q_TAG,
8312 /*command*/ATA_SETFEATURES,
8318 /*timeout*/timeout ? timeout : 30 * 1000,
8326 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
8327 int show_sa_errors, int sa_set, int service_action,
8328 int timeout_desc, int task_attr, int retry_count, int timeout,
8329 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
8331 union ccb *ccb = NULL;
8332 uint8_t *buf = NULL;
8333 uint32_t alloc_len = 0, num_opcodes;
8334 uint32_t valid_len = 0;
8335 uint32_t avail_len = 0;
8336 struct scsi_report_supported_opcodes_all *all_hdr;
8337 struct scsi_report_supported_opcodes_one *one;
8342 * Make it clear that we haven't yet allocated or filled anything.
8347 ccb = cam_getccb(device);
8349 warnx("couldn't allocate CCB");
8354 /* cam_getccb cleans up the header, caller has to zero the payload */
8355 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8357 if (opcode_set != 0) {
8358 options |= RSO_OPTIONS_OC;
8360 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
8363 alloc_len = sizeof(*all_hdr) + (num_opcodes *
8364 sizeof(struct scsi_report_supported_opcodes_descr));
8367 if (timeout_desc != 0) {
8368 options |= RSO_RCTD;
8369 alloc_len += num_opcodes *
8370 sizeof(struct scsi_report_supported_opcodes_timeout);
8374 options |= RSO_OPTIONS_OC_SA;
8375 if (show_sa_errors != 0)
8376 options &= ~RSO_OPTIONS_OC;
8385 buf = malloc(alloc_len);
8387 warn("Unable to allocate %u bytes", alloc_len);
8391 bzero(buf, alloc_len);
8393 scsi_report_supported_opcodes(&ccb->csio,
8394 /*retries*/ retry_count,
8396 /*tag_action*/ task_attr,
8397 /*options*/ options,
8398 /*req_opcode*/ opcode,
8399 /*req_service_action*/ service_action,
8401 /*dxfer_len*/ alloc_len,
8402 /*sense_len*/ SSD_FULL_SIZE,
8403 /*timeout*/ timeout ? timeout : 10000);
8405 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8407 if (retry_count != 0)
8408 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
8410 if (cam_send_ccb(device, ccb) < 0) {
8411 perror("error sending REPORT SUPPORTED OPERATION CODES");
8416 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8417 if (verbosemode != 0)
8418 cam_error_print(device, ccb, CAM_ESF_ALL,
8419 CAM_EPF_ALL, stderr);
8425 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
8427 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
8428 && (valid_len >= sizeof(*all_hdr))) {
8429 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
8430 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
8431 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
8432 && (valid_len >= sizeof(*one))) {
8433 uint32_t cdb_length;
8435 one = (struct scsi_report_supported_opcodes_one *)buf;
8436 cdb_length = scsi_2btoul(one->cdb_length);
8437 avail_len = sizeof(*one) + cdb_length;
8438 if (one->support & RSO_ONE_CTDP) {
8439 struct scsi_report_supported_opcodes_timeout *td;
8441 td = (struct scsi_report_supported_opcodes_timeout *)
8443 if (valid_len >= (avail_len + sizeof(td->length))) {
8444 avail_len += scsi_2btoul(td->length) +
8447 avail_len += sizeof(*td);
8453 * avail_len could be zero if we didn't get enough data back from
8454 * thet target to determine
8456 if ((avail_len != 0)
8457 && (avail_len > valid_len)) {
8458 alloc_len = avail_len;
8462 *fill_len = valid_len;
8474 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
8475 int req_sa, uint8_t *buf, uint32_t valid_len)
8477 struct scsi_report_supported_opcodes_one *one;
8478 struct scsi_report_supported_opcodes_timeout *td;
8479 uint32_t cdb_len = 0, td_len = 0;
8480 const char *op_desc = NULL;
8484 one = (struct scsi_report_supported_opcodes_one *)buf;
8487 * If we don't have the full single opcode descriptor, no point in
8490 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8492 warnx("Only %u bytes returned, not enough to verify support",
8498 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
8500 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
8503 printf(", SA 0x%x", req_sa);
8506 switch (one->support & RSO_ONE_SUP_MASK) {
8507 case RSO_ONE_SUP_UNAVAIL:
8508 printf("No command support information currently available\n");
8510 case RSO_ONE_SUP_NOT_SUP:
8511 printf("Command not supported\n");
8514 break; /*NOTREACHED*/
8515 case RSO_ONE_SUP_AVAIL:
8516 printf("Command is supported, complies with a SCSI standard\n");
8518 case RSO_ONE_SUP_VENDOR:
8519 printf("Command is supported, vendor-specific "
8520 "implementation\n");
8523 printf("Unknown command support flags 0x%#x\n",
8524 one->support & RSO_ONE_SUP_MASK);
8529 * If we don't have the CDB length, it isn't exactly an error, the
8530 * command probably isn't supported.
8532 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8536 cdb_len = scsi_2btoul(one->cdb_length);
8539 * If our valid data doesn't include the full reported length,
8540 * return. The caller should have detected this and adjusted his
8541 * allocation length to get all of the available data.
8543 if (valid_len < sizeof(*one) + cdb_len) {
8549 * If all we have is the opcode, there is no point in printing out
8557 printf("CDB usage bitmap:");
8558 for (i = 0; i < cdb_len; i++) {
8559 printf(" %02x", one->cdb_usage[i]);
8564 * If we don't have a timeout descriptor, we're done.
8566 if ((one->support & RSO_ONE_CTDP) == 0)
8570 * If we don't have enough valid length to include the timeout
8571 * descriptor length, we're done.
8573 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
8576 td = (struct scsi_report_supported_opcodes_timeout *)
8577 &buf[sizeof(*one) + cdb_len];
8578 td_len = scsi_2btoul(td->length);
8579 td_len += sizeof(td->length);
8582 * If we don't have the full timeout descriptor, we're done.
8584 if (td_len < sizeof(*td))
8588 * If we don't have enough valid length to contain the full timeout
8589 * descriptor, we're done.
8591 if (valid_len < (sizeof(*one) + cdb_len + td_len))
8594 printf("Timeout information:\n");
8595 printf("Command-specific: 0x%02x\n", td->cmd_specific);
8596 printf("Nominal timeout: %u seconds\n",
8597 scsi_4btoul(td->nominal_time));
8598 printf("Recommended timeout: %u seconds\n",
8599 scsi_4btoul(td->recommended_time));
8606 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
8609 struct scsi_report_supported_opcodes_all *hdr;
8610 struct scsi_report_supported_opcodes_descr *desc;
8611 uint32_t avail_len = 0, used_len = 0;
8615 if (valid_len < sizeof(*hdr)) {
8616 warnx("%s: not enough returned data (%u bytes) opcode list",
8617 __func__, valid_len);
8621 hdr = (struct scsi_report_supported_opcodes_all *)buf;
8622 avail_len = scsi_4btoul(hdr->length);
8623 avail_len += sizeof(hdr->length);
8625 * Take the lesser of the amount of data the drive claims is
8626 * available, and the amount of data the HBA says was returned.
8628 avail_len = MIN(avail_len, valid_len);
8630 used_len = sizeof(hdr->length);
8632 printf("%-6s %4s %8s ",
8633 "Opcode", "SA", "CDB len" );
8636 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
8637 printf(" Description\n");
8639 while ((avail_len - used_len) > sizeof(*desc)) {
8640 struct scsi_report_supported_opcodes_timeout *td;
8642 const char *op_desc = NULL;
8644 cur_ptr = &buf[used_len];
8645 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
8647 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
8648 if (op_desc == NULL)
8649 op_desc = "UNKNOWN";
8651 printf("0x%02x %#4x %8u ", desc->opcode,
8652 scsi_2btoul(desc->service_action),
8653 scsi_2btoul(desc->cdb_length));
8655 used_len += sizeof(*desc);
8657 if ((desc->flags & RSO_CTDP) == 0) {
8658 printf(" %s\n", op_desc);
8663 * If we don't have enough space to fit a timeout
8664 * descriptor, then we're done.
8666 if (avail_len - used_len < sizeof(*td)) {
8667 used_len = avail_len;
8668 printf(" %s\n", op_desc);
8671 cur_ptr = &buf[used_len];
8672 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
8673 td_len = scsi_2btoul(td->length);
8674 td_len += sizeof(td->length);
8678 * If the given timeout descriptor length is less than what
8679 * we understand, skip it.
8681 if (td_len < sizeof(*td)) {
8682 printf(" %s\n", op_desc);
8686 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
8687 scsi_4btoul(td->nominal_time),
8688 scsi_4btoul(td->recommended_time), op_desc);
8695 scsiopcodes(struct cam_device *device, int argc, char **argv,
8696 char *combinedopt, int task_attr, int retry_count, int timeout,
8700 uint32_t opcode = 0, service_action = 0;
8701 int td_set = 0, opcode_set = 0, sa_set = 0;
8702 int show_sa_errors = 1;
8703 uint32_t valid_len = 0;
8704 uint8_t *buf = NULL;
8708 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8714 opcode = strtoul(optarg, &endptr, 0);
8715 if (*endptr != '\0') {
8716 warnx("Invalid opcode \"%s\", must be a number",
8721 if (opcode > 0xff) {
8722 warnx("Invalid opcode 0x%#x, must be between"
8723 "0 and 0xff inclusive", opcode);
8730 service_action = strtoul(optarg, &endptr, 0);
8731 if (*endptr != '\0') {
8732 warnx("Invalid service action \"%s\", must "
8733 "be a number", optarg);
8737 if (service_action > 0xffff) {
8738 warnx("Invalid service action 0x%#x, must "
8739 "be between 0 and 0xffff inclusive",
8754 && (opcode_set == 0)) {
8755 warnx("You must specify an opcode with -o if a service "
8760 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
8761 sa_set, service_action, td_set, task_attr,
8762 retry_count, timeout, verbosemode, &valid_len,
8767 if ((opcode_set != 0)
8769 retval = scsiprintoneopcode(device, opcode, sa_set,
8770 service_action, buf, valid_len);
8772 retval = scsiprintopcodes(device, td_set, buf, valid_len);
8781 #endif /* MINIMALISTIC */
8784 scsireprobe(struct cam_device *device)
8789 ccb = cam_getccb(device);
8792 warnx("%s: error allocating ccb", __func__);
8796 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8798 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
8800 if (cam_send_ccb(device, ccb) < 0) {
8801 warn("error sending XPT_REPROBE_LUN CCB");
8806 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8807 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
8819 usage(int printlong)
8822 fprintf(printlong ? stdout : stderr,
8823 "usage: camcontrol <command> [device id][generic args][command args]\n"
8824 " camcontrol devlist [-b] [-v]\n"
8825 #ifndef MINIMALISTIC
8826 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
8827 " camcontrol tur [dev_id][generic args]\n"
8828 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
8829 " camcontrol identify [dev_id][generic args] [-v]\n"
8830 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
8831 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
8833 " camcontrol start [dev_id][generic args]\n"
8834 " camcontrol stop [dev_id][generic args]\n"
8835 " camcontrol load [dev_id][generic args]\n"
8836 " camcontrol eject [dev_id][generic args]\n"
8837 " camcontrol reprobe [dev_id][generic args]\n"
8838 #endif /* MINIMALISTIC */
8839 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
8840 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
8841 #ifndef MINIMALISTIC
8842 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
8843 " [-q][-s][-S offset][-X]\n"
8844 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
8845 " [-P pagectl][-e | -b][-d]\n"
8846 " camcontrol cmd [dev_id][generic args]\n"
8847 " <-a cmd [args] | -c cmd [args]>\n"
8848 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
8849 " camcontrol smpcmd [dev_id][generic args]\n"
8850 " <-r len fmt [args]> <-R len fmt [args]>\n"
8851 " camcontrol smprg [dev_id][generic args][-l]\n"
8852 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
8853 " [-o operation][-d name][-m rate][-M rate]\n"
8854 " [-T pp_timeout][-a enable|disable]\n"
8855 " [-A enable|disable][-s enable|disable]\n"
8856 " [-S enable|disable]\n"
8857 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
8858 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
8859 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
8860 " <all|bus[:target[:lun]]|off>\n"
8861 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
8862 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
8863 " [-D <enable|disable>][-M mode][-O offset]\n"
8864 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
8865 " [-U][-W bus_width]\n"
8866 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
8867 " camcontrol sanitize [dev_id][generic args]\n"
8868 " [-a overwrite|block|crypto|exitfailure]\n"
8869 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
8871 " camcontrol idle [dev_id][generic args][-t time]\n"
8872 " camcontrol standby [dev_id][generic args][-t time]\n"
8873 " camcontrol sleep [dev_id][generic args]\n"
8874 " camcontrol apm [dev_id][generic args][-l level]\n"
8875 " camcontrol aam [dev_id][generic args][-l level]\n"
8876 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
8878 " camcontrol security [dev_id][generic args]\n"
8879 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
8880 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
8881 " [-U <user|master>] [-y]\n"
8882 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
8883 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
8884 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
8885 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
8886 " [-s scope][-S][-T type][-U]\n"
8887 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
8888 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
8889 " [-p part][-s start][-T type][-V vol]\n"
8890 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
8892 #endif /* MINIMALISTIC */
8893 " camcontrol help\n");
8896 #ifndef MINIMALISTIC
8898 "Specify one of the following options:\n"
8899 "devlist list all CAM devices\n"
8900 "periphlist list all CAM peripheral drivers attached to a device\n"
8901 "tur send a test unit ready to the named device\n"
8902 "inquiry send a SCSI inquiry command to the named device\n"
8903 "identify send a ATA identify command to the named device\n"
8904 "reportluns send a SCSI report luns command to the device\n"
8905 "readcap send a SCSI read capacity command to the device\n"
8906 "start send a Start Unit command to the device\n"
8907 "stop send a Stop Unit command to the device\n"
8908 "load send a Start Unit command to the device with the load bit set\n"
8909 "eject send a Stop Unit command to the device with the eject bit set\n"
8910 "reprobe update capacity information of the given device\n"
8911 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
8912 "reset reset all buses, the given bus, bus:target:lun or device\n"
8913 "defects read the defect list of the specified device\n"
8914 "modepage display or edit (-e) the given mode page\n"
8915 "cmd send the given SCSI command, may need -i or -o as well\n"
8916 "smpcmd send the given SMP command, requires -o and -i\n"
8917 "smprg send the SMP Report General command\n"
8918 "smppc send the SMP PHY Control command, requires -p\n"
8919 "smpphylist display phys attached to a SAS expander\n"
8920 "smpmaninfo send the SMP Report Manufacturer Info command\n"
8921 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
8922 "tags report or set the number of transaction slots for a device\n"
8923 "negotiate report or set device negotiation parameters\n"
8924 "format send the SCSI FORMAT UNIT command to the named device\n"
8925 "sanitize send the SCSI SANITIZE command to the named device\n"
8926 "idle send the ATA IDLE command to the named device\n"
8927 "standby send the ATA STANDBY command to the named device\n"
8928 "sleep send the ATA SLEEP command to the named device\n"
8929 "fwdownload program firmware of the named device with the given image\n"
8930 "security report or send ATA security commands to the named device\n"
8931 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
8932 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
8933 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
8934 "help this message\n"
8935 "Device Identifiers:\n"
8936 "bus:target specify the bus and target, lun defaults to 0\n"
8937 "bus:target:lun specify the bus, target and lun\n"
8938 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
8939 "Generic arguments:\n"
8940 "-v be verbose, print out sense information\n"
8941 "-t timeout command timeout in seconds, overrides default timeout\n"
8942 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
8943 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
8944 "-E have the kernel attempt to perform SCSI error recovery\n"
8945 "-C count specify the SCSI command retry count (needs -E to work)\n"
8946 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
8947 "modepage arguments:\n"
8948 "-l list all available mode pages\n"
8949 "-m page specify the mode page to view or edit\n"
8950 "-e edit the specified mode page\n"
8951 "-b force view to binary mode\n"
8952 "-d disable block descriptors for mode sense\n"
8953 "-P pgctl page control field 0-3\n"
8954 "defects arguments:\n"
8955 "-f format specify defect list format (block, bfi or phys)\n"
8956 "-G get the grown defect list\n"
8957 "-P get the permanent defect list\n"
8958 "inquiry arguments:\n"
8959 "-D get the standard inquiry data\n"
8960 "-S get the serial number\n"
8961 "-R get the transfer rate, etc.\n"
8962 "reportluns arguments:\n"
8963 "-c only report a count of available LUNs\n"
8964 "-l only print out luns, and not a count\n"
8965 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
8966 "readcap arguments\n"
8967 "-b only report the blocksize\n"
8968 "-h human readable device size, base 2\n"
8969 "-H human readable device size, base 10\n"
8970 "-N print the number of blocks instead of last block\n"
8971 "-q quiet, print numbers only\n"
8972 "-s only report the last block/device size\n"
8974 "-c cdb [args] specify the SCSI CDB\n"
8975 "-i len fmt specify input data and input data format\n"
8976 "-o len fmt [args] specify output data and output data fmt\n"
8977 "smpcmd arguments:\n"
8978 "-r len fmt [args] specify the SMP command to be sent\n"
8979 "-R len fmt [args] specify SMP response format\n"
8980 "smprg arguments:\n"
8981 "-l specify the long response format\n"
8982 "smppc arguments:\n"
8983 "-p phy specify the PHY to operate on\n"
8984 "-l specify the long request/response format\n"
8985 "-o operation specify the phy control operation\n"
8986 "-d name set the attached device name\n"
8987 "-m rate set the minimum physical link rate\n"
8988 "-M rate set the maximum physical link rate\n"
8989 "-T pp_timeout set the partial pathway timeout value\n"
8990 "-a enable|disable enable or disable SATA slumber\n"
8991 "-A enable|disable enable or disable SATA partial phy power\n"
8992 "-s enable|disable enable or disable SAS slumber\n"
8993 "-S enable|disable enable or disable SAS partial phy power\n"
8994 "smpphylist arguments:\n"
8995 "-l specify the long response format\n"
8996 "-q only print phys with attached devices\n"
8997 "smpmaninfo arguments:\n"
8998 "-l specify the long response format\n"
8999 "debug arguments:\n"
9000 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
9001 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
9002 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
9003 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
9005 "-N tags specify the number of tags to use for this device\n"
9006 "-q be quiet, don't report the number of tags\n"
9007 "-v report a number of tag-related parameters\n"
9008 "negotiate arguments:\n"
9009 "-a send a test unit ready after negotiation\n"
9010 "-c report/set current negotiation settings\n"
9011 "-D <arg> \"enable\" or \"disable\" disconnection\n"
9012 "-M mode set ATA mode\n"
9013 "-O offset set command delay offset\n"
9014 "-q be quiet, don't report anything\n"
9015 "-R syncrate synchronization rate in MHz\n"
9016 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
9017 "-U report/set user negotiation settings\n"
9018 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
9019 "-v also print a Path Inquiry CCB for the controller\n"
9020 "format arguments:\n"
9021 "-q be quiet, don't print status messages\n"
9022 "-r run in report only mode\n"
9023 "-w don't send immediate format command\n"
9024 "-y don't ask any questions\n"
9025 "sanitize arguments:\n"
9026 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
9027 "-c passes overwrite passes to perform (1 to 31)\n"
9028 "-I invert overwrite pattern after each pass\n"
9029 "-P pattern path to overwrite pattern file\n"
9030 "-q be quiet, don't print status messages\n"
9031 "-r run in report only mode\n"
9032 "-U run operation in unrestricted completion exit mode\n"
9033 "-w don't send immediate sanitize command\n"
9034 "-y don't ask any questions\n"
9035 "idle/standby arguments:\n"
9036 "-t <arg> number of seconds before respective state.\n"
9037 "fwdownload arguments:\n"
9038 "-f fw_image path to firmware image file\n"
9039 "-q don't print informational messages, only errors\n"
9040 "-s run in simulation mode\n"
9041 "-v print info for every firmware segment sent to device\n"
9042 "-y don't ask any questions\n"
9043 "security arguments:\n"
9044 "-d pwd disable security using the given password for the selected\n"
9046 "-e pwd erase the device using the given pwd for the selected user\n"
9047 "-f freeze the security configuration of the specified device\n"
9048 "-h pwd enhanced erase the device using the given pwd for the\n"
9050 "-k pwd unlock the device using the given pwd for the selected\n"
9052 "-l <high|maximum> specifies which security level to set: high or maximum\n"
9053 "-q be quiet, do not print any status messages\n"
9054 "-s pwd password the device (enable security) using the given\n"
9055 " pwd for the selected user\n"
9056 "-T timeout overrides the timeout (seconds) used for erase operation\n"
9057 "-U <user|master> specifies which user to set: user or master\n"
9058 "-y don't ask any questions\n"
9060 "-f freeze the HPA configuration of the device\n"
9061 "-l lock the HPA configuration of the device\n"
9062 "-P make the HPA max sectors persist\n"
9063 "-p pwd Set the HPA configuration password required for unlock\n"
9065 "-q be quiet, do not print any status messages\n"
9066 "-s sectors configures the maximum user accessible sectors of the\n"
9068 "-U pwd unlock the HPA configuration of the device\n"
9069 "-y don't ask any questions\n"
9070 "persist arguments:\n"
9071 "-i action specify read_keys, read_reservation, report_cap, or\n"
9072 " read_full_status\n"
9073 "-o action specify register, register_ignore, reserve, release,\n"
9074 " clear, preempt, preempt_abort, register_move, replace_lost\n"
9075 "-a set the All Target Ports (ALL_TG_PT) bit\n"
9076 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
9077 "-k key specify the Reservation Key\n"
9078 "-K sa_key specify the Service Action Reservation Key\n"
9079 "-p set the Activate Persist Through Power Loss bit\n"
9080 "-R rtp specify the Relative Target Port\n"
9081 "-s scope specify the scope: lun, extent, element or a number\n"
9082 "-S specify Transport ID for register, requires -I\n"
9083 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
9084 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
9085 "-U unregister the current initiator for register_move\n"
9086 "attrib arguments:\n"
9087 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
9089 "-w attr specify an attribute to write, one -w argument per attr\n"
9090 "-a attr_num only display this attribute number\n"
9091 "-c get cached attributes\n"
9092 "-e elem_addr request attributes for the given element in a changer\n"
9093 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
9094 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
9095 " field_none, field_desc, field_num, field_size, field_rw\n"
9096 "-p partition request attributes for the given partition\n"
9097 "-s start_attr request attributes starting at the given number\n"
9098 "-T elem_type specify the element type (used with -e)\n"
9099 "-V logical_vol specify the logical volume ID\n"
9100 "opcodes arguments:\n"
9101 "-o opcode specify the individual opcode to list\n"
9102 "-s service_action specify the service action for the opcode\n"
9103 "-N do not return SCSI error for unsupported SA\n"
9104 "-T request nominal and recommended timeout values\n"
9106 #endif /* MINIMALISTIC */
9110 main(int argc, char **argv)
9113 char *device = NULL;
9115 struct cam_device *cam_dev = NULL;
9116 int timeout = 0, retry_count = 1;
9117 camcontrol_optret optreturn;
9119 const char *mainopt = "C:En:Q:t:u:v";
9120 const char *subopt = NULL;
9121 char combinedopt[256];
9122 int error = 0, optstart = 2;
9123 int task_attr = MSG_SIMPLE_Q_TAG;
9125 #ifndef MINIMALISTIC
9129 #endif /* MINIMALISTIC */
9131 cmdlist = CAM_CMD_NONE;
9132 arglist = CAM_ARG_NONE;
9140 * Get the base option.
9142 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
9144 if (optreturn == CC_OR_AMBIGUOUS) {
9145 warnx("ambiguous option %s", argv[1]);
9148 } else if (optreturn == CC_OR_NOT_FOUND) {
9149 warnx("option %s not found", argv[1]);
9155 * Ahh, getopt(3) is a pain.
9157 * This is a gross hack. There really aren't many other good
9158 * options (excuse the pun) for parsing options in a situation like
9159 * this. getopt is kinda braindead, so you end up having to run
9160 * through the options twice, and give each invocation of getopt
9161 * the option string for the other invocation.
9163 * You would think that you could just have two groups of options.
9164 * The first group would get parsed by the first invocation of
9165 * getopt, and the second group would get parsed by the second
9166 * invocation of getopt. It doesn't quite work out that way. When
9167 * the first invocation of getopt finishes, it leaves optind pointing
9168 * to the argument _after_ the first argument in the second group.
9169 * So when the second invocation of getopt comes around, it doesn't
9170 * recognize the first argument it gets and then bails out.
9172 * A nice alternative would be to have a flag for getopt that says
9173 * "just keep parsing arguments even when you encounter an unknown
9174 * argument", but there isn't one. So there's no real clean way to
9175 * easily parse two sets of arguments without having one invocation
9176 * of getopt know about the other.
9178 * Without this hack, the first invocation of getopt would work as
9179 * long as the generic arguments are first, but the second invocation
9180 * (in the subfunction) would fail in one of two ways. In the case
9181 * where you don't set optreset, it would fail because optind may be
9182 * pointing to the argument after the one it should be pointing at.
9183 * In the case where you do set optreset, and reset optind, it would
9184 * fail because getopt would run into the first set of options, which
9185 * it doesn't understand.
9187 * All of this would "sort of" work if you could somehow figure out
9188 * whether optind had been incremented one option too far. The
9189 * mechanics of that, however, are more daunting than just giving
9190 * both invocations all of the expect options for either invocation.
9192 * Needless to say, I wouldn't mind if someone invented a better
9193 * (non-GPL!) command line parsing interface than getopt. I
9194 * wouldn't mind if someone added more knobs to getopt to make it
9195 * work better. Who knows, I may talk myself into doing it someday,
9196 * if the standards weenies let me. As it is, it just leads to
9197 * hackery like this and causes people to avoid it in some cases.
9199 * KDM, September 8th, 1998
9202 sprintf(combinedopt, "%s%s", mainopt, subopt);
9204 sprintf(combinedopt, "%s", mainopt);
9207 * For these options we do not parse optional device arguments and
9208 * we do not open a passthrough device.
9210 if ((cmdlist == CAM_CMD_RESCAN)
9211 || (cmdlist == CAM_CMD_RESET)
9212 || (cmdlist == CAM_CMD_DEVTREE)
9213 || (cmdlist == CAM_CMD_USAGE)
9214 || (cmdlist == CAM_CMD_DEBUG))
9217 #ifndef MINIMALISTIC
9219 && (argc > 2 && argv[2][0] != '-')) {
9223 if (isdigit(argv[2][0])) {
9224 /* device specified as bus:target[:lun] */
9225 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9227 errx(1, "numeric device specification must "
9228 "be either bus:target, or "
9230 /* default to 0 if lun was not specified */
9231 if ((arglist & CAM_ARG_LUN) == 0) {
9233 arglist |= CAM_ARG_LUN;
9237 if (cam_get_device(argv[2], name, sizeof name, &unit)
9239 errx(1, "%s", cam_errbuf);
9240 device = strdup(name);
9241 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
9245 #endif /* MINIMALISTIC */
9247 * Start getopt processing at argv[2/3], since we've already
9248 * accepted argv[1..2] as the command name, and as a possible
9254 * Now we run through the argument list looking for generic
9255 * options, and ignoring options that possibly belong to
9258 while ((c = getopt(argc, argv, combinedopt))!= -1){
9261 retry_count = strtol(optarg, NULL, 0);
9262 if (retry_count < 0)
9263 errx(1, "retry count %d is < 0",
9265 arglist |= CAM_ARG_RETRIES;
9268 arglist |= CAM_ARG_ERR_RECOVER;
9271 arglist |= CAM_ARG_DEVICE;
9273 while (isspace(*tstr) && (*tstr != '\0'))
9275 device = (char *)strdup(tstr);
9279 int table_entry = 0;
9282 while (isspace(*tstr) && (*tstr != '\0'))
9284 if (isdigit(*tstr)) {
9285 task_attr = strtol(tstr, &endptr, 0);
9286 if (*endptr != '\0') {
9287 errx(1, "Invalid queue option "
9292 scsi_nv_status status;
9294 table_size = sizeof(task_attrs) /
9295 sizeof(task_attrs[0]);
9296 status = scsi_get_nv(task_attrs,
9297 table_size, tstr, &table_entry,
9298 SCSI_NV_FLAG_IG_CASE);
9299 if (status == SCSI_NV_FOUND)
9300 task_attr = task_attrs[
9303 errx(1, "%s option %s",
9304 (status == SCSI_NV_AMBIGUOUS)?
9305 "ambiguous" : "invalid",
9312 timeout = strtol(optarg, NULL, 0);
9314 errx(1, "invalid timeout %d", timeout);
9315 /* Convert the timeout from seconds to ms */
9317 arglist |= CAM_ARG_TIMEOUT;
9320 arglist |= CAM_ARG_UNIT;
9321 unit = strtol(optarg, NULL, 0);
9324 arglist |= CAM_ARG_VERBOSE;
9331 #ifndef MINIMALISTIC
9333 * For most commands we'll want to open the passthrough device
9334 * associated with the specified device. In the case of the rescan
9335 * commands, we don't use a passthrough device at all, just the
9336 * transport layer device.
9339 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
9340 && (((arglist & CAM_ARG_DEVICE) == 0)
9341 || ((arglist & CAM_ARG_UNIT) == 0))) {
9342 errx(1, "subcommand \"%s\" requires a valid device "
9343 "identifier", argv[1]);
9346 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
9347 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
9348 cam_open_spec_device(device,unit,O_RDWR,NULL)))
9350 errx(1,"%s", cam_errbuf);
9352 #endif /* MINIMALISTIC */
9355 * Reset optind to 2, and reset getopt, so these routines can parse
9356 * the arguments again.
9362 #ifndef MINIMALISTIC
9363 case CAM_CMD_DEVLIST:
9364 error = getdevlist(cam_dev);
9367 error = atahpa(cam_dev, retry_count, timeout,
9368 argc, argv, combinedopt);
9370 #endif /* MINIMALISTIC */
9371 case CAM_CMD_DEVTREE:
9372 error = getdevtree(argc, argv, combinedopt);
9374 #ifndef MINIMALISTIC
9376 error = testunitready(cam_dev, task_attr, retry_count,
9379 case CAM_CMD_INQUIRY:
9380 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
9381 task_attr, retry_count, timeout);
9383 case CAM_CMD_IDENTIFY:
9384 error = ataidentify(cam_dev, retry_count, timeout);
9386 case CAM_CMD_STARTSTOP:
9387 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
9388 arglist & CAM_ARG_EJECT, task_attr,
9389 retry_count, timeout);
9391 #endif /* MINIMALISTIC */
9392 case CAM_CMD_RESCAN:
9393 error = dorescan_or_reset(argc, argv, 1);
9396 error = dorescan_or_reset(argc, argv, 0);
9398 #ifndef MINIMALISTIC
9399 case CAM_CMD_READ_DEFECTS:
9400 error = readdefects(cam_dev, argc, argv, combinedopt,
9401 task_attr, retry_count, timeout);
9403 case CAM_CMD_MODE_PAGE:
9404 modepage(cam_dev, argc, argv, combinedopt,
9405 task_attr, retry_count, timeout);
9407 case CAM_CMD_SCSI_CMD:
9408 error = scsicmd(cam_dev, argc, argv, combinedopt,
9409 task_attr, retry_count, timeout);
9411 case CAM_CMD_SMP_CMD:
9412 error = smpcmd(cam_dev, argc, argv, combinedopt,
9413 retry_count, timeout);
9415 case CAM_CMD_SMP_RG:
9416 error = smpreportgeneral(cam_dev, argc, argv,
9417 combinedopt, retry_count,
9420 case CAM_CMD_SMP_PC:
9421 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
9422 retry_count, timeout);
9424 case CAM_CMD_SMP_PHYLIST:
9425 error = smpphylist(cam_dev, argc, argv, combinedopt,
9426 retry_count, timeout);
9428 case CAM_CMD_SMP_MANINFO:
9429 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
9430 retry_count, timeout);
9433 error = camdebug(argc, argv, combinedopt);
9436 error = tagcontrol(cam_dev, argc, argv, combinedopt);
9439 error = ratecontrol(cam_dev, task_attr, retry_count,
9440 timeout, argc, argv, combinedopt);
9442 case CAM_CMD_FORMAT:
9443 error = scsiformat(cam_dev, argc, argv,
9444 combinedopt, task_attr, retry_count,
9447 case CAM_CMD_REPORTLUNS:
9448 error = scsireportluns(cam_dev, argc, argv,
9449 combinedopt, task_attr,
9450 retry_count, timeout);
9452 case CAM_CMD_READCAP:
9453 error = scsireadcapacity(cam_dev, argc, argv,
9454 combinedopt, task_attr,
9455 retry_count, timeout);
9458 case CAM_CMD_STANDBY:
9460 error = atapm(cam_dev, argc, argv,
9461 combinedopt, retry_count, timeout);
9465 error = ataaxm(cam_dev, argc, argv,
9466 combinedopt, retry_count, timeout);
9468 case CAM_CMD_SECURITY:
9469 error = atasecurity(cam_dev, retry_count, timeout,
9470 argc, argv, combinedopt);
9472 case CAM_CMD_DOWNLOAD_FW:
9473 error = fwdownload(cam_dev, argc, argv, combinedopt,
9474 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
9477 case CAM_CMD_SANITIZE:
9478 error = scsisanitize(cam_dev, argc, argv,
9479 combinedopt, task_attr,
9480 retry_count, timeout);
9482 case CAM_CMD_PERSIST:
9483 error = scsipersist(cam_dev, argc, argv, combinedopt,
9484 task_attr, retry_count, timeout,
9485 arglist & CAM_ARG_VERBOSE,
9486 arglist & CAM_ARG_ERR_RECOVER);
9488 case CAM_CMD_ATTRIB:
9489 error = scsiattrib(cam_dev, argc, argv, combinedopt,
9490 task_attr, retry_count, timeout,
9491 arglist & CAM_ARG_VERBOSE,
9492 arglist & CAM_ARG_ERR_RECOVER);
9494 case CAM_CMD_OPCODES:
9495 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
9496 task_attr, retry_count, timeout,
9497 arglist & CAM_ARG_VERBOSE);
9499 case CAM_CMD_REPROBE:
9500 error = scsireprobe(cam_dev);
9503 #endif /* MINIMALISTIC */
9513 if (cam_dev != NULL)
9514 cam_close_device(cam_dev);