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>
63 #include <cam/mmc/mmc_all.h>
65 #include "camcontrol.h"
68 CAM_CMD_NONE = 0x00000000,
69 CAM_CMD_DEVLIST = 0x00000001,
70 CAM_CMD_TUR = 0x00000002,
71 CAM_CMD_INQUIRY = 0x00000003,
72 CAM_CMD_STARTSTOP = 0x00000004,
73 CAM_CMD_RESCAN = 0x00000005,
74 CAM_CMD_READ_DEFECTS = 0x00000006,
75 CAM_CMD_MODE_PAGE = 0x00000007,
76 CAM_CMD_SCSI_CMD = 0x00000008,
77 CAM_CMD_DEVTREE = 0x00000009,
78 CAM_CMD_USAGE = 0x0000000a,
79 CAM_CMD_DEBUG = 0x0000000b,
80 CAM_CMD_RESET = 0x0000000c,
81 CAM_CMD_FORMAT = 0x0000000d,
82 CAM_CMD_TAG = 0x0000000e,
83 CAM_CMD_RATE = 0x0000000f,
84 CAM_CMD_DETACH = 0x00000010,
85 CAM_CMD_REPORTLUNS = 0x00000011,
86 CAM_CMD_READCAP = 0x00000012,
87 CAM_CMD_IDENTIFY = 0x00000013,
88 CAM_CMD_IDLE = 0x00000014,
89 CAM_CMD_STANDBY = 0x00000015,
90 CAM_CMD_SLEEP = 0x00000016,
91 CAM_CMD_SMP_CMD = 0x00000017,
92 CAM_CMD_SMP_RG = 0x00000018,
93 CAM_CMD_SMP_PC = 0x00000019,
94 CAM_CMD_SMP_PHYLIST = 0x0000001a,
95 CAM_CMD_SMP_MANINFO = 0x0000001b,
96 CAM_CMD_DOWNLOAD_FW = 0x0000001c,
97 CAM_CMD_SECURITY = 0x0000001d,
98 CAM_CMD_HPA = 0x0000001e,
99 CAM_CMD_SANITIZE = 0x0000001f,
100 CAM_CMD_PERSIST = 0x00000020,
101 CAM_CMD_APM = 0x00000021,
102 CAM_CMD_AAM = 0x00000022,
103 CAM_CMD_ATTRIB = 0x00000023,
104 CAM_CMD_OPCODES = 0x00000024,
105 CAM_CMD_REPROBE = 0x00000025,
106 CAM_CMD_ZONE = 0x00000026,
107 CAM_CMD_EPC = 0x00000027,
108 CAM_CMD_TIMESTAMP = 0x00000028,
109 CAM_CMD_MMCSD_CMD = 0x00000029
113 CAM_ARG_NONE = 0x00000000,
114 CAM_ARG_VERBOSE = 0x00000001,
115 CAM_ARG_DEVICE = 0x00000002,
116 CAM_ARG_BUS = 0x00000004,
117 CAM_ARG_TARGET = 0x00000008,
118 CAM_ARG_LUN = 0x00000010,
119 CAM_ARG_EJECT = 0x00000020,
120 CAM_ARG_UNIT = 0x00000040,
121 CAM_ARG_FORMAT_BLOCK = 0x00000080,
122 CAM_ARG_FORMAT_BFI = 0x00000100,
123 CAM_ARG_FORMAT_PHYS = 0x00000200,
124 CAM_ARG_PLIST = 0x00000400,
125 CAM_ARG_GLIST = 0x00000800,
126 CAM_ARG_GET_SERIAL = 0x00001000,
127 CAM_ARG_GET_STDINQ = 0x00002000,
128 CAM_ARG_GET_XFERRATE = 0x00004000,
129 CAM_ARG_INQ_MASK = 0x00007000,
130 CAM_ARG_TIMEOUT = 0x00020000,
131 CAM_ARG_CMD_IN = 0x00040000,
132 CAM_ARG_CMD_OUT = 0x00080000,
133 CAM_ARG_ERR_RECOVER = 0x00200000,
134 CAM_ARG_RETRIES = 0x00400000,
135 CAM_ARG_START_UNIT = 0x00800000,
136 CAM_ARG_DEBUG_INFO = 0x01000000,
137 CAM_ARG_DEBUG_TRACE = 0x02000000,
138 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
139 CAM_ARG_DEBUG_CDB = 0x08000000,
140 CAM_ARG_DEBUG_XPT = 0x10000000,
141 CAM_ARG_DEBUG_PERIPH = 0x20000000,
142 CAM_ARG_DEBUG_PROBE = 0x40000000,
145 struct camcontrol_opts {
153 struct ata_res_pass16 {
154 u_int16_t reserved[5];
157 u_int8_t sector_count_exp;
158 u_int8_t sector_count;
159 u_int8_t lba_low_exp;
161 u_int8_t lba_mid_exp;
163 u_int8_t lba_high_exp;
169 struct ata_set_max_pwd
172 u_int8_t password[32];
173 u_int16_t reserved2[239];
176 static struct scsi_nv task_attrs[] = {
177 { "simple", MSG_SIMPLE_Q_TAG },
178 { "head", MSG_HEAD_OF_Q_TAG },
179 { "ordered", MSG_ORDERED_Q_TAG },
180 { "iwr", MSG_IGN_WIDE_RESIDUE },
181 { "aca", MSG_ACA_TASK }
184 static const char scsicmd_opts[] = "a:c:dfi:o:r";
185 static const char readdefect_opts[] = "f:GPqsS:X";
186 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
187 static const char smprg_opts[] = "l";
188 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
189 static const char smpphylist_opts[] = "lq";
193 static struct camcontrol_opts option_table[] = {
195 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
196 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
197 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
198 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
199 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
200 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
201 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
202 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
203 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
204 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
205 #endif /* MINIMALISTIC */
206 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
207 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
209 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
210 {"mmcsdcmd", CAM_CMD_MMCSD_CMD, CAM_ARG_NONE, "c:a:f:Wb:l:41S:I"},
211 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
212 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
213 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
214 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
215 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
216 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
217 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
218 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
219 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
220 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
221 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
222 #endif /* MINIMALISTIC */
223 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
225 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
226 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
227 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
228 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
229 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
230 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
231 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
232 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
233 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
234 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
235 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
236 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
237 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
238 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
239 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
240 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
241 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
242 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
243 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
244 {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
245 {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
246 {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
247 #endif /* MINIMALISTIC */
248 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
249 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
250 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
255 struct device_match_result dev_match;
257 struct periph_match_result *periph_matches;
258 struct scsi_vpd_device_id *device_id;
260 STAILQ_ENTRY(cam_devitem) links;
264 STAILQ_HEAD(, cam_devitem) dev_queue;
268 static cam_cmdmask cmdlist;
269 static cam_argmask arglist;
271 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
272 uint32_t *cmdnum, cam_argmask *argnum,
273 const char **subopt);
275 static int getdevlist(struct cam_device *device);
276 #endif /* MINIMALISTIC */
277 static int getdevtree(int argc, char **argv, char *combinedopt);
278 static int print_dev_scsi(struct device_match_result *dev_result, char *tmpstr);
279 static int print_dev_ata(struct device_match_result *dev_result, char *tmpstr);
280 static int print_dev_semb(struct device_match_result *dev_result, char *tmpstr);
281 static int print_dev_mmcsd(struct device_match_result *dev_result,
283 static int print_dev_nvme(struct device_match_result *dev_result, char *tmpstr);
285 static int testunitready(struct cam_device *device, int task_attr,
286 int retry_count, int timeout, int quiet);
287 static int scsistart(struct cam_device *device, int startstop, int loadeject,
288 int task_attr, int retry_count, int timeout);
289 static int scsiinquiry(struct cam_device *device, int task_attr,
290 int retry_count, int timeout);
291 static int scsiserial(struct cam_device *device, int task_attr,
292 int retry_count, int timeout);
293 #endif /* MINIMALISTIC */
294 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
295 lun_id_t *lun, cam_argmask *arglst);
296 static int dorescan_or_reset(int argc, char **argv, int rescan);
297 static int rescan_or_reset_bus(path_id_t bus, int rescan);
298 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
299 lun_id_t lun, int scan);
301 static int readdefects(struct cam_device *device, int argc, char **argv,
302 char *combinedopt, int task_attr, int retry_count,
304 static void modepage(struct cam_device *device, int argc, char **argv,
305 char *combinedopt, int task_attr, int retry_count,
307 static int scsicmd(struct cam_device *device, int argc, char **argv,
308 char *combinedopt, int task_attr, int retry_count,
310 static int smpcmd(struct cam_device *device, int argc, char **argv,
311 char *combinedopt, int retry_count, int timeout);
312 static int mmcsdcmd(struct cam_device *device, int argc, char **argv,
313 char *combinedopt, int retry_count, int timeout);
314 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
315 char *combinedopt, int retry_count, int timeout);
316 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
317 char *combinedopt, int retry_count, int timeout);
318 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
319 char *combinedopt, int retry_count, int timeout);
320 static int getdevid(struct cam_devitem *item);
321 static int buildbusdevlist(struct cam_devlist *devlist);
322 static void freebusdevlist(struct cam_devlist *devlist);
323 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
325 static int smpphylist(struct cam_device *device, int argc, char **argv,
326 char *combinedopt, int retry_count, int timeout);
327 static int tagcontrol(struct cam_device *device, int argc, char **argv,
329 static void cts_print(struct cam_device *device,
330 struct ccb_trans_settings *cts);
331 static void cpi_print(struct ccb_pathinq *cpi);
332 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
333 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
334 static int get_print_cts(struct cam_device *device, int user_settings,
335 int quiet, struct ccb_trans_settings *cts);
336 static int ratecontrol(struct cam_device *device, int task_attr,
337 int retry_count, int timeout, int argc, char **argv,
339 static int scsiformat(struct cam_device *device, int argc, char **argv,
340 char *combinedopt, int task_attr, int retry_count,
342 static int scsisanitize(struct cam_device *device, int argc, char **argv,
343 char *combinedopt, int task_attr, int retry_count,
345 static int scsireportluns(struct cam_device *device, int argc, char **argv,
346 char *combinedopt, int task_attr, int retry_count,
348 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
349 char *combinedopt, int task_attr, int retry_count,
351 static int atapm(struct cam_device *device, int argc, char **argv,
352 char *combinedopt, int retry_count, int timeout);
353 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
354 int argc, char **argv, char *combinedopt);
355 static int atahpa(struct cam_device *device, int retry_count, int timeout,
356 int argc, char **argv, char *combinedopt);
357 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
358 int sa_set, int req_sa, uint8_t *buf,
360 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
362 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
363 char *combinedopt, int task_attr, int retry_count,
364 int timeout, int verbose);
365 static int scsireprobe(struct cam_device *device);
367 #endif /* MINIMALISTIC */
369 #define min(a,b) (((a)<(b))?(a):(b))
372 #define max(a,b) (((a)>(b))?(a):(b))
376 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
377 cam_argmask *argnum, const char **subopt)
379 struct camcontrol_opts *opts;
382 for (opts = table; (opts != NULL) && (opts->optname != NULL);
384 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
385 *cmdnum = opts->cmdnum;
386 *argnum = opts->argnum;
387 *subopt = opts->subopt;
388 if (++num_matches > 1)
389 return (CC_OR_AMBIGUOUS);
394 return (CC_OR_FOUND);
396 return (CC_OR_NOT_FOUND);
401 getdevlist(struct cam_device *device)
407 ccb = cam_getccb(device);
409 ccb->ccb_h.func_code = XPT_GDEVLIST;
410 ccb->ccb_h.flags = CAM_DIR_NONE;
411 ccb->ccb_h.retry_count = 1;
413 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
414 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
415 if (cam_send_ccb(device, ccb) < 0) {
416 perror("error getting device list");
423 switch (ccb->cgdl.status) {
424 case CAM_GDEVLIST_MORE_DEVS:
425 strcpy(status, "MORE");
427 case CAM_GDEVLIST_LAST_DEVICE:
428 strcpy(status, "LAST");
430 case CAM_GDEVLIST_LIST_CHANGED:
431 strcpy(status, "CHANGED");
433 case CAM_GDEVLIST_ERROR:
434 strcpy(status, "ERROR");
439 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
440 ccb->cgdl.periph_name,
441 ccb->cgdl.unit_number,
442 ccb->cgdl.generation,
447 * If the list has changed, we need to start over from the
450 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
458 #endif /* MINIMALISTIC */
461 getdevtree(int argc, char **argv, char *combinedopt)
472 while ((c = getopt(argc, argv, combinedopt)) != -1) {
475 if ((arglist & CAM_ARG_VERBOSE) == 0)
483 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
484 warn("couldn't open %s", XPT_DEVICE);
488 bzero(&ccb, sizeof(union ccb));
490 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
491 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
492 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
494 ccb.ccb_h.func_code = XPT_DEV_MATCH;
495 bufsize = sizeof(struct dev_match_result) * 100;
496 ccb.cdm.match_buf_len = bufsize;
497 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
498 if (ccb.cdm.matches == NULL) {
499 warnx("can't malloc memory for matches");
503 ccb.cdm.num_matches = 0;
506 * We fetch all nodes, since we display most of them in the default
507 * case, and all in the verbose case.
509 ccb.cdm.num_patterns = 0;
510 ccb.cdm.pattern_buf_len = 0;
513 * We do the ioctl multiple times if necessary, in case there are
514 * more than 100 nodes in the EDT.
517 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
518 warn("error sending CAMIOCOMMAND ioctl");
523 if ((ccb.ccb_h.status != CAM_REQ_CMP)
524 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
525 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
526 warnx("got CAM error %#x, CDM error %d\n",
527 ccb.ccb_h.status, ccb.cdm.status);
532 for (i = 0; i < ccb.cdm.num_matches; i++) {
533 switch (ccb.cdm.matches[i].type) {
534 case DEV_MATCH_BUS: {
535 struct bus_match_result *bus_result;
538 * Only print the bus information if the
539 * user turns on the verbose flag.
541 if ((busonly == 0) &&
542 (arglist & CAM_ARG_VERBOSE) == 0)
546 &ccb.cdm.matches[i].result.bus_result;
549 fprintf(stdout, ")\n");
553 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
555 bus_result->dev_name,
556 bus_result->unit_number,
558 (busonly ? "" : ":"));
561 case DEV_MATCH_DEVICE: {
562 struct device_match_result *dev_result;
569 &ccb.cdm.matches[i].result.device_result;
571 if ((dev_result->flags
572 & DEV_RESULT_UNCONFIGURED)
573 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
579 if (dev_result->protocol == PROTO_SCSI) {
580 if (print_dev_scsi(dev_result,
585 } else if (dev_result->protocol == PROTO_ATA ||
586 dev_result->protocol == PROTO_SATAPM) {
587 if (print_dev_ata(dev_result,
592 } else if (dev_result->protocol == PROTO_MMCSD){
593 if (print_dev_mmcsd(dev_result,
598 } else if (dev_result->protocol == PROTO_SEMB) {
599 if (print_dev_semb(dev_result,
604 } else if (dev_result->protocol == PROTO_NVME) {
605 if (print_dev_nvme(dev_result,
611 sprintf(tmpstr, "<>");
614 fprintf(stdout, ")\n");
618 fprintf(stdout, "%-33s at scbus%d "
619 "target %d lun %jx (",
622 dev_result->target_id,
623 (uintmax_t)dev_result->target_lun);
629 case DEV_MATCH_PERIPH: {
630 struct periph_match_result *periph_result;
633 &ccb.cdm.matches[i].result.periph_result;
635 if (busonly || skip_device != 0)
639 fprintf(stdout, ",");
641 fprintf(stdout, "%s%d",
642 periph_result->periph_name,
643 periph_result->unit_number);
649 fprintf(stdout, "unknown match type\n");
654 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
655 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
658 fprintf(stdout, ")\n");
666 print_dev_scsi(struct device_match_result *dev_result, char *tmpstr)
668 char vendor[16], product[48], revision[16];
670 cam_strvis(vendor, dev_result->inq_data.vendor,
671 sizeof(dev_result->inq_data.vendor), sizeof(vendor));
672 cam_strvis(product, dev_result->inq_data.product,
673 sizeof(dev_result->inq_data.product), sizeof(product));
674 cam_strvis(revision, dev_result->inq_data.revision,
675 sizeof(dev_result->inq_data.revision), sizeof(revision));
676 sprintf(tmpstr, "<%s %s %s>", vendor, product, revision);
682 print_dev_ata(struct device_match_result *dev_result, char *tmpstr)
684 char product[48], revision[16];
686 cam_strvis(product, dev_result->ident_data.model,
687 sizeof(dev_result->ident_data.model), sizeof(product));
688 cam_strvis(revision, dev_result->ident_data.revision,
689 sizeof(dev_result->ident_data.revision), sizeof(revision));
690 sprintf(tmpstr, "<%s %s>", product, revision);
696 print_dev_semb(struct device_match_result *dev_result, char *tmpstr)
698 struct sep_identify_data *sid;
699 char vendor[16], product[48], revision[16], fw[5];
701 sid = (struct sep_identify_data *)&dev_result->ident_data;
702 cam_strvis(vendor, sid->vendor_id,
703 sizeof(sid->vendor_id), sizeof(vendor));
704 cam_strvis(product, sid->product_id,
705 sizeof(sid->product_id), sizeof(product));
706 cam_strvis(revision, sid->product_rev,
707 sizeof(sid->product_rev), sizeof(revision));
708 cam_strvis(fw, sid->firmware_rev,
709 sizeof(sid->firmware_rev), sizeof(fw));
710 sprintf(tmpstr, "<%s %s %s %s>", vendor, product, revision, fw);
716 print_dev_mmcsd(struct device_match_result *dev_result, char *tmpstr)
719 struct ccb_dev_advinfo *advi;
720 struct cam_device *dev;
721 struct mmc_params mmc_ident_data;
723 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
724 dev_result->target_lun, O_RDWR, NULL);
726 warnx("%s", cam_errbuf);
730 ccb = cam_getccb(dev);
732 warnx("couldn't allocate CCB");
733 cam_close_device(dev);
738 advi->ccb_h.flags = CAM_DIR_IN;
739 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
740 advi->flags = CDAI_FLAG_NONE;
741 advi->buftype = CDAI_TYPE_MMC_PARAMS;
742 advi->bufsiz = sizeof(struct mmc_params);
743 advi->buf = (uint8_t *)&mmc_ident_data;
745 if (cam_send_ccb(dev, ccb) < 0) {
746 warn("error sending CAMIOCOMMAND ioctl");
748 cam_close_device(dev);
752 if (strlen(mmc_ident_data.model) > 0) {
753 sprintf(tmpstr, "<%s>", mmc_ident_data.model);
755 sprintf(tmpstr, "<%s card>",
756 mmc_ident_data.card_features &
757 CARD_FEATURE_SDIO ? "SDIO" : "unknown");
761 cam_close_device(dev);
766 print_dev_nvme(struct device_match_result *dev_result, char *tmpstr)
769 struct ccb_dev_advinfo *advi;
770 struct cam_device *dev;
771 struct nvme_controller_data cdata;
772 char vendor[64], product[64];
774 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
775 dev_result->target_lun, O_RDWR, NULL);
777 warnx("%s", cam_errbuf);
781 ccb = cam_getccb(dev);
783 warnx("couldn't allocate CCB");
784 cam_close_device(dev);
789 advi->ccb_h.flags = CAM_DIR_IN;
790 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
791 advi->flags = CDAI_FLAG_NONE;
792 advi->buftype = CDAI_TYPE_NVME_CNTRL;
793 advi->bufsiz = sizeof(struct nvme_controller_data);
794 advi->buf = (uint8_t *)&cdata;
796 if (cam_send_ccb(dev, ccb) < 0) {
797 warn("error sending CAMIOCOMMAND ioctl");
799 cam_close_device(dev);
802 if (advi->ccb_h.status != CAM_REQ_CMP) {
803 warnx("got CAM error %#x", advi->ccb_h.status);
805 cam_close_device(dev);
808 cam_strvis(vendor, cdata.mn, sizeof(cdata.mn), sizeof(vendor));
809 cam_strvis(product, cdata.fr, sizeof(cdata.fr), sizeof(product));
810 sprintf(tmpstr, "<%s %s>", vendor, product);
813 cam_close_device(dev);
819 testunitready(struct cam_device *device, int task_attr, int retry_count,
820 int timeout, int quiet)
825 ccb = cam_getccb(device);
827 scsi_test_unit_ready(&ccb->csio,
828 /* retries */ retry_count,
830 /* tag_action */ task_attr,
831 /* sense_len */ SSD_FULL_SIZE,
832 /* timeout */ timeout ? timeout : 5000);
834 /* Disable freezing the device queue */
835 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
837 if (arglist & CAM_ARG_ERR_RECOVER)
838 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
840 if (cam_send_ccb(device, ccb) < 0) {
842 perror("error sending test unit ready");
844 if (arglist & CAM_ARG_VERBOSE) {
845 cam_error_print(device, ccb, CAM_ESF_ALL,
846 CAM_EPF_ALL, stderr);
853 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
855 fprintf(stdout, "Unit is ready\n");
858 fprintf(stdout, "Unit is not ready\n");
861 if (arglist & CAM_ARG_VERBOSE) {
862 cam_error_print(device, ccb, CAM_ESF_ALL,
863 CAM_EPF_ALL, stderr);
873 scsistart(struct cam_device *device, int startstop, int loadeject,
874 int task_attr, int retry_count, int timeout)
879 ccb = cam_getccb(device);
882 * If we're stopping, send an ordered tag so the drive in question
883 * will finish any previously queued writes before stopping. If
884 * the device isn't capable of tagged queueing, or if tagged
885 * queueing is turned off, the tag action is a no-op. We override
886 * the default simple tag, although this also has the effect of
887 * overriding the user's wishes if he wanted to specify a simple
891 && (task_attr == MSG_SIMPLE_Q_TAG))
892 task_attr = MSG_ORDERED_Q_TAG;
894 scsi_start_stop(&ccb->csio,
895 /* retries */ retry_count,
897 /* tag_action */ task_attr,
898 /* start/stop */ startstop,
899 /* load_eject */ loadeject,
901 /* sense_len */ SSD_FULL_SIZE,
902 /* timeout */ timeout ? timeout : 120000);
904 /* Disable freezing the device queue */
905 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
907 if (arglist & CAM_ARG_ERR_RECOVER)
908 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
910 if (cam_send_ccb(device, ccb) < 0) {
911 perror("error sending start unit");
913 if (arglist & CAM_ARG_VERBOSE) {
914 cam_error_print(device, ccb, CAM_ESF_ALL,
915 CAM_EPF_ALL, stderr);
922 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
924 fprintf(stdout, "Unit started successfully");
926 fprintf(stdout,", Media loaded\n");
928 fprintf(stdout,"\n");
930 fprintf(stdout, "Unit stopped successfully");
932 fprintf(stdout, ", Media ejected\n");
934 fprintf(stdout, "\n");
940 "Error received from start unit command\n");
943 "Error received from stop unit command\n");
945 if (arglist & CAM_ARG_VERBOSE) {
946 cam_error_print(device, ccb, CAM_ESF_ALL,
947 CAM_EPF_ALL, stderr);
957 scsidoinquiry(struct cam_device *device, int argc, char **argv,
958 char *combinedopt, int task_attr, int retry_count, int timeout)
963 while ((c = getopt(argc, argv, combinedopt)) != -1) {
966 arglist |= CAM_ARG_GET_STDINQ;
969 arglist |= CAM_ARG_GET_XFERRATE;
972 arglist |= CAM_ARG_GET_SERIAL;
980 * If the user didn't specify any inquiry options, he wants all of
983 if ((arglist & CAM_ARG_INQ_MASK) == 0)
984 arglist |= CAM_ARG_INQ_MASK;
986 if (arglist & CAM_ARG_GET_STDINQ)
987 error = scsiinquiry(device, task_attr, retry_count, timeout);
992 if (arglist & CAM_ARG_GET_SERIAL)
993 scsiserial(device, task_attr, retry_count, timeout);
995 if (arglist & CAM_ARG_GET_XFERRATE)
996 error = camxferrate(device);
1002 scsiinquiry(struct cam_device *device, int task_attr, int retry_count,
1006 struct scsi_inquiry_data *inq_buf;
1009 ccb = cam_getccb(device);
1012 warnx("couldn't allocate CCB");
1016 /* cam_getccb cleans up the header, caller has to zero the payload */
1017 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1019 inq_buf = (struct scsi_inquiry_data *)malloc(
1020 sizeof(struct scsi_inquiry_data));
1022 if (inq_buf == NULL) {
1024 warnx("can't malloc memory for inquiry\n");
1027 bzero(inq_buf, sizeof(*inq_buf));
1030 * Note that although the size of the inquiry buffer is the full
1031 * 256 bytes specified in the SCSI spec, we only tell the device
1032 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
1033 * two reasons for this:
1035 * - The SCSI spec says that when a length field is only 1 byte,
1036 * a value of 0 will be interpreted as 256. Therefore
1037 * scsi_inquiry() will convert an inq_len (which is passed in as
1038 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
1039 * to 0. Evidently, very few devices meet the spec in that
1040 * regard. Some devices, like many Seagate disks, take the 0 as
1041 * 0, and don't return any data. One Pioneer DVD-R drive
1042 * returns more data than the command asked for.
1044 * So, since there are numerous devices that just don't work
1045 * right with the full inquiry size, we don't send the full size.
1047 * - The second reason not to use the full inquiry data length is
1048 * that we don't need it here. The only reason we issue a
1049 * standard inquiry is to get the vendor name, device name,
1050 * and revision so scsi_print_inquiry() can print them.
1052 * If, at some point in the future, more inquiry data is needed for
1053 * some reason, this code should use a procedure similar to the
1054 * probe code. i.e., issue a short inquiry, and determine from
1055 * the additional length passed back from the device how much
1056 * inquiry data the device supports. Once the amount the device
1057 * supports is determined, issue an inquiry for that amount and no
1062 scsi_inquiry(&ccb->csio,
1063 /* retries */ retry_count,
1065 /* tag_action */ task_attr,
1066 /* inq_buf */ (u_int8_t *)inq_buf,
1067 /* inq_len */ SHORT_INQUIRY_LENGTH,
1070 /* sense_len */ SSD_FULL_SIZE,
1071 /* timeout */ timeout ? timeout : 5000);
1073 /* Disable freezing the device queue */
1074 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1076 if (arglist & CAM_ARG_ERR_RECOVER)
1077 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1079 if (cam_send_ccb(device, ccb) < 0) {
1080 perror("error sending SCSI inquiry");
1082 if (arglist & CAM_ARG_VERBOSE) {
1083 cam_error_print(device, ccb, CAM_ESF_ALL,
1084 CAM_EPF_ALL, stderr);
1091 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1094 if (arglist & CAM_ARG_VERBOSE) {
1095 cam_error_print(device, ccb, CAM_ESF_ALL,
1096 CAM_EPF_ALL, stderr);
1107 fprintf(stdout, "%s%d: ", device->device_name,
1108 device->dev_unit_num);
1109 scsi_print_inquiry(inq_buf);
1117 scsiserial(struct cam_device *device, int task_attr, int retry_count,
1121 struct scsi_vpd_unit_serial_number *serial_buf;
1122 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
1125 ccb = cam_getccb(device);
1128 warnx("couldn't allocate CCB");
1132 /* cam_getccb cleans up the header, caller has to zero the payload */
1133 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1135 serial_buf = (struct scsi_vpd_unit_serial_number *)
1136 malloc(sizeof(*serial_buf));
1138 if (serial_buf == NULL) {
1140 warnx("can't malloc memory for serial number");
1144 scsi_inquiry(&ccb->csio,
1145 /*retries*/ retry_count,
1147 /* tag_action */ task_attr,
1148 /* inq_buf */ (u_int8_t *)serial_buf,
1149 /* inq_len */ sizeof(*serial_buf),
1151 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
1152 /* sense_len */ SSD_FULL_SIZE,
1153 /* timeout */ timeout ? timeout : 5000);
1155 /* Disable freezing the device queue */
1156 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1158 if (arglist & CAM_ARG_ERR_RECOVER)
1159 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1161 if (cam_send_ccb(device, ccb) < 0) {
1162 warn("error getting serial number");
1164 if (arglist & CAM_ARG_VERBOSE) {
1165 cam_error_print(device, ccb, CAM_ESF_ALL,
1166 CAM_EPF_ALL, stderr);
1174 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1177 if (arglist & CAM_ARG_VERBOSE) {
1178 cam_error_print(device, ccb, CAM_ESF_ALL,
1179 CAM_EPF_ALL, stderr);
1190 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1191 serial_num[serial_buf->length] = '\0';
1193 if ((arglist & CAM_ARG_GET_STDINQ)
1194 || (arglist & CAM_ARG_GET_XFERRATE))
1195 fprintf(stdout, "%s%d: Serial Number ",
1196 device->device_name, device->dev_unit_num);
1198 fprintf(stdout, "%.60s\n", serial_num);
1206 camxferrate(struct cam_device *device)
1208 struct ccb_pathinq cpi;
1210 u_int32_t speed = 0;
1215 if ((retval = get_cpi(device, &cpi)) != 0)
1218 ccb = cam_getccb(device);
1221 warnx("couldn't allocate CCB");
1225 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
1227 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1228 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1230 if (((retval = cam_send_ccb(device, ccb)) < 0)
1231 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1232 const char error_string[] = "error getting transfer settings";
1237 warnx(error_string);
1239 if (arglist & CAM_ARG_VERBOSE)
1240 cam_error_print(device, ccb, CAM_ESF_ALL,
1241 CAM_EPF_ALL, stderr);
1245 goto xferrate_bailout;
1249 speed = cpi.base_transfer_speed;
1251 if (ccb->cts.transport == XPORT_SPI) {
1252 struct ccb_trans_settings_spi *spi =
1253 &ccb->cts.xport_specific.spi;
1255 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1256 freq = scsi_calc_syncsrate(spi->sync_period);
1259 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1260 speed *= (0x01 << spi->bus_width);
1262 } else if (ccb->cts.transport == XPORT_FC) {
1263 struct ccb_trans_settings_fc *fc =
1264 &ccb->cts.xport_specific.fc;
1266 if (fc->valid & CTS_FC_VALID_SPEED)
1267 speed = fc->bitrate;
1268 } else if (ccb->cts.transport == XPORT_SAS) {
1269 struct ccb_trans_settings_sas *sas =
1270 &ccb->cts.xport_specific.sas;
1272 if (sas->valid & CTS_SAS_VALID_SPEED)
1273 speed = sas->bitrate;
1274 } else if (ccb->cts.transport == XPORT_ATA) {
1275 struct ccb_trans_settings_pata *pata =
1276 &ccb->cts.xport_specific.ata;
1278 if (pata->valid & CTS_ATA_VALID_MODE)
1279 speed = ata_mode2speed(pata->mode);
1280 } else if (ccb->cts.transport == XPORT_SATA) {
1281 struct ccb_trans_settings_sata *sata =
1282 &ccb->cts.xport_specific.sata;
1284 if (sata->valid & CTS_SATA_VALID_REVISION)
1285 speed = ata_revision2speed(sata->revision);
1290 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1291 device->device_name, device->dev_unit_num,
1294 fprintf(stdout, "%s%d: %dKB/s transfers",
1295 device->device_name, device->dev_unit_num,
1299 if (ccb->cts.transport == XPORT_SPI) {
1300 struct ccb_trans_settings_spi *spi =
1301 &ccb->cts.xport_specific.spi;
1303 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1304 && (spi->sync_offset != 0))
1305 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1306 freq % 1000, spi->sync_offset);
1308 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1309 && (spi->bus_width > 0)) {
1310 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1311 && (spi->sync_offset != 0)) {
1312 fprintf(stdout, ", ");
1314 fprintf(stdout, " (");
1316 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1317 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1318 && (spi->sync_offset != 0)) {
1319 fprintf(stdout, ")");
1321 } else if (ccb->cts.transport == XPORT_ATA) {
1322 struct ccb_trans_settings_pata *pata =
1323 &ccb->cts.xport_specific.ata;
1326 if (pata->valid & CTS_ATA_VALID_MODE)
1327 printf("%s, ", ata_mode2string(pata->mode));
1328 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1329 printf("ATAPI %dbytes, ", pata->atapi);
1330 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1331 printf("PIO %dbytes", pata->bytecount);
1333 } else if (ccb->cts.transport == XPORT_SATA) {
1334 struct ccb_trans_settings_sata *sata =
1335 &ccb->cts.xport_specific.sata;
1338 if (sata->valid & CTS_SATA_VALID_REVISION)
1339 printf("SATA %d.x, ", sata->revision);
1342 if (sata->valid & CTS_SATA_VALID_MODE)
1343 printf("%s, ", ata_mode2string(sata->mode));
1344 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1345 printf("ATAPI %dbytes, ", sata->atapi);
1346 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1347 printf("PIO %dbytes", sata->bytecount);
1351 if (ccb->cts.protocol == PROTO_SCSI) {
1352 struct ccb_trans_settings_scsi *scsi =
1353 &ccb->cts.proto_specific.scsi;
1354 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1355 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1356 fprintf(stdout, ", Command Queueing Enabled");
1361 fprintf(stdout, "\n");
1371 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1373 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1374 ((u_int32_t)parm->lba_size_2 << 16);
1376 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1377 ((u_int64_t)parm->lba_size48_2 << 16) |
1378 ((u_int64_t)parm->lba_size48_3 << 32) |
1379 ((u_int64_t)parm->lba_size48_4 << 48);
1383 "Support Enabled Value\n");
1386 printf("Host Protected Area (HPA) ");
1387 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1388 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1389 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1392 printf("HPA - Security ");
1393 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1403 atasata(struct ata_params *parm)
1407 if (parm->satacapabilities != 0xffff &&
1408 parm->satacapabilities != 0x0000)
1415 atacapprint(struct ata_params *parm)
1417 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1418 ((u_int32_t)parm->lba_size_2 << 16);
1420 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1421 ((u_int64_t)parm->lba_size48_2 << 16) |
1422 ((u_int64_t)parm->lba_size48_3 << 32) |
1423 ((u_int64_t)parm->lba_size48_4 << 48);
1426 printf("protocol ");
1427 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1428 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1429 if (parm->satacapabilities & ATA_SATA_GEN3)
1430 printf(" SATA 3.x\n");
1431 else if (parm->satacapabilities & ATA_SATA_GEN2)
1432 printf(" SATA 2.x\n");
1433 else if (parm->satacapabilities & ATA_SATA_GEN1)
1434 printf(" SATA 1.x\n");
1440 printf("device model %.40s\n", parm->model);
1441 printf("firmware revision %.8s\n", parm->revision);
1442 printf("serial number %.20s\n", parm->serial);
1443 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1444 printf("WWN %04x%04x%04x%04x\n",
1445 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1447 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1448 printf("media serial number %.30s\n",
1449 parm->media_serial);
1452 printf("cylinders %d\n", parm->cylinders);
1453 printf("heads %d\n", parm->heads);
1454 printf("sectors/track %d\n", parm->sectors);
1455 printf("sector size logical %u, physical %lu, offset %lu\n",
1456 ata_logical_sector_size(parm),
1457 (unsigned long)ata_physical_sector_size(parm),
1458 (unsigned long)ata_logical_sector_offset(parm));
1460 if (parm->config == ATA_PROTO_CFA ||
1461 (parm->support.command2 & ATA_SUPPORT_CFA))
1462 printf("CFA supported\n");
1464 printf("LBA%ssupported ",
1465 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1467 printf("%d sectors\n", lbasize);
1471 printf("LBA48%ssupported ",
1472 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1474 printf("%ju sectors\n", (uintmax_t)lbasize48);
1478 printf("PIO supported PIO");
1479 switch (ata_max_pmode(parm)) {
1495 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1496 printf(" w/o IORDY");
1499 printf("DMA%ssupported ",
1500 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1501 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1502 if (parm->mwdmamodes & 0xff) {
1504 if (parm->mwdmamodes & 0x04)
1506 else if (parm->mwdmamodes & 0x02)
1508 else if (parm->mwdmamodes & 0x01)
1512 if ((parm->atavalid & ATA_FLAG_88) &&
1513 (parm->udmamodes & 0xff)) {
1515 if (parm->udmamodes & 0x40)
1517 else if (parm->udmamodes & 0x20)
1519 else if (parm->udmamodes & 0x10)
1521 else if (parm->udmamodes & 0x08)
1523 else if (parm->udmamodes & 0x04)
1525 else if (parm->udmamodes & 0x02)
1527 else if (parm->udmamodes & 0x01)
1534 if (parm->media_rotation_rate == 1) {
1535 printf("media RPM non-rotating\n");
1536 } else if (parm->media_rotation_rate >= 0x0401 &&
1537 parm->media_rotation_rate <= 0xFFFE) {
1538 printf("media RPM %d\n",
1539 parm->media_rotation_rate);
1542 printf("Zoned-Device Commands ");
1543 switch (parm->support3 & ATA_SUPPORT_ZONE_MASK) {
1544 case ATA_SUPPORT_ZONE_DEV_MANAGED:
1545 printf("device managed\n");
1547 case ATA_SUPPORT_ZONE_HOST_AWARE:
1548 printf("host aware\n");
1555 "Support Enabled Value Vendor\n");
1556 printf("read ahead %s %s\n",
1557 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1558 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1559 printf("write cache %s %s\n",
1560 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1561 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1562 printf("flush cache %s %s\n",
1563 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1564 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1565 printf("overlap %s\n",
1566 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1567 printf("Tagged Command Queuing (TCQ) %s %s",
1568 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1569 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1570 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1571 printf(" %d tags\n",
1572 ATA_QUEUE_LEN(parm->queue) + 1);
1575 printf("Native Command Queuing (NCQ) ");
1576 if (parm->satacapabilities != 0xffff &&
1577 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1578 printf("yes %d tags\n",
1579 ATA_QUEUE_LEN(parm->queue) + 1);
1583 printf("NCQ Queue Management %s\n", atasata(parm) &&
1584 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1586 printf("NCQ Streaming %s\n", atasata(parm) &&
1587 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1589 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1590 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1593 printf("SMART %s %s\n",
1594 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1595 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1596 printf("microcode download %s %s\n",
1597 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1598 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1599 printf("security %s %s\n",
1600 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1601 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1602 printf("power management %s %s\n",
1603 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1604 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1605 printf("advanced power management %s %s",
1606 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1607 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1608 if (parm->support.command2 & ATA_SUPPORT_APM) {
1609 printf(" %d/0x%02X\n",
1610 parm->apm_value & 0xff, parm->apm_value & 0xff);
1613 printf("automatic acoustic management %s %s",
1614 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1615 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1616 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1617 printf(" %d/0x%02X %d/0x%02X\n",
1618 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1619 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1620 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1621 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1624 printf("media status notification %s %s\n",
1625 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1626 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1627 printf("power-up in Standby %s %s\n",
1628 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1629 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1630 printf("write-read-verify %s %s",
1631 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1632 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1633 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1634 printf(" %d/0x%x\n",
1635 parm->wrv_mode, parm->wrv_mode);
1638 printf("unload %s %s\n",
1639 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1640 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1641 printf("general purpose logging %s %s\n",
1642 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1643 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1644 printf("free-fall %s %s\n",
1645 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1646 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1647 printf("Data Set Management (DSM/TRIM) ");
1648 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1650 printf("DSM - max 512byte blocks ");
1651 if (parm->max_dsm_blocks == 0x00)
1652 printf("yes not specified\n");
1655 parm->max_dsm_blocks);
1657 printf("DSM - deterministic read ");
1658 if (parm->support3 & ATA_SUPPORT_DRAT) {
1659 if (parm->support3 & ATA_SUPPORT_RZAT)
1660 printf("yes zeroed\n");
1662 printf("yes any value\n");
1672 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1674 struct ata_pass_16 *ata_pass_16;
1675 struct ata_cmd ata_cmd;
1677 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1678 ata_cmd.command = ata_pass_16->command;
1679 ata_cmd.control = ata_pass_16->control;
1680 ata_cmd.features = ata_pass_16->features;
1682 if (arglist & CAM_ARG_VERBOSE) {
1683 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1684 ata_op_string(&ata_cmd),
1685 ccb->csio.ccb_h.timeout);
1688 /* Disable freezing the device queue */
1689 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1691 if (arglist & CAM_ARG_ERR_RECOVER)
1692 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1694 if (cam_send_ccb(device, ccb) < 0) {
1695 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1696 warn("error sending ATA %s via pass_16",
1697 ata_op_string(&ata_cmd));
1700 if (arglist & CAM_ARG_VERBOSE) {
1701 cam_error_print(device, ccb, CAM_ESF_ALL,
1702 CAM_EPF_ALL, stderr);
1708 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1709 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1710 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1711 warnx("ATA %s via pass_16 failed",
1712 ata_op_string(&ata_cmd));
1714 if (arglist & CAM_ARG_VERBOSE) {
1715 cam_error_print(device, ccb, CAM_ESF_ALL,
1716 CAM_EPF_ALL, stderr);
1727 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1729 if (arglist & CAM_ARG_VERBOSE) {
1730 warnx("sending ATA %s with timeout of %u msecs",
1731 ata_op_string(&(ccb->ataio.cmd)),
1732 ccb->ataio.ccb_h.timeout);
1735 /* Disable freezing the device queue */
1736 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1738 if (arglist & CAM_ARG_ERR_RECOVER)
1739 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1741 if (cam_send_ccb(device, ccb) < 0) {
1742 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1743 warn("error sending ATA %s",
1744 ata_op_string(&(ccb->ataio.cmd)));
1747 if (arglist & CAM_ARG_VERBOSE) {
1748 cam_error_print(device, ccb, CAM_ESF_ALL,
1749 CAM_EPF_ALL, stderr);
1755 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1756 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1757 warnx("ATA %s failed: %d",
1758 ata_op_string(&(ccb->ataio.cmd)), quiet);
1761 if (arglist & CAM_ARG_VERBOSE) {
1762 cam_error_print(device, ccb, CAM_ESF_ALL,
1763 CAM_EPF_ALL, stderr);
1773 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1774 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1775 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1776 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1777 u_int16_t dxfer_len, int timeout, int quiet)
1779 if (data_ptr != NULL) {
1780 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1781 AP_FLAG_TLEN_SECT_CNT;
1782 if (flags & CAM_DIR_OUT)
1783 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1785 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1787 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1790 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1792 scsi_ata_pass_16(&ccb->csio,
1806 /*sense_len*/SSD_FULL_SIZE,
1809 return scsi_cam_pass_16_send(device, ccb, quiet);
1813 ata_try_pass_16(struct cam_device *device)
1815 struct ccb_pathinq cpi;
1817 if (get_cpi(device, &cpi) != 0) {
1818 warnx("couldn't get CPI");
1822 if (cpi.protocol == PROTO_SCSI) {
1823 /* possibly compatible with pass_16 */
1827 /* likely not compatible with pass_16 */
1832 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1833 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1834 u_int8_t command, u_int8_t features, u_int32_t lba,
1835 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1836 int timeout, int quiet)
1840 switch (ata_try_pass_16(device)) {
1844 /* Try using SCSI Passthrough */
1845 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1846 0, tag_action, command, features, lba,
1847 sector_count, data_ptr, dxfer_len,
1851 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1852 cam_fill_ataio(&ccb->ataio,
1861 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1862 return ata_cam_send(device, ccb, quiet);
1866 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1867 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1868 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1869 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1870 u_int16_t dxfer_len, int timeout, int force48bit)
1874 retval = ata_try_pass_16(device);
1881 /* Try using SCSI Passthrough */
1882 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1883 ata_flags, tag_action, command, features,
1884 lba, sector_count, data_ptr, dxfer_len,
1887 if (ata_flags & AP_FLAG_CHK_COND) {
1888 /* Decode ata_res from sense data */
1889 struct ata_res_pass16 *res_pass16;
1890 struct ata_res *res;
1894 /* sense_data is 4 byte aligned */
1895 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1896 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1897 ptr[i] = le16toh(ptr[i]);
1899 /* sense_data is 4 byte aligned */
1900 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1901 &ccb->csio.sense_data;
1902 res = &ccb->ataio.res;
1903 res->flags = res_pass16->flags;
1904 res->status = res_pass16->status;
1905 res->error = res_pass16->error;
1906 res->lba_low = res_pass16->lba_low;
1907 res->lba_mid = res_pass16->lba_mid;
1908 res->lba_high = res_pass16->lba_high;
1909 res->device = res_pass16->device;
1910 res->lba_low_exp = res_pass16->lba_low_exp;
1911 res->lba_mid_exp = res_pass16->lba_mid_exp;
1912 res->lba_high_exp = res_pass16->lba_high_exp;
1913 res->sector_count = res_pass16->sector_count;
1914 res->sector_count_exp = res_pass16->sector_count_exp;
1920 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1921 cam_fill_ataio(&ccb->ataio,
1930 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1931 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1933 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1935 if (ata_flags & AP_FLAG_CHK_COND)
1936 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1938 return ata_cam_send(device, ccb, 0);
1942 dump_data(uint16_t *ptr, uint32_t len)
1946 for (i = 0; i < len / 2; i++) {
1948 printf(" %3d: ", i);
1949 printf("%04hx ", ptr[i]);
1958 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1959 int is48bit, u_int64_t *hpasize)
1961 struct ata_res *res;
1963 res = &ccb->ataio.res;
1964 if (res->status & ATA_STATUS_ERROR) {
1965 if (arglist & CAM_ARG_VERBOSE) {
1966 cam_error_print(device, ccb, CAM_ESF_ALL,
1967 CAM_EPF_ALL, stderr);
1968 printf("error = 0x%02x, sector_count = 0x%04x, "
1969 "device = 0x%02x, status = 0x%02x\n",
1970 res->error, res->sector_count,
1971 res->device, res->status);
1974 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1975 warnx("Max address has already been set since "
1976 "last power-on or hardware reset");
1982 if (arglist & CAM_ARG_VERBOSE) {
1983 fprintf(stdout, "%s%d: Raw native max data:\n",
1984 device->device_name, device->dev_unit_num);
1985 /* res is 4 byte aligned */
1986 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1988 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1989 "status = 0x%02x\n", res->error, res->sector_count,
1990 res->device, res->status);
1993 if (hpasize != NULL) {
1995 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1996 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1997 ((res->lba_high << 16) | (res->lba_mid << 8) |
2000 *hpasize = (((res->device & 0x0f) << 24) |
2001 (res->lba_high << 16) | (res->lba_mid << 8) |
2010 ata_read_native_max(struct cam_device *device, int retry_count,
2011 u_int32_t timeout, union ccb *ccb,
2012 struct ata_params *parm, u_int64_t *hpasize)
2018 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
2019 protocol = AP_PROTO_NON_DATA;
2022 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
2023 protocol |= AP_EXTEND;
2025 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
2028 error = ata_do_cmd(device,
2031 /*flags*/CAM_DIR_NONE,
2032 /*protocol*/protocol,
2033 /*ata_flags*/AP_FLAG_CHK_COND,
2034 /*tag_action*/MSG_SIMPLE_Q_TAG,
2041 timeout ? timeout : 1000,
2047 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
2051 atahpa_set_max(struct cam_device *device, int retry_count,
2052 u_int32_t timeout, union ccb *ccb,
2053 int is48bit, u_int64_t maxsize, int persist)
2059 protocol = AP_PROTO_NON_DATA;
2062 cmd = ATA_SET_MAX_ADDRESS48;
2063 protocol |= AP_EXTEND;
2065 cmd = ATA_SET_MAX_ADDRESS;
2068 /* lba's are zero indexed so the max lba is requested max - 1 */
2072 error = ata_do_cmd(device,
2075 /*flags*/CAM_DIR_NONE,
2076 /*protocol*/protocol,
2077 /*ata_flags*/AP_FLAG_CHK_COND,
2078 /*tag_action*/MSG_SIMPLE_Q_TAG,
2080 /*features*/ATA_HPA_FEAT_MAX_ADDR,
2082 /*sector_count*/persist,
2085 timeout ? timeout : 1000,
2091 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2095 atahpa_password(struct cam_device *device, int retry_count,
2096 u_int32_t timeout, union ccb *ccb,
2097 int is48bit, struct ata_set_max_pwd *pwd)
2103 protocol = AP_PROTO_PIO_OUT;
2104 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2106 error = ata_do_cmd(device,
2109 /*flags*/CAM_DIR_OUT,
2110 /*protocol*/protocol,
2111 /*ata_flags*/AP_FLAG_CHK_COND,
2112 /*tag_action*/MSG_SIMPLE_Q_TAG,
2114 /*features*/ATA_HPA_FEAT_SET_PWD,
2117 /*data_ptr*/(u_int8_t*)pwd,
2118 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2119 timeout ? timeout : 1000,
2125 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2129 atahpa_lock(struct cam_device *device, int retry_count,
2130 u_int32_t timeout, union ccb *ccb, int is48bit)
2136 protocol = AP_PROTO_NON_DATA;
2137 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2139 error = ata_do_cmd(device,
2142 /*flags*/CAM_DIR_NONE,
2143 /*protocol*/protocol,
2144 /*ata_flags*/AP_FLAG_CHK_COND,
2145 /*tag_action*/MSG_SIMPLE_Q_TAG,
2147 /*features*/ATA_HPA_FEAT_LOCK,
2152 timeout ? timeout : 1000,
2158 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2162 atahpa_unlock(struct cam_device *device, int retry_count,
2163 u_int32_t timeout, union ccb *ccb,
2164 int is48bit, struct ata_set_max_pwd *pwd)
2170 protocol = AP_PROTO_PIO_OUT;
2171 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2173 error = ata_do_cmd(device,
2176 /*flags*/CAM_DIR_OUT,
2177 /*protocol*/protocol,
2178 /*ata_flags*/AP_FLAG_CHK_COND,
2179 /*tag_action*/MSG_SIMPLE_Q_TAG,
2181 /*features*/ATA_HPA_FEAT_UNLOCK,
2184 /*data_ptr*/(u_int8_t*)pwd,
2185 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2186 timeout ? timeout : 1000,
2192 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2196 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2197 u_int32_t timeout, union ccb *ccb, int is48bit)
2203 protocol = AP_PROTO_NON_DATA;
2204 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2206 error = ata_do_cmd(device,
2209 /*flags*/CAM_DIR_NONE,
2210 /*protocol*/protocol,
2211 /*ata_flags*/AP_FLAG_CHK_COND,
2212 /*tag_action*/MSG_SIMPLE_Q_TAG,
2214 /*features*/ATA_HPA_FEAT_FREEZE,
2219 timeout ? timeout : 1000,
2225 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2230 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2231 union ccb *ccb, struct ata_params** ident_bufp)
2233 struct ata_params *ident_buf;
2234 struct ccb_pathinq cpi;
2235 struct ccb_getdev cgd;
2238 u_int8_t command, retry_command;
2240 if (get_cpi(device, &cpi) != 0) {
2241 warnx("couldn't get CPI");
2245 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2246 if (cpi.protocol == PROTO_ATA) {
2247 if (get_cgd(device, &cgd) != 0) {
2248 warnx("couldn't get CGD");
2252 command = (cgd.protocol == PROTO_ATA) ?
2253 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2256 /* We don't know which for sure so try both */
2257 command = ATA_ATA_IDENTIFY;
2258 retry_command = ATA_ATAPI_IDENTIFY;
2261 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2263 warnx("can't calloc memory for identify\n");
2267 error = ata_do_28bit_cmd(device,
2269 /*retries*/retry_count,
2270 /*flags*/CAM_DIR_IN,
2271 /*protocol*/AP_PROTO_PIO_IN,
2272 /*tag_action*/MSG_SIMPLE_Q_TAG,
2276 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2277 /*data_ptr*/(u_int8_t *)ptr,
2278 /*dxfer_len*/sizeof(struct ata_params),
2279 /*timeout*/timeout ? timeout : 30 * 1000,
2283 if (retry_command == 0) {
2287 error = ata_do_28bit_cmd(device,
2289 /*retries*/retry_count,
2290 /*flags*/CAM_DIR_IN,
2291 /*protocol*/AP_PROTO_PIO_IN,
2292 /*tag_action*/MSG_SIMPLE_Q_TAG,
2293 /*command*/retry_command,
2296 /*sector_count*/(u_int8_t)
2297 sizeof(struct ata_params),
2298 /*data_ptr*/(u_int8_t *)ptr,
2299 /*dxfer_len*/sizeof(struct ata_params),
2300 /*timeout*/timeout ? timeout : 30 * 1000,
2310 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2311 ptr[i] = le16toh(ptr[i]);
2316 if (arglist & CAM_ARG_VERBOSE) {
2317 fprintf(stdout, "%s%d: Raw identify data:\n",
2318 device->device_name, device->dev_unit_num);
2319 dump_data(ptr, sizeof(struct ata_params));
2322 /* check for invalid (all zero) response */
2324 warnx("Invalid identify response detected");
2329 ident_buf = (struct ata_params *)ptr;
2330 if (strncmp(ident_buf->model, "FX", 2) &&
2331 strncmp(ident_buf->model, "NEC", 3) &&
2332 strncmp(ident_buf->model, "Pioneer", 7) &&
2333 strncmp(ident_buf->model, "SHARP", 5)) {
2334 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2335 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2336 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2337 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2339 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2340 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2341 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2342 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2343 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2344 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2345 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2346 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2347 sizeof(ident_buf->media_serial));
2349 *ident_bufp = ident_buf;
2356 ataidentify(struct cam_device *device, int retry_count, int timeout)
2359 struct ata_params *ident_buf;
2362 if ((ccb = cam_getccb(device)) == NULL) {
2363 warnx("couldn't allocate CCB");
2367 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2372 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2373 if (ata_read_native_max(device, retry_count, timeout, ccb,
2374 ident_buf, &hpasize) != 0) {
2382 printf("%s%d: ", device->device_name, device->dev_unit_num);
2383 ata_print_ident(ident_buf);
2384 camxferrate(device);
2385 atacapprint(ident_buf);
2386 atahpa_print(ident_buf, hpasize, 0);
2393 #endif /* MINIMALISTIC */
2396 #ifndef MINIMALISTIC
2398 ATA_SECURITY_ACTION_PRINT,
2399 ATA_SECURITY_ACTION_FREEZE,
2400 ATA_SECURITY_ACTION_UNLOCK,
2401 ATA_SECURITY_ACTION_DISABLE,
2402 ATA_SECURITY_ACTION_ERASE,
2403 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2404 ATA_SECURITY_ACTION_SET_PASSWORD
2408 atasecurity_print_time(u_int16_t tw)
2412 printf("unspecified");
2414 printf("> 508 min");
2416 printf("%i min", 2 * tw);
2420 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2424 return 2 * 3600 * 1000; /* default: two hours */
2425 else if (timeout > 255)
2426 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2428 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2433 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2437 bzero(&cmd, sizeof(cmd));
2438 cmd.command = command;
2439 printf("Issuing %s", ata_op_string(&cmd));
2442 char pass[sizeof(pwd->password)+1];
2444 /* pwd->password may not be null terminated */
2445 pass[sizeof(pwd->password)] = '\0';
2446 strncpy(pass, pwd->password, sizeof(pwd->password));
2447 printf(" password='%s', user='%s'",
2449 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2452 if (command == ATA_SECURITY_SET_PASSWORD) {
2453 printf(", mode='%s'",
2454 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2455 "maximum" : "high");
2463 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2464 int retry_count, u_int32_t timeout, int quiet)
2468 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2470 return ata_do_28bit_cmd(device,
2473 /*flags*/CAM_DIR_NONE,
2474 /*protocol*/AP_PROTO_NON_DATA,
2475 /*tag_action*/MSG_SIMPLE_Q_TAG,
2476 /*command*/ATA_SECURITY_FREEZE_LOCK,
2487 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2488 int retry_count, u_int32_t timeout,
2489 struct ata_security_password *pwd, int quiet)
2493 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2495 return ata_do_28bit_cmd(device,
2498 /*flags*/CAM_DIR_OUT,
2499 /*protocol*/AP_PROTO_PIO_OUT,
2500 /*tag_action*/MSG_SIMPLE_Q_TAG,
2501 /*command*/ATA_SECURITY_UNLOCK,
2505 /*data_ptr*/(u_int8_t *)pwd,
2506 /*dxfer_len*/sizeof(*pwd),
2512 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2513 int retry_count, u_int32_t timeout,
2514 struct ata_security_password *pwd, int quiet)
2518 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2519 return ata_do_28bit_cmd(device,
2522 /*flags*/CAM_DIR_OUT,
2523 /*protocol*/AP_PROTO_PIO_OUT,
2524 /*tag_action*/MSG_SIMPLE_Q_TAG,
2525 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2529 /*data_ptr*/(u_int8_t *)pwd,
2530 /*dxfer_len*/sizeof(*pwd),
2537 atasecurity_erase_confirm(struct cam_device *device,
2538 struct ata_params* ident_buf)
2541 printf("\nYou are about to ERASE ALL DATA from the following"
2542 " device:\n%s%d,%s%d: ", device->device_name,
2543 device->dev_unit_num, device->given_dev_name,
2544 device->given_unit_number);
2545 ata_print_ident(ident_buf);
2549 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2551 if (fgets(str, sizeof(str), stdin) != NULL) {
2552 if (strncasecmp(str, "yes", 3) == 0) {
2554 } else if (strncasecmp(str, "no", 2) == 0) {
2557 printf("Please answer \"yes\" or "
2568 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2569 int retry_count, u_int32_t timeout,
2570 u_int32_t erase_timeout,
2571 struct ata_security_password *pwd, int quiet)
2576 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2578 error = ata_do_28bit_cmd(device,
2581 /*flags*/CAM_DIR_NONE,
2582 /*protocol*/AP_PROTO_NON_DATA,
2583 /*tag_action*/MSG_SIMPLE_Q_TAG,
2584 /*command*/ATA_SECURITY_ERASE_PREPARE,
2597 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2599 error = ata_do_28bit_cmd(device,
2602 /*flags*/CAM_DIR_OUT,
2603 /*protocol*/AP_PROTO_PIO_OUT,
2604 /*tag_action*/MSG_SIMPLE_Q_TAG,
2605 /*command*/ATA_SECURITY_ERASE_UNIT,
2609 /*data_ptr*/(u_int8_t *)pwd,
2610 /*dxfer_len*/sizeof(*pwd),
2611 /*timeout*/erase_timeout,
2614 if (error == 0 && quiet == 0)
2615 printf("\nErase Complete\n");
2621 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2622 int retry_count, u_int32_t timeout,
2623 struct ata_security_password *pwd, int quiet)
2627 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2629 return ata_do_28bit_cmd(device,
2632 /*flags*/CAM_DIR_OUT,
2633 /*protocol*/AP_PROTO_PIO_OUT,
2634 /*tag_action*/MSG_SIMPLE_Q_TAG,
2635 /*command*/ATA_SECURITY_SET_PASSWORD,
2639 /*data_ptr*/(u_int8_t *)pwd,
2640 /*dxfer_len*/sizeof(*pwd),
2646 atasecurity_print(struct ata_params *parm)
2649 printf("\nSecurity Option Value\n");
2650 if (arglist & CAM_ARG_VERBOSE) {
2651 printf("status %04x\n",
2652 parm->security_status);
2654 printf("supported %s\n",
2655 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2656 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2658 printf("enabled %s\n",
2659 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2660 printf("drive locked %s\n",
2661 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2662 printf("security config frozen %s\n",
2663 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2664 printf("count expired %s\n",
2665 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2666 printf("security level %s\n",
2667 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2668 printf("enhanced erase supported %s\n",
2669 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2670 printf("erase time ");
2671 atasecurity_print_time(parm->erase_time);
2673 printf("enhanced erase time ");
2674 atasecurity_print_time(parm->enhanced_erase_time);
2676 printf("master password rev %04x%s\n",
2677 parm->master_passwd_revision,
2678 parm->master_passwd_revision == 0x0000 ||
2679 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2683 * Validates and copies the password in optarg to the passed buffer.
2684 * If the password in optarg is the same length as the buffer then
2685 * the data will still be copied but no null termination will occur.
2688 ata_getpwd(u_int8_t *passwd, int max, char opt)
2692 len = strlen(optarg);
2694 warnx("-%c password is too long", opt);
2696 } else if (len == 0) {
2697 warnx("-%c password is missing", opt);
2699 } else if (optarg[0] == '-'){
2700 warnx("-%c password starts with '-' (generic arg?)", opt);
2702 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2703 warnx("-%c password conflicts with existing password from -%c",
2708 /* Callers pass in a buffer which does NOT need to be terminated */
2709 strncpy(passwd, optarg, max);
2716 ATA_HPA_ACTION_PRINT,
2717 ATA_HPA_ACTION_SET_MAX,
2718 ATA_HPA_ACTION_SET_PWD,
2719 ATA_HPA_ACTION_LOCK,
2720 ATA_HPA_ACTION_UNLOCK,
2721 ATA_HPA_ACTION_FREEZE_LOCK
2725 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2726 u_int64_t maxsize, int persist)
2728 printf("\nYou are about to configure HPA to limit the user accessible\n"
2729 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2730 persist ? "persistently" : "temporarily",
2731 device->device_name, device->dev_unit_num,
2732 device->given_dev_name, device->given_unit_number);
2733 ata_print_ident(ident_buf);
2737 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2739 if (NULL != fgets(str, sizeof(str), stdin)) {
2740 if (0 == strncasecmp(str, "yes", 3)) {
2742 } else if (0 == strncasecmp(str, "no", 2)) {
2745 printf("Please answer \"yes\" or "
2756 atahpa(struct cam_device *device, int retry_count, int timeout,
2757 int argc, char **argv, char *combinedopt)
2760 struct ata_params *ident_buf;
2761 struct ccb_getdev cgd;
2762 struct ata_set_max_pwd pwd;
2763 int error, confirm, quiet, c, action, actions, persist;
2764 int security, is48bit, pwdsize;
2765 u_int64_t hpasize, maxsize;
2774 memset(&pwd, 0, sizeof(pwd));
2776 /* default action is to print hpa information */
2777 action = ATA_HPA_ACTION_PRINT;
2778 pwdsize = sizeof(pwd.password);
2780 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2783 action = ATA_HPA_ACTION_SET_MAX;
2784 maxsize = strtoumax(optarg, NULL, 0);
2789 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2791 action = ATA_HPA_ACTION_SET_PWD;
2797 action = ATA_HPA_ACTION_LOCK;
2803 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2805 action = ATA_HPA_ACTION_UNLOCK;
2811 action = ATA_HPA_ACTION_FREEZE_LOCK;
2831 warnx("too many hpa actions specified");
2835 if (get_cgd(device, &cgd) != 0) {
2836 warnx("couldn't get CGD");
2840 ccb = cam_getccb(device);
2842 warnx("couldn't allocate CCB");
2846 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2853 printf("%s%d: ", device->device_name, device->dev_unit_num);
2854 ata_print_ident(ident_buf);
2855 camxferrate(device);
2858 if (action == ATA_HPA_ACTION_PRINT) {
2859 error = ata_read_native_max(device, retry_count, timeout, ccb,
2860 ident_buf, &hpasize);
2862 atahpa_print(ident_buf, hpasize, 1);
2869 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2870 warnx("HPA is not supported by this device");
2876 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2877 warnx("HPA Security is not supported by this device");
2883 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2886 * The ATA spec requires:
2887 * 1. Read native max addr is called directly before set max addr
2888 * 2. Read native max addr is NOT called before any other set max call
2891 case ATA_HPA_ACTION_SET_MAX:
2893 atahpa_set_confirm(device, ident_buf, maxsize,
2900 error = ata_read_native_max(device, retry_count, timeout,
2901 ccb, ident_buf, &hpasize);
2903 error = atahpa_set_max(device, retry_count, timeout,
2904 ccb, is48bit, maxsize, persist);
2906 /* redo identify to get new lba values */
2907 error = ata_do_identify(device, retry_count,
2910 atahpa_print(ident_buf, hpasize, 1);
2915 case ATA_HPA_ACTION_SET_PWD:
2916 error = atahpa_password(device, retry_count, timeout,
2917 ccb, is48bit, &pwd);
2919 printf("HPA password has been set\n");
2922 case ATA_HPA_ACTION_LOCK:
2923 error = atahpa_lock(device, retry_count, timeout,
2926 printf("HPA has been locked\n");
2929 case ATA_HPA_ACTION_UNLOCK:
2930 error = atahpa_unlock(device, retry_count, timeout,
2931 ccb, is48bit, &pwd);
2933 printf("HPA has been unlocked\n");
2936 case ATA_HPA_ACTION_FREEZE_LOCK:
2937 error = atahpa_freeze_lock(device, retry_count, timeout,
2940 printf("HPA has been frozen\n");
2944 errx(1, "Option currently not supported");
2954 atasecurity(struct cam_device *device, int retry_count, int timeout,
2955 int argc, char **argv, char *combinedopt)
2958 struct ata_params *ident_buf;
2959 int error, confirm, quiet, c, action, actions, setpwd;
2960 int security_enabled, erase_timeout, pwdsize;
2961 struct ata_security_password pwd;
2969 memset(&pwd, 0, sizeof(pwd));
2971 /* default action is to print security information */
2972 action = ATA_SECURITY_ACTION_PRINT;
2974 /* user is master by default as its safer that way */
2975 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2976 pwdsize = sizeof(pwd.password);
2978 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2981 action = ATA_SECURITY_ACTION_FREEZE;
2986 if (strcasecmp(optarg, "user") == 0) {
2987 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2988 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2989 } else if (strcasecmp(optarg, "master") == 0) {
2990 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2991 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2993 warnx("-U argument '%s' is invalid (must be "
2994 "'user' or 'master')", optarg);
3000 if (strcasecmp(optarg, "high") == 0) {
3001 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3002 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3003 } else if (strcasecmp(optarg, "maximum") == 0) {
3004 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3005 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3007 warnx("-l argument '%s' is unknown (must be "
3008 "'high' or 'maximum')", optarg);
3014 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3016 action = ATA_SECURITY_ACTION_UNLOCK;
3021 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3023 action = ATA_SECURITY_ACTION_DISABLE;
3028 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3030 action = ATA_SECURITY_ACTION_ERASE;
3035 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3037 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3038 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3043 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3046 if (action == ATA_SECURITY_ACTION_PRINT)
3047 action = ATA_SECURITY_ACTION_SET_PASSWORD;
3049 * Don't increment action as this can be combined
3050 * with other actions.
3063 erase_timeout = atoi(optarg) * 1000;
3069 warnx("too many security actions specified");
3073 if ((ccb = cam_getccb(device)) == NULL) {
3074 warnx("couldn't allocate CCB");
3078 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3085 printf("%s%d: ", device->device_name, device->dev_unit_num);
3086 ata_print_ident(ident_buf);
3087 camxferrate(device);
3090 if (action == ATA_SECURITY_ACTION_PRINT) {
3091 atasecurity_print(ident_buf);
3097 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3098 warnx("Security not supported");
3104 /* default timeout 15 seconds the same as linux hdparm */
3105 timeout = timeout ? timeout : 15 * 1000;
3107 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3109 /* first set the password if requested */
3111 /* confirm we can erase before setting the password if erasing */
3113 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3114 action == ATA_SECURITY_ACTION_ERASE) &&
3115 atasecurity_erase_confirm(device, ident_buf) == 0) {
3121 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3122 pwd.revision = ident_buf->master_passwd_revision;
3123 if (pwd.revision != 0 && pwd.revision != 0xfff &&
3124 --pwd.revision == 0) {
3125 pwd.revision = 0xfffe;
3128 error = atasecurity_set_password(device, ccb, retry_count,
3129 timeout, &pwd, quiet);
3135 security_enabled = 1;
3139 case ATA_SECURITY_ACTION_FREEZE:
3140 error = atasecurity_freeze(device, ccb, retry_count,
3144 case ATA_SECURITY_ACTION_UNLOCK:
3145 if (security_enabled) {
3146 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3147 error = atasecurity_unlock(device, ccb,
3148 retry_count, timeout, &pwd, quiet);
3150 warnx("Can't unlock, drive is not locked");
3154 warnx("Can't unlock, security is disabled");
3159 case ATA_SECURITY_ACTION_DISABLE:
3160 if (security_enabled) {
3161 /* First unlock the drive if its locked */
3162 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3163 error = atasecurity_unlock(device, ccb,
3171 error = atasecurity_disable(device,
3179 warnx("Can't disable security (already disabled)");
3184 case ATA_SECURITY_ACTION_ERASE:
3185 if (security_enabled) {
3186 if (erase_timeout == 0) {
3187 erase_timeout = atasecurity_erase_timeout_msecs(
3188 ident_buf->erase_time);
3191 error = atasecurity_erase(device, ccb, retry_count,
3192 timeout, erase_timeout, &pwd, quiet);
3194 warnx("Can't secure erase (security is disabled)");
3199 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3200 if (security_enabled) {
3201 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3202 if (erase_timeout == 0) {
3204 atasecurity_erase_timeout_msecs(
3205 ident_buf->enhanced_erase_time);
3208 error = atasecurity_erase(device, ccb,
3209 retry_count, timeout,
3210 erase_timeout, &pwd,
3213 warnx("Enhanced erase is not supported");
3217 warnx("Can't secure erase (enhanced), "
3218 "(security is disabled)");
3229 #endif /* MINIMALISTIC */
3232 * Parse out a bus, or a bus, target and lun in the following
3238 * Returns the number of parsed components, or 0.
3241 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3242 cam_argmask *arglst)
3247 while (isspace(*tstr) && (*tstr != '\0'))
3250 tmpstr = (char *)strtok(tstr, ":");
3251 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3252 *bus = strtol(tmpstr, NULL, 0);
3253 *arglst |= CAM_ARG_BUS;
3255 tmpstr = (char *)strtok(NULL, ":");
3256 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3257 *target = strtol(tmpstr, NULL, 0);
3258 *arglst |= CAM_ARG_TARGET;
3260 tmpstr = (char *)strtok(NULL, ":");
3261 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3262 *lun = strtol(tmpstr, NULL, 0);
3263 *arglst |= CAM_ARG_LUN;
3273 dorescan_or_reset(int argc, char **argv, int rescan)
3275 static const char must[] =
3276 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3278 path_id_t bus = CAM_BUS_WILDCARD;
3279 target_id_t target = CAM_TARGET_WILDCARD;
3280 lun_id_t lun = CAM_LUN_WILDCARD;
3284 warnx(must, rescan? "rescan" : "reset");
3288 tstr = argv[optind];
3289 while (isspace(*tstr) && (*tstr != '\0'))
3291 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3292 arglist |= CAM_ARG_BUS;
3293 else if (isdigit(*tstr)) {
3294 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3295 if (rv != 1 && rv != 3) {
3296 warnx(must, rescan? "rescan" : "reset");
3306 * Note that resetting or rescanning a device used to
3307 * require a bus or bus:target:lun. This is because the
3308 * device in question may not exist and you're trying to
3309 * get the controller to rescan to find it. It may also be
3310 * because the device is hung / unresponsive, and opening
3311 * an unresponsive device is not desireable.
3313 * It can be more convenient to reference a device by
3314 * peripheral name and unit number, though, and it is
3315 * possible to get the bus:target:lun for devices that
3316 * currently exist in the EDT. So this can work for
3317 * devices that we want to reset, or devices that exist
3318 * that we want to rescan, but not devices that do not
3321 * So, we are careful here to look up the bus/target/lun
3322 * for the device the user wants to operate on, specified
3323 * by peripheral instance (e.g. da0, pass32) without
3324 * actually opening that device. The process is similar to
3325 * what cam_lookup_pass() does, except that we don't
3326 * actually open the passthrough driver instance in the end.
3329 if (cam_get_device(tstr, name, sizeof(name), &unit) == -1) {
3330 warnx("%s", cam_errbuf);
3335 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3336 warn("Unable to open %s", XPT_DEVICE);
3341 bzero(&ccb, sizeof(ccb));
3344 * The function code isn't strictly necessary for the
3345 * GETPASSTHRU ioctl.
3347 ccb.ccb_h.func_code = XPT_GDEVLIST;
3350 * These two are necessary for the GETPASSTHRU ioctl to
3353 strlcpy(ccb.cgdl.periph_name, name,
3354 sizeof(ccb.cgdl.periph_name));
3355 ccb.cgdl.unit_number = unit;
3358 * Attempt to get the passthrough device. This ioctl will
3359 * fail if the device name is null, if the device doesn't
3360 * exist, or if the passthrough driver isn't in the kernel.
3362 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3363 warn("Unable to find bus:target:lun for device %s%d",
3369 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3370 const struct cam_status_entry *entry;
3372 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3373 warnx("Unable to find bus:target_lun for device %s%d, "
3374 "CAM status: %s (%#x)", name, unit,
3375 entry ? entry->status_text : "Unknown",
3383 * The kernel fills in the bus/target/lun. We don't
3384 * need the passthrough device name and unit number since
3385 * we aren't going to open it.
3387 bus = ccb.ccb_h.path_id;
3388 target = ccb.ccb_h.target_id;
3389 lun = ccb.ccb_h.target_lun;
3391 arglist |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3396 if ((arglist & CAM_ARG_BUS)
3397 && (arglist & CAM_ARG_TARGET)
3398 && (arglist & CAM_ARG_LUN))
3399 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3401 error = rescan_or_reset_bus(bus, rescan);
3409 rescan_or_reset_bus(path_id_t bus, int rescan)
3411 union ccb *ccb = NULL, *matchccb = NULL;
3412 int fd = -1, retval;
3417 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3418 warnx("error opening transport layer device %s", XPT_DEVICE);
3419 warn("%s", XPT_DEVICE);
3423 ccb = malloc(sizeof(*ccb));
3425 warn("failed to allocate CCB");
3429 bzero(ccb, sizeof(*ccb));
3431 if (bus != CAM_BUS_WILDCARD) {
3432 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3433 ccb->ccb_h.path_id = bus;
3434 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3435 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3436 ccb->crcn.flags = CAM_FLAG_NONE;
3438 /* run this at a low priority */
3439 ccb->ccb_h.pinfo.priority = 5;
3441 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3442 warn("CAMIOCOMMAND ioctl failed");
3447 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3448 fprintf(stdout, "%s of bus %d was successful\n",
3449 rescan ? "Re-scan" : "Reset", bus);
3451 fprintf(stdout, "%s of bus %d returned error %#x\n",
3452 rescan ? "Re-scan" : "Reset", bus,
3453 ccb->ccb_h.status & CAM_STATUS_MASK);
3462 * The right way to handle this is to modify the xpt so that it can
3463 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3464 * that isn't implemented, so instead we enumerate the buses and
3465 * send the rescan or reset to those buses in the case where the
3466 * given bus is -1 (wildcard). We don't send a rescan or reset
3467 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3468 * no-op, sending a rescan to the xpt bus would result in a status of
3471 matchccb = malloc(sizeof(*matchccb));
3472 if (matchccb == NULL) {
3473 warn("failed to allocate CCB");
3477 bzero(matchccb, sizeof(*matchccb));
3478 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3479 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3480 bufsize = sizeof(struct dev_match_result) * 20;
3481 matchccb->cdm.match_buf_len = bufsize;
3482 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3483 if (matchccb->cdm.matches == NULL) {
3484 warnx("can't malloc memory for matches");
3488 matchccb->cdm.num_matches = 0;
3490 matchccb->cdm.num_patterns = 1;
3491 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3493 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3494 matchccb->cdm.pattern_buf_len);
3495 if (matchccb->cdm.patterns == NULL) {
3496 warnx("can't malloc memory for patterns");
3500 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3501 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3506 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3507 warn("CAMIOCOMMAND ioctl failed");
3512 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3513 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3514 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3515 warnx("got CAM error %#x, CDM error %d\n",
3516 matchccb->ccb_h.status, matchccb->cdm.status);
3521 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3522 struct bus_match_result *bus_result;
3524 /* This shouldn't happen. */
3525 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3528 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3531 * We don't want to rescan or reset the xpt bus.
3534 if (bus_result->path_id == CAM_XPT_PATH_ID)
3537 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3539 ccb->ccb_h.path_id = bus_result->path_id;
3540 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3541 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3542 ccb->crcn.flags = CAM_FLAG_NONE;
3544 /* run this at a low priority */
3545 ccb->ccb_h.pinfo.priority = 5;
3547 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3548 warn("CAMIOCOMMAND ioctl failed");
3553 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3554 fprintf(stdout, "%s of bus %d was successful\n",
3555 rescan? "Re-scan" : "Reset",
3556 bus_result->path_id);
3559 * Don't bail out just yet, maybe the other
3560 * rescan or reset commands will complete
3563 fprintf(stderr, "%s of bus %d returned error "
3564 "%#x\n", rescan? "Re-scan" : "Reset",
3565 bus_result->path_id,
3566 ccb->ccb_h.status & CAM_STATUS_MASK);
3570 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3571 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3578 if (matchccb != NULL) {
3579 free(matchccb->cdm.patterns);
3580 free(matchccb->cdm.matches);
3589 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3592 struct cam_device *device;
3597 if (bus == CAM_BUS_WILDCARD) {
3598 warnx("invalid bus number %d", bus);
3602 if (target == CAM_TARGET_WILDCARD) {
3603 warnx("invalid target number %d", target);
3607 if (lun == CAM_LUN_WILDCARD) {
3608 warnx("invalid lun number %jx", (uintmax_t)lun);
3614 bzero(&ccb, sizeof(union ccb));
3617 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3618 warnx("error opening transport layer device %s\n",
3620 warn("%s", XPT_DEVICE);
3624 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3625 if (device == NULL) {
3626 warnx("%s", cam_errbuf);
3631 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3632 ccb.ccb_h.path_id = bus;
3633 ccb.ccb_h.target_id = target;
3634 ccb.ccb_h.target_lun = lun;
3635 ccb.ccb_h.timeout = 5000;
3636 ccb.crcn.flags = CAM_FLAG_NONE;
3638 /* run this at a low priority */
3639 ccb.ccb_h.pinfo.priority = 5;
3642 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3643 warn("CAMIOCOMMAND ioctl failed");
3648 if (cam_send_ccb(device, &ccb) < 0) {
3649 warn("error sending XPT_RESET_DEV CCB");
3650 cam_close_device(device);
3658 cam_close_device(device);
3661 * An error code of CAM_BDR_SENT is normal for a BDR request.
3663 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3665 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3666 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3667 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3670 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3671 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3672 ccb.ccb_h.status & CAM_STATUS_MASK);
3677 #ifndef MINIMALISTIC
3679 static struct scsi_nv defect_list_type_map[] = {
3680 { "block", SRDD10_BLOCK_FORMAT },
3681 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3682 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3683 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3684 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3685 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3689 readdefects(struct cam_device *device, int argc, char **argv,
3690 char *combinedopt, int task_attr, int retry_count, int timeout)
3692 union ccb *ccb = NULL;
3693 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3694 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3695 size_t hdr_size = 0, entry_size = 0;
3698 u_int8_t *defect_list = NULL;
3699 u_int8_t list_format = 0;
3700 int list_type_set = 0;
3701 u_int32_t dlist_length = 0;
3702 u_int32_t returned_length = 0, valid_len = 0;
3703 u_int32_t num_returned = 0, num_valid = 0;
3704 u_int32_t max_possible_size = 0, hdr_max = 0;
3705 u_int32_t starting_offset = 0;
3706 u_int8_t returned_format, returned_type;
3708 int summary = 0, quiet = 0;
3710 int lists_specified = 0;
3711 int get_length = 1, first_pass = 1;
3714 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3718 scsi_nv_status status;
3721 status = scsi_get_nv(defect_list_type_map,
3722 sizeof(defect_list_type_map) /
3723 sizeof(defect_list_type_map[0]), optarg,
3724 &entry_num, SCSI_NV_FLAG_IG_CASE);
3726 if (status == SCSI_NV_FOUND) {
3727 list_format = defect_list_type_map[
3731 warnx("%s: %s %s option %s", __func__,
3732 (status == SCSI_NV_AMBIGUOUS) ?
3733 "ambiguous" : "invalid", "defect list type",
3736 goto defect_bailout;
3741 arglist |= CAM_ARG_GLIST;
3744 arglist |= CAM_ARG_PLIST;
3755 starting_offset = strtoul(optarg, &endptr, 0);
3756 if (*endptr != '\0') {
3758 warnx("invalid starting offset %s", optarg);
3759 goto defect_bailout;
3771 if (list_type_set == 0) {
3773 warnx("no defect list format specified");
3774 goto defect_bailout;
3777 if (arglist & CAM_ARG_PLIST) {
3778 list_format |= SRDD10_PLIST;
3782 if (arglist & CAM_ARG_GLIST) {
3783 list_format |= SRDD10_GLIST;
3788 * This implies a summary, and was the previous behavior.
3790 if (lists_specified == 0)
3793 ccb = cam_getccb(device);
3798 * We start off asking for just the header to determine how much
3799 * defect data is available. Some Hitachi drives return an error
3800 * if you ask for more data than the drive has. Once we know the
3801 * length, we retry the command with the returned length.
3803 if (use_12byte == 0)
3804 dlist_length = sizeof(*hdr10);
3806 dlist_length = sizeof(*hdr12);
3809 if (defect_list != NULL) {
3813 defect_list = malloc(dlist_length);
3814 if (defect_list == NULL) {
3815 warnx("can't malloc memory for defect list");
3817 goto defect_bailout;
3821 bzero(defect_list, dlist_length);
3824 * cam_getccb() zeros the CCB header only. So we need to zero the
3825 * payload portion of the ccb.
3827 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3829 scsi_read_defects(&ccb->csio,
3830 /*retries*/ retry_count,
3832 /*tag_action*/ task_attr,
3833 /*list_format*/ list_format,
3834 /*addr_desc_index*/ starting_offset,
3835 /*data_ptr*/ defect_list,
3836 /*dxfer_len*/ dlist_length,
3837 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3838 /*sense_len*/ SSD_FULL_SIZE,
3839 /*timeout*/ timeout ? timeout : 5000);
3841 /* Disable freezing the device queue */
3842 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3844 if (cam_send_ccb(device, ccb) < 0) {
3845 perror("error reading defect list");
3847 if (arglist & CAM_ARG_VERBOSE) {
3848 cam_error_print(device, ccb, CAM_ESF_ALL,
3849 CAM_EPF_ALL, stderr);
3853 goto defect_bailout;
3856 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3858 if (use_12byte == 0) {
3859 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3860 hdr_size = sizeof(*hdr10);
3861 hdr_max = SRDDH10_MAX_LENGTH;
3863 if (valid_len >= hdr_size) {
3864 returned_length = scsi_2btoul(hdr10->length);
3865 returned_format = hdr10->format;
3867 returned_length = 0;
3868 returned_format = 0;
3871 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3872 hdr_size = sizeof(*hdr12);
3873 hdr_max = SRDDH12_MAX_LENGTH;
3875 if (valid_len >= hdr_size) {
3876 returned_length = scsi_4btoul(hdr12->length);
3877 returned_format = hdr12->format;
3879 returned_length = 0;
3880 returned_format = 0;
3884 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3885 switch (returned_type) {
3886 case SRDD10_BLOCK_FORMAT:
3887 entry_size = sizeof(struct scsi_defect_desc_block);
3889 case SRDD10_LONG_BLOCK_FORMAT:
3890 entry_size = sizeof(struct scsi_defect_desc_long_block);
3892 case SRDD10_EXT_PHYS_FORMAT:
3893 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3894 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3896 case SRDD10_EXT_BFI_FORMAT:
3897 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3898 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3901 warnx("Unknown defect format 0x%x\n", returned_type);
3903 goto defect_bailout;
3907 max_possible_size = (hdr_max / entry_size) * entry_size;
3908 num_returned = returned_length / entry_size;
3909 num_valid = min(returned_length, valid_len - hdr_size);
3910 num_valid /= entry_size;
3912 if (get_length != 0) {
3915 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3916 CAM_SCSI_STATUS_ERROR) {
3917 struct scsi_sense_data *sense;
3918 int error_code, sense_key, asc, ascq;
3920 sense = &ccb->csio.sense_data;
3921 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3922 ccb->csio.sense_resid, &error_code, &sense_key,
3923 &asc, &ascq, /*show_errors*/ 1);
3926 * If the drive is reporting that it just doesn't
3927 * support the defect list format, go ahead and use
3928 * the length it reported. Otherwise, the length
3929 * may not be valid, so use the maximum.
3931 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3932 && (asc == 0x1c) && (ascq == 0x00)
3933 && (returned_length > 0)) {
3934 if ((use_12byte == 0)
3935 && (returned_length >= max_possible_size)) {
3940 dlist_length = returned_length + hdr_size;
3941 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3942 && (asc == 0x1f) && (ascq == 0x00)
3943 && (returned_length > 0)) {
3944 /* Partial defect list transfer */
3946 * Hitachi drives return this error
3947 * along with a partial defect list if they
3948 * have more defects than the 10 byte
3949 * command can support. Retry with the 12
3952 if (use_12byte == 0) {
3957 dlist_length = returned_length + hdr_size;
3958 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
3959 && (asc == 0x24) && (ascq == 0x00)) {
3960 /* Invalid field in CDB */
3962 * SBC-3 says that if the drive has more
3963 * defects than can be reported with the
3964 * 10 byte command, it should return this
3965 * error and no data. Retry with the 12
3968 if (use_12byte == 0) {
3973 dlist_length = returned_length + hdr_size;
3976 * If we got a SCSI error and no valid length,
3977 * just use the 10 byte maximum. The 12
3978 * byte maximum is too large.
3980 if (returned_length == 0)
3981 dlist_length = SRDD10_MAX_LENGTH;
3983 if ((use_12byte == 0)
3984 && (returned_length >=
3985 max_possible_size)) {
3990 dlist_length = returned_length +
3994 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3997 warnx("Error reading defect header");
3998 if (arglist & CAM_ARG_VERBOSE)
3999 cam_error_print(device, ccb, CAM_ESF_ALL,
4000 CAM_EPF_ALL, stderr);
4001 goto defect_bailout;
4003 if ((use_12byte == 0)
4004 && (returned_length >= max_possible_size)) {
4009 dlist_length = returned_length + hdr_size;
4012 fprintf(stdout, "%u", num_returned);
4014 fprintf(stdout, " defect%s",
4015 (num_returned != 1) ? "s" : "");
4017 fprintf(stdout, "\n");
4019 goto defect_bailout;
4023 * We always limit the list length to the 10-byte maximum
4024 * length (0xffff). The reason is that some controllers
4025 * can't handle larger I/Os, and we can transfer the entire
4026 * 10 byte list in one shot. For drives that support the 12
4027 * byte read defects command, we'll step through the list
4028 * by specifying a starting offset. For drives that don't
4029 * support the 12 byte command's starting offset, we'll
4030 * just display the first 64K.
4032 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4038 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4039 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4040 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4041 struct scsi_sense_data *sense;
4042 int error_code, sense_key, asc, ascq;
4044 sense = &ccb->csio.sense_data;
4045 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4046 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4047 &ascq, /*show_errors*/ 1);
4050 * According to the SCSI spec, if the disk doesn't support
4051 * the requested format, it will generally return a sense
4052 * key of RECOVERED ERROR, and an additional sense code
4053 * of "DEFECT LIST NOT FOUND". HGST drives also return
4054 * Primary/Grown defect list not found errors. So just
4055 * check for an ASC of 0x1c.
4057 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4059 const char *format_str;
4061 format_str = scsi_nv_to_str(defect_list_type_map,
4062 sizeof(defect_list_type_map) /
4063 sizeof(defect_list_type_map[0]),
4064 list_format & SRDD10_DLIST_FORMAT_MASK);
4065 warnx("requested defect format %s not available",
4066 format_str ? format_str : "unknown");
4068 format_str = scsi_nv_to_str(defect_list_type_map,
4069 sizeof(defect_list_type_map) /
4070 sizeof(defect_list_type_map[0]), returned_type);
4071 if (format_str != NULL) {
4072 warnx("Device returned %s format",
4076 warnx("Device returned unknown defect"
4077 " data format %#x", returned_type);
4078 goto defect_bailout;
4082 warnx("Error returned from read defect data command");
4083 if (arglist & CAM_ARG_VERBOSE)
4084 cam_error_print(device, ccb, CAM_ESF_ALL,
4085 CAM_EPF_ALL, stderr);
4086 goto defect_bailout;
4088 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4090 warnx("Error returned from read defect data command");
4091 if (arglist & CAM_ARG_VERBOSE)
4092 cam_error_print(device, ccb, CAM_ESF_ALL,
4093 CAM_EPF_ALL, stderr);
4094 goto defect_bailout;
4097 if (first_pass != 0) {
4098 fprintf(stderr, "Got %d defect", num_returned);
4100 if ((lists_specified == 0) || (num_returned == 0)) {
4101 fprintf(stderr, "s.\n");
4102 goto defect_bailout;
4103 } else if (num_returned == 1)
4104 fprintf(stderr, ":\n");
4106 fprintf(stderr, "s:\n");
4112 * XXX KDM I should probably clean up the printout format for the
4115 switch (returned_type) {
4116 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4117 case SRDD10_EXT_PHYS_FORMAT:
4119 struct scsi_defect_desc_phys_sector *dlist;
4121 dlist = (struct scsi_defect_desc_phys_sector *)
4122 (defect_list + hdr_size);
4124 for (i = 0; i < num_valid; i++) {
4127 sector = scsi_4btoul(dlist[i].sector);
4128 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4129 mads = (sector & SDD_EXT_PHYS_MADS) ?
4131 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4133 if (hex_format == 0)
4134 fprintf(stdout, "%d:%d:%d%s",
4135 scsi_3btoul(dlist[i].cylinder),
4137 scsi_4btoul(dlist[i].sector),
4138 mads ? " - " : "\n");
4140 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4141 scsi_3btoul(dlist[i].cylinder),
4143 scsi_4btoul(dlist[i].sector),
4144 mads ? " - " : "\n");
4147 if (num_valid < num_returned) {
4148 starting_offset += num_valid;
4153 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4154 case SRDD10_EXT_BFI_FORMAT:
4156 struct scsi_defect_desc_bytes_from_index *dlist;
4158 dlist = (struct scsi_defect_desc_bytes_from_index *)
4159 (defect_list + hdr_size);
4161 for (i = 0; i < num_valid; i++) {
4164 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4165 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4166 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4167 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4169 if (hex_format == 0)
4170 fprintf(stdout, "%d:%d:%d%s",
4171 scsi_3btoul(dlist[i].cylinder),
4173 scsi_4btoul(dlist[i].bytes_from_index),
4174 mads ? " - " : "\n");
4176 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4177 scsi_3btoul(dlist[i].cylinder),
4179 scsi_4btoul(dlist[i].bytes_from_index),
4180 mads ? " - " : "\n");
4184 if (num_valid < num_returned) {
4185 starting_offset += num_valid;
4190 case SRDDH10_BLOCK_FORMAT:
4192 struct scsi_defect_desc_block *dlist;
4194 dlist = (struct scsi_defect_desc_block *)
4195 (defect_list + hdr_size);
4197 for (i = 0; i < num_valid; i++) {
4198 if (hex_format == 0)
4199 fprintf(stdout, "%u\n",
4200 scsi_4btoul(dlist[i].address));
4202 fprintf(stdout, "0x%x\n",
4203 scsi_4btoul(dlist[i].address));
4206 if (num_valid < num_returned) {
4207 starting_offset += num_valid;
4213 case SRDD10_LONG_BLOCK_FORMAT:
4215 struct scsi_defect_desc_long_block *dlist;
4217 dlist = (struct scsi_defect_desc_long_block *)
4218 (defect_list + hdr_size);
4220 for (i = 0; i < num_valid; i++) {
4221 if (hex_format == 0)
4222 fprintf(stdout, "%ju\n",
4223 (uintmax_t)scsi_8btou64(
4226 fprintf(stdout, "0x%jx\n",
4227 (uintmax_t)scsi_8btou64(
4231 if (num_valid < num_returned) {
4232 starting_offset += num_valid;
4238 fprintf(stderr, "Unknown defect format 0x%x\n",
4245 if (defect_list != NULL)
4253 #endif /* MINIMALISTIC */
4257 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4261 ccb = cam_getccb(device);
4267 #ifndef MINIMALISTIC
4269 mode_sense(struct cam_device *device, int dbd, int pc, int page, int subpage,
4270 int task_attr, int retry_count, int timeout, u_int8_t *data,
4276 ccb = cam_getccb(device);
4279 errx(1, "mode_sense: couldn't allocate CCB");
4281 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4283 scsi_mode_sense_subpage(&ccb->csio,
4284 /* retries */ retry_count,
4286 /* tag_action */ task_attr,
4290 /* subpage */ subpage,
4291 /* param_buf */ data,
4292 /* param_len */ datalen,
4293 /* minimum_cmd_size */ 0,
4294 /* sense_len */ SSD_FULL_SIZE,
4295 /* timeout */ timeout ? timeout : 5000);
4297 if (arglist & CAM_ARG_ERR_RECOVER)
4298 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4300 /* Disable freezing the device queue */
4301 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4303 if (((retval = cam_send_ccb(device, ccb)) < 0)
4304 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4305 if (arglist & CAM_ARG_VERBOSE) {
4306 cam_error_print(device, ccb, CAM_ESF_ALL,
4307 CAM_EPF_ALL, stderr);
4310 cam_close_device(device);
4312 err(1, "error sending mode sense command");
4314 errx(1, "error sending mode sense command");
4321 mode_select(struct cam_device *device, int save_pages, int task_attr,
4322 int retry_count, int timeout, u_int8_t *data, int datalen)
4327 ccb = cam_getccb(device);
4330 errx(1, "mode_select: couldn't allocate CCB");
4332 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4334 scsi_mode_select(&ccb->csio,
4335 /* retries */ retry_count,
4337 /* tag_action */ task_attr,
4338 /* scsi_page_fmt */ 1,
4339 /* save_pages */ save_pages,
4340 /* param_buf */ data,
4341 /* param_len */ datalen,
4342 /* sense_len */ SSD_FULL_SIZE,
4343 /* timeout */ timeout ? timeout : 5000);
4345 if (arglist & CAM_ARG_ERR_RECOVER)
4346 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4348 /* Disable freezing the device queue */
4349 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4351 if (((retval = cam_send_ccb(device, ccb)) < 0)
4352 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4353 if (arglist & CAM_ARG_VERBOSE) {
4354 cam_error_print(device, ccb, CAM_ESF_ALL,
4355 CAM_EPF_ALL, stderr);
4358 cam_close_device(device);
4361 err(1, "error sending mode select command");
4363 errx(1, "error sending mode select command");
4371 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4372 int task_attr, int retry_count, int timeout)
4375 int c, page = -1, subpage = -1, pc = 0;
4376 int binary = 0, dbd = 0, edit = 0, list = 0;
4378 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4393 str_subpage = optarg;
4394 strsep(&str_subpage, ",");
4395 page = strtol(optarg, NULL, 0);
4397 subpage = strtol(str_subpage, NULL, 0);
4401 errx(1, "invalid mode page %d", page);
4403 errx(1, "invalid mode subpage %d", subpage);
4406 pc = strtol(optarg, NULL, 0);
4407 if ((pc < 0) || (pc > 3))
4408 errx(1, "invalid page control field %d", pc);
4415 if (page == -1 && list == 0)
4416 errx(1, "you must specify a mode page!");
4419 mode_list(device, dbd, pc, list > 1, task_attr, retry_count,
4422 mode_edit(device, dbd, pc, page, subpage, edit, binary,
4423 task_attr, retry_count, timeout);
4428 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4429 int task_attr, int retry_count, int timeout)
4432 u_int32_t flags = CAM_DIR_NONE;
4433 u_int8_t *data_ptr = NULL;
4435 u_int8_t atacmd[12];
4436 struct get_hook hook;
4437 int c, data_bytes = 0, valid_bytes;
4443 char *datastr = NULL, *tstr, *resstr = NULL;
4445 int fd_data = 0, fd_res = 0;
4448 ccb = cam_getccb(device);
4451 warnx("scsicmd: error allocating ccb");
4455 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4457 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4461 while (isspace(*tstr) && (*tstr != '\0'))
4463 hook.argc = argc - optind;
4464 hook.argv = argv + optind;
4466 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4469 * Increment optind by the number of arguments the
4470 * encoding routine processed. After each call to
4471 * getopt(3), optind points to the argument that
4472 * getopt should process _next_. In this case,
4473 * that means it points to the first command string
4474 * argument, if there is one. Once we increment
4475 * this, it should point to either the next command
4476 * line argument, or it should be past the end of
4483 while (isspace(*tstr) && (*tstr != '\0'))
4485 hook.argc = argc - optind;
4486 hook.argv = argv + optind;
4488 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4491 * Increment optind by the number of arguments the
4492 * encoding routine processed. After each call to
4493 * getopt(3), optind points to the argument that
4494 * getopt should process _next_. In this case,
4495 * that means it points to the first command string
4496 * argument, if there is one. Once we increment
4497 * this, it should point to either the next command
4498 * line argument, or it should be past the end of
4510 if (arglist & CAM_ARG_CMD_OUT) {
4511 warnx("command must either be "
4512 "read or write, not both");
4514 goto scsicmd_bailout;
4516 arglist |= CAM_ARG_CMD_IN;
4518 data_bytes = strtol(optarg, NULL, 0);
4519 if (data_bytes <= 0) {
4520 warnx("invalid number of input bytes %d",
4523 goto scsicmd_bailout;
4525 hook.argc = argc - optind;
4526 hook.argv = argv + optind;
4529 datastr = cget(&hook, NULL);
4531 * If the user supplied "-" instead of a format, he
4532 * wants the data to be written to stdout.
4534 if ((datastr != NULL)
4535 && (datastr[0] == '-'))
4538 data_ptr = (u_int8_t *)malloc(data_bytes);
4539 if (data_ptr == NULL) {
4540 warnx("can't malloc memory for data_ptr");
4542 goto scsicmd_bailout;
4546 if (arglist & CAM_ARG_CMD_IN) {
4547 warnx("command must either be "
4548 "read or write, not both");
4550 goto scsicmd_bailout;
4552 arglist |= CAM_ARG_CMD_OUT;
4553 flags = CAM_DIR_OUT;
4554 data_bytes = strtol(optarg, NULL, 0);
4555 if (data_bytes <= 0) {
4556 warnx("invalid number of output bytes %d",
4559 goto scsicmd_bailout;
4561 hook.argc = argc - optind;
4562 hook.argv = argv + optind;
4564 datastr = cget(&hook, NULL);
4565 data_ptr = (u_int8_t *)malloc(data_bytes);
4566 if (data_ptr == NULL) {
4567 warnx("can't malloc memory for data_ptr");
4569 goto scsicmd_bailout;
4571 bzero(data_ptr, data_bytes);
4573 * If the user supplied "-" instead of a format, he
4574 * wants the data to be read from stdin.
4576 if ((datastr != NULL)
4577 && (datastr[0] == '-'))
4580 buff_encode_visit(data_ptr, data_bytes, datastr,
4586 hook.argc = argc - optind;
4587 hook.argv = argv + optind;
4589 resstr = cget(&hook, NULL);
4590 if ((resstr != NULL) && (resstr[0] == '-'))
4600 * If fd_data is set, and we're writing to the device, we need to
4601 * read the data the user wants written from stdin.
4603 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4605 int amt_to_read = data_bytes;
4606 u_int8_t *buf_ptr = data_ptr;
4608 for (amt_read = 0; amt_to_read > 0;
4609 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4610 if (amt_read == -1) {
4611 warn("error reading data from stdin");
4613 goto scsicmd_bailout;
4615 amt_to_read -= amt_read;
4616 buf_ptr += amt_read;
4620 if (arglist & CAM_ARG_ERR_RECOVER)
4621 flags |= CAM_PASS_ERR_RECOVER;
4623 /* Disable freezing the device queue */
4624 flags |= CAM_DEV_QFRZDIS;
4628 * This is taken from the SCSI-3 draft spec.
4629 * (T10/1157D revision 0.3)
4630 * The top 3 bits of an opcode are the group code.
4631 * The next 5 bits are the command code.
4632 * Group 0: six byte commands
4633 * Group 1: ten byte commands
4634 * Group 2: ten byte commands
4636 * Group 4: sixteen byte commands
4637 * Group 5: twelve byte commands
4638 * Group 6: vendor specific
4639 * Group 7: vendor specific
4641 switch((cdb[0] >> 5) & 0x7) {
4652 /* computed by buff_encode_visit */
4663 * We should probably use csio_build_visit or something like that
4664 * here, but it's easier to encode arguments as you go. The
4665 * alternative would be skipping the CDB argument and then encoding
4666 * it here, since we've got the data buffer argument by now.
4668 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4670 cam_fill_csio(&ccb->csio,
4671 /*retries*/ retry_count,
4674 /*tag_action*/ task_attr,
4675 /*data_ptr*/ data_ptr,
4676 /*dxfer_len*/ data_bytes,
4677 /*sense_len*/ SSD_FULL_SIZE,
4678 /*cdb_len*/ cdb_len,
4679 /*timeout*/ timeout ? timeout : 5000);
4682 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4684 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4686 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4688 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4690 cam_fill_ataio(&ccb->ataio,
4691 /*retries*/ retry_count,
4695 /*data_ptr*/ data_ptr,
4696 /*dxfer_len*/ data_bytes,
4697 /*timeout*/ timeout ? timeout : 5000);
4700 if (((retval = cam_send_ccb(device, ccb)) < 0)
4701 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4702 const char warnstr[] = "error sending command";
4709 if (arglist & CAM_ARG_VERBOSE) {
4710 cam_error_print(device, ccb, CAM_ESF_ALL,
4711 CAM_EPF_ALL, stderr);
4715 goto scsicmd_bailout;
4718 if (atacmd_len && need_res) {
4720 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4722 fprintf(stdout, "\n");
4725 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4726 ccb->ataio.res.status,
4727 ccb->ataio.res.error,
4728 ccb->ataio.res.lba_low,
4729 ccb->ataio.res.lba_mid,
4730 ccb->ataio.res.lba_high,
4731 ccb->ataio.res.device,
4732 ccb->ataio.res.lba_low_exp,
4733 ccb->ataio.res.lba_mid_exp,
4734 ccb->ataio.res.lba_high_exp,
4735 ccb->ataio.res.sector_count,
4736 ccb->ataio.res.sector_count_exp);
4742 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4744 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4745 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4746 && (arglist & CAM_ARG_CMD_IN)
4747 && (valid_bytes > 0)) {
4749 buff_decode_visit(data_ptr, valid_bytes, datastr,
4751 fprintf(stdout, "\n");
4753 ssize_t amt_written;
4754 int amt_to_write = valid_bytes;
4755 u_int8_t *buf_ptr = data_ptr;
4757 for (amt_written = 0; (amt_to_write > 0) &&
4758 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4759 amt_to_write -= amt_written;
4760 buf_ptr += amt_written;
4762 if (amt_written == -1) {
4763 warn("error writing data to stdout");
4765 goto scsicmd_bailout;
4766 } else if ((amt_written == 0)
4767 && (amt_to_write > 0)) {
4768 warnx("only wrote %u bytes out of %u",
4769 valid_bytes - amt_to_write, valid_bytes);
4776 if ((data_bytes > 0) && (data_ptr != NULL))
4785 camdebug(int argc, char **argv, char *combinedopt)
4788 path_id_t bus = CAM_BUS_WILDCARD;
4789 target_id_t target = CAM_TARGET_WILDCARD;
4790 lun_id_t lun = CAM_LUN_WILDCARD;
4791 char *tstr, *tmpstr = NULL;
4795 bzero(&ccb, sizeof(union ccb));
4797 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4800 arglist |= CAM_ARG_DEBUG_INFO;
4801 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4804 arglist |= CAM_ARG_DEBUG_PERIPH;
4805 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4808 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4809 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4812 arglist |= CAM_ARG_DEBUG_TRACE;
4813 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4816 arglist |= CAM_ARG_DEBUG_XPT;
4817 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4820 arglist |= CAM_ARG_DEBUG_CDB;
4821 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4824 arglist |= CAM_ARG_DEBUG_PROBE;
4825 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4832 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4833 warnx("error opening transport layer device %s", XPT_DEVICE);
4834 warn("%s", XPT_DEVICE);
4841 warnx("you must specify \"off\", \"all\" or a bus,");
4842 warnx("bus:target, or bus:target:lun");
4849 while (isspace(*tstr) && (*tstr != '\0'))
4852 if (strncmp(tstr, "off", 3) == 0) {
4853 ccb.cdbg.flags = CAM_DEBUG_NONE;
4854 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4855 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4856 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4857 } else if (strncmp(tstr, "all", 3) != 0) {
4858 tmpstr = (char *)strtok(tstr, ":");
4859 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4860 bus = strtol(tmpstr, NULL, 0);
4861 arglist |= CAM_ARG_BUS;
4862 tmpstr = (char *)strtok(NULL, ":");
4863 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4864 target = strtol(tmpstr, NULL, 0);
4865 arglist |= CAM_ARG_TARGET;
4866 tmpstr = (char *)strtok(NULL, ":");
4867 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4868 lun = strtol(tmpstr, NULL, 0);
4869 arglist |= CAM_ARG_LUN;
4874 warnx("you must specify \"all\", \"off\", or a bus,");
4875 warnx("bus:target, or bus:target:lun to debug");
4881 ccb.ccb_h.func_code = XPT_DEBUG;
4882 ccb.ccb_h.path_id = bus;
4883 ccb.ccb_h.target_id = target;
4884 ccb.ccb_h.target_lun = lun;
4886 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4887 warn("CAMIOCOMMAND ioctl failed");
4892 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4893 CAM_FUNC_NOTAVAIL) {
4894 warnx("CAM debugging not available");
4895 warnx("you need to put options CAMDEBUG in"
4896 " your kernel config file!");
4898 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4900 warnx("XPT_DEBUG CCB failed with status %#x",
4904 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4906 "Debugging turned off\n");
4909 "Debugging enabled for "
4911 bus, target, (uintmax_t)lun);
4922 tagcontrol(struct cam_device *device, int argc, char **argv,
4932 ccb = cam_getccb(device);
4935 warnx("tagcontrol: error allocating ccb");
4939 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4942 numtags = strtol(optarg, NULL, 0);
4944 warnx("tag count %d is < 0", numtags);
4946 goto tagcontrol_bailout;
4957 cam_path_string(device, pathstr, sizeof(pathstr));
4960 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
4961 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4962 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4963 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4964 ccb->crs.openings = numtags;
4967 if (cam_send_ccb(device, ccb) < 0) {
4968 perror("error sending XPT_REL_SIMQ CCB");
4970 goto tagcontrol_bailout;
4973 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4974 warnx("XPT_REL_SIMQ CCB failed");
4975 cam_error_print(device, ccb, CAM_ESF_ALL,
4976 CAM_EPF_ALL, stderr);
4978 goto tagcontrol_bailout;
4983 fprintf(stdout, "%stagged openings now %d\n",
4984 pathstr, ccb->crs.openings);
4987 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
4989 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4991 if (cam_send_ccb(device, ccb) < 0) {
4992 perror("error sending XPT_GDEV_STATS CCB");
4994 goto tagcontrol_bailout;
4997 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4998 warnx("XPT_GDEV_STATS CCB failed");
4999 cam_error_print(device, ccb, CAM_ESF_ALL,
5000 CAM_EPF_ALL, stderr);
5002 goto tagcontrol_bailout;
5005 if (arglist & CAM_ARG_VERBOSE) {
5006 fprintf(stdout, "%s", pathstr);
5007 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5008 fprintf(stdout, "%s", pathstr);
5009 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5010 fprintf(stdout, "%s", pathstr);
5011 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5012 fprintf(stdout, "%s", pathstr);
5013 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5014 fprintf(stdout, "%s", pathstr);
5015 fprintf(stdout, "held %d\n", ccb->cgds.held);
5016 fprintf(stdout, "%s", pathstr);
5017 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5018 fprintf(stdout, "%s", pathstr);
5019 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5022 fprintf(stdout, "%s", pathstr);
5023 fprintf(stdout, "device openings: ");
5025 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5026 ccb->cgds.dev_active);
5036 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5040 cam_path_string(device, pathstr, sizeof(pathstr));
5042 if (cts->transport == XPORT_SPI) {
5043 struct ccb_trans_settings_spi *spi =
5044 &cts->xport_specific.spi;
5046 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5048 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5051 if (spi->sync_offset != 0) {
5054 freq = scsi_calc_syncsrate(spi->sync_period);
5055 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5056 pathstr, freq / 1000, freq % 1000);
5060 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5061 fprintf(stdout, "%soffset: %d\n", pathstr,
5065 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5066 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5067 (0x01 << spi->bus_width) * 8);
5070 if (spi->valid & CTS_SPI_VALID_DISC) {
5071 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5072 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5073 "enabled" : "disabled");
5076 if (cts->transport == XPORT_FC) {
5077 struct ccb_trans_settings_fc *fc =
5078 &cts->xport_specific.fc;
5080 if (fc->valid & CTS_FC_VALID_WWNN)
5081 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5082 (long long) fc->wwnn);
5083 if (fc->valid & CTS_FC_VALID_WWPN)
5084 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5085 (long long) fc->wwpn);
5086 if (fc->valid & CTS_FC_VALID_PORT)
5087 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5088 if (fc->valid & CTS_FC_VALID_SPEED)
5089 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5090 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5092 if (cts->transport == XPORT_SAS) {
5093 struct ccb_trans_settings_sas *sas =
5094 &cts->xport_specific.sas;
5096 if (sas->valid & CTS_SAS_VALID_SPEED)
5097 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5098 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5100 if (cts->transport == XPORT_ATA) {
5101 struct ccb_trans_settings_pata *pata =
5102 &cts->xport_specific.ata;
5104 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5105 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5106 ata_mode2string(pata->mode));
5108 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5109 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5112 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5113 fprintf(stdout, "%sPIO transaction length: %d\n",
5114 pathstr, pata->bytecount);
5117 if (cts->transport == XPORT_SATA) {
5118 struct ccb_trans_settings_sata *sata =
5119 &cts->xport_specific.sata;
5121 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5122 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5125 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5126 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5127 ata_mode2string(sata->mode));
5129 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5130 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5133 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5134 fprintf(stdout, "%sPIO transaction length: %d\n",
5135 pathstr, sata->bytecount);
5137 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5138 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5141 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5142 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5145 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5146 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5150 if (cts->protocol == PROTO_ATA) {
5151 struct ccb_trans_settings_ata *ata=
5152 &cts->proto_specific.ata;
5154 if (ata->valid & CTS_ATA_VALID_TQ) {
5155 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5156 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5157 "enabled" : "disabled");
5160 if (cts->protocol == PROTO_SCSI) {
5161 struct ccb_trans_settings_scsi *scsi=
5162 &cts->proto_specific.scsi;
5164 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5165 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5166 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5167 "enabled" : "disabled");
5174 * Get a path inquiry CCB for the specified device.
5177 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5182 ccb = cam_getccb(device);
5184 warnx("get_cpi: couldn't allocate CCB");
5187 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5188 ccb->ccb_h.func_code = XPT_PATH_INQ;
5189 if (cam_send_ccb(device, ccb) < 0) {
5190 warn("get_cpi: error sending Path Inquiry CCB");
5191 if (arglist & CAM_ARG_VERBOSE)
5192 cam_error_print(device, ccb, CAM_ESF_ALL,
5193 CAM_EPF_ALL, stderr);
5195 goto get_cpi_bailout;
5197 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5198 if (arglist & CAM_ARG_VERBOSE)
5199 cam_error_print(device, ccb, CAM_ESF_ALL,
5200 CAM_EPF_ALL, stderr);
5202 goto get_cpi_bailout;
5204 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5212 * Get a get device CCB for the specified device.
5215 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5220 ccb = cam_getccb(device);
5222 warnx("get_cgd: couldn't allocate CCB");
5225 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5226 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5227 if (cam_send_ccb(device, ccb) < 0) {
5228 warn("get_cgd: error sending Path Inquiry CCB");
5229 if (arglist & CAM_ARG_VERBOSE)
5230 cam_error_print(device, ccb, CAM_ESF_ALL,
5231 CAM_EPF_ALL, stderr);
5233 goto get_cgd_bailout;
5235 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5236 if (arglist & CAM_ARG_VERBOSE)
5237 cam_error_print(device, ccb, CAM_ESF_ALL,
5238 CAM_EPF_ALL, stderr);
5240 goto get_cgd_bailout;
5242 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5250 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5254 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5255 int timeout, int verbosemode)
5257 union ccb *ccb = NULL;
5258 struct scsi_vpd_supported_page_list sup_pages;
5262 ccb = cam_getccb(dev);
5264 warn("Unable to allocate CCB");
5269 /* cam_getccb cleans up the header, caller has to zero the payload */
5270 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5272 bzero(&sup_pages, sizeof(sup_pages));
5274 scsi_inquiry(&ccb->csio,
5275 /*retries*/ retry_count,
5277 /* tag_action */ MSG_SIMPLE_Q_TAG,
5278 /* inq_buf */ (u_int8_t *)&sup_pages,
5279 /* inq_len */ sizeof(sup_pages),
5281 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5282 /* sense_len */ SSD_FULL_SIZE,
5283 /* timeout */ timeout ? timeout : 5000);
5285 /* Disable freezing the device queue */
5286 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5288 if (retry_count != 0)
5289 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5291 if (cam_send_ccb(dev, ccb) < 0) {
5298 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5299 if (verbosemode != 0)
5300 cam_error_print(dev, ccb, CAM_ESF_ALL,
5301 CAM_EPF_ALL, stderr);
5306 for (i = 0; i < sup_pages.length; i++) {
5307 if (sup_pages.list[i] == page_id) {
5320 * devtype is filled in with the type of device.
5321 * Returns 0 for success, non-zero for failure.
5324 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5325 int verbosemode, camcontrol_devtype *devtype)
5327 struct ccb_getdev cgd;
5330 retval = get_cgd(dev, &cgd);
5334 switch (cgd.protocol) {
5340 *devtype = CC_DT_ATA;
5342 break; /*NOTREACHED*/
5344 *devtype = CC_DT_UNKNOWN;
5346 break; /*NOTREACHED*/
5350 * Check for the ATA Information VPD page (0x89). If this is an
5351 * ATA device behind a SCSI to ATA translation layer, this VPD page
5352 * should be present.
5354 * If that VPD page isn't present, or we get an error back from the
5355 * INQUIRY command, we'll just treat it as a normal SCSI device.
5357 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5358 timeout, verbosemode);
5360 *devtype = CC_DT_ATA_BEHIND_SCSI;
5362 *devtype = CC_DT_SCSI;
5371 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5372 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5373 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5374 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5375 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5376 int is48bit, camcontrol_devtype devtype)
5380 if (devtype == CC_DT_ATA) {
5381 cam_fill_ataio(&ccb->ataio,
5382 /*retries*/ retry_count,
5385 /*tag_action*/ tag_action,
5386 /*data_ptr*/ data_ptr,
5387 /*dxfer_len*/ dxfer_len,
5388 /*timeout*/ timeout);
5389 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5390 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5393 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5396 if (auxiliary != 0) {
5397 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5398 ccb->ataio.aux = auxiliary;
5401 if (ata_flags & AP_FLAG_CHK_COND)
5402 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5404 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5405 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5406 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5407 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5409 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5410 protocol |= AP_EXTEND;
5412 retval = scsi_ata_pass(&ccb->csio,
5413 /*retries*/ retry_count,
5416 /*tag_action*/ tag_action,
5417 /*protocol*/ protocol,
5418 /*ata_flags*/ ata_flags,
5419 /*features*/ features,
5420 /*sector_count*/ sector_count,
5422 /*command*/ command,
5425 /*auxiliary*/ auxiliary,
5427 /*data_ptr*/ data_ptr,
5428 /*dxfer_len*/ dxfer_len,
5429 /*cdb_storage*/ cdb_storage,
5430 /*cdb_storage_len*/ cdb_storage_len,
5431 /*minimum_cmd_size*/ 0,
5432 /*sense_len*/ sense_len,
5433 /*timeout*/ timeout);
5440 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5441 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5445 switch (ccb->ccb_h.func_code) {
5448 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5451 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5452 * or 16 byte, and need to see what
5454 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5455 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5457 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5458 if ((opcode != ATA_PASS_12)
5459 && (opcode != ATA_PASS_16)) {
5461 warnx("%s: unsupported opcode %02x", __func__, opcode);
5465 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5467 /* Note: the _ccb() variant returns 0 for an error */
5474 switch (error_code) {
5475 case SSD_DESC_CURRENT_ERROR:
5476 case SSD_DESC_DEFERRED_ERROR: {
5477 struct scsi_sense_data_desc *sense;
5478 struct scsi_sense_ata_ret_desc *desc;
5481 sense = (struct scsi_sense_data_desc *)
5482 &ccb->csio.sense_data;
5484 desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len -
5485 ccb->csio.sense_resid, SSD_DESC_ATA);
5486 if (desc_ptr == NULL) {
5487 cam_error_print(dev, ccb, CAM_ESF_ALL,
5488 CAM_EPF_ALL, stderr);
5492 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5494 *error = desc->error;
5495 *count = (desc->count_15_8 << 8) |
5497 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5498 ((uint64_t)desc->lba_39_32 << 32) |
5499 ((uint64_t)desc->lba_31_24 << 24) |
5500 (desc->lba_23_16 << 16) |
5501 (desc->lba_15_8 << 8) |
5503 *device = desc->device;
5504 *status = desc->status;
5507 * If the extend bit isn't set, the result is for a
5508 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5509 * command without the extend bit set. This means
5510 * that the device is supposed to return 28-bit
5511 * status. The count field is only 8 bits, and the
5512 * LBA field is only 8 bits.
5514 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5520 case SSD_CURRENT_ERROR:
5521 case SSD_DEFERRED_ERROR: {
5523 struct scsi_sense_data_fixed *sense;
5526 * XXX KDM need to support fixed sense data.
5528 warnx("%s: Fixed sense data not supported yet",
5532 break; /*NOTREACHED*/
5543 struct ata_res *res;
5546 * In this case, we have an ATA command, and we need to
5547 * fill in the requested values from the result register
5550 res = &ccb->ataio.res;
5551 *error = res->error;
5552 *status = res->status;
5553 *device = res->device;
5554 *count = res->sector_count;
5555 *lba = (res->lba_high << 16) |
5556 (res->lba_mid << 8) |
5558 if (res->flags & CAM_ATAIO_48BIT) {
5559 *count |= (res->sector_count_exp << 8);
5560 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5561 ((uint64_t)res->lba_mid_exp << 32) |
5562 ((uint64_t)res->lba_high_exp << 40);
5564 *lba |= (res->device & 0xf) << 24;
5577 cpi_print(struct ccb_pathinq *cpi)
5579 char adapter_str[1024];
5582 snprintf(adapter_str, sizeof(adapter_str),
5583 "%s%d:", cpi->dev_name, cpi->unit_number);
5585 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5588 for (i = 1; i < UINT8_MAX; i = i << 1) {
5591 if ((i & cpi->hba_inquiry) == 0)
5594 fprintf(stdout, "%s supports ", adapter_str);
5598 str = "MDP message";
5601 str = "32 bit wide SCSI";
5604 str = "16 bit wide SCSI";
5607 str = "SDTR message";
5610 str = "linked CDBs";
5613 str = "tag queue messages";
5616 str = "soft reset alternative";
5619 str = "SATA Port Multiplier";
5622 str = "unknown PI bit set";
5625 fprintf(stdout, "%s\n", str);
5628 for (i = 1; i < UINT32_MAX; i = i << 1) {
5631 if ((i & cpi->hba_misc) == 0)
5634 fprintf(stdout, "%s ", adapter_str);
5638 str = "can understand ata_ext requests";
5641 str = "64bit extended LUNs supported";
5644 str = "bus scans from high ID to low ID";
5647 str = "removable devices not included in scan";
5649 case PIM_NOINITIATOR:
5650 str = "initiator role not supported";
5652 case PIM_NOBUSRESET:
5653 str = "user has disabled initial BUS RESET or"
5654 " controller is in target/mixed mode";
5657 str = "do not send 6-byte commands";
5660 str = "scan bus sequentially";
5663 str = "unmapped I/O supported";
5666 str = "does its own scanning";
5669 str = "unknown PIM bit set";
5672 fprintf(stdout, "%s\n", str);
5675 for (i = 1; i < UINT16_MAX; i = i << 1) {
5678 if ((i & cpi->target_sprt) == 0)
5681 fprintf(stdout, "%s supports ", adapter_str);
5684 str = "target mode processor mode";
5687 str = "target mode phase cog. mode";
5689 case PIT_DISCONNECT:
5690 str = "disconnects in target mode";
5693 str = "terminate I/O message in target mode";
5696 str = "group 6 commands in target mode";
5699 str = "group 7 commands in target mode";
5702 str = "unknown PIT bit set";
5706 fprintf(stdout, "%s\n", str);
5708 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5710 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5712 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5714 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5715 adapter_str, cpi->hpath_id);
5716 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5718 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5719 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5720 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5721 adapter_str, cpi->hba_vendor);
5722 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5723 adapter_str, cpi->hba_device);
5724 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5725 adapter_str, cpi->hba_subvendor);
5726 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5727 adapter_str, cpi->hba_subdevice);
5728 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5729 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5730 if (cpi->base_transfer_speed > 1000)
5731 fprintf(stdout, "%d.%03dMB/sec\n",
5732 cpi->base_transfer_speed / 1000,
5733 cpi->base_transfer_speed % 1000);
5735 fprintf(stdout, "%dKB/sec\n",
5736 (cpi->base_transfer_speed % 1000) * 1000);
5737 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5738 adapter_str, cpi->maxio);
5742 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5743 struct ccb_trans_settings *cts)
5749 ccb = cam_getccb(device);
5752 warnx("get_print_cts: error allocating ccb");
5756 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5758 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5760 if (user_settings == 0)
5761 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5763 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5765 if (cam_send_ccb(device, ccb) < 0) {
5766 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5767 if (arglist & CAM_ARG_VERBOSE)
5768 cam_error_print(device, ccb, CAM_ESF_ALL,
5769 CAM_EPF_ALL, stderr);
5771 goto get_print_cts_bailout;
5774 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5775 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5776 if (arglist & CAM_ARG_VERBOSE)
5777 cam_error_print(device, ccb, CAM_ESF_ALL,
5778 CAM_EPF_ALL, stderr);
5780 goto get_print_cts_bailout;
5784 cts_print(device, &ccb->cts);
5787 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5789 get_print_cts_bailout:
5797 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
5798 int timeout, int argc, char **argv, char *combinedopt)
5802 int user_settings = 0;
5804 int disc_enable = -1, tag_enable = -1;
5807 double syncrate = -1;
5810 int change_settings = 0, send_tur = 0;
5811 struct ccb_pathinq cpi;
5813 ccb = cam_getccb(device);
5815 warnx("ratecontrol: error allocating ccb");
5818 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5827 if (strncasecmp(optarg, "enable", 6) == 0)
5829 else if (strncasecmp(optarg, "disable", 7) == 0)
5832 warnx("-D argument \"%s\" is unknown", optarg);
5834 goto ratecontrol_bailout;
5836 change_settings = 1;
5839 mode = ata_string2mode(optarg);
5841 warnx("unknown mode '%s'", optarg);
5843 goto ratecontrol_bailout;
5845 change_settings = 1;
5848 offset = strtol(optarg, NULL, 0);
5850 warnx("offset value %d is < 0", offset);
5852 goto ratecontrol_bailout;
5854 change_settings = 1;
5860 syncrate = atof(optarg);
5862 warnx("sync rate %f is < 0", syncrate);
5864 goto ratecontrol_bailout;
5866 change_settings = 1;
5869 if (strncasecmp(optarg, "enable", 6) == 0)
5871 else if (strncasecmp(optarg, "disable", 7) == 0)
5874 warnx("-T argument \"%s\" is unknown", optarg);
5876 goto ratecontrol_bailout;
5878 change_settings = 1;
5884 bus_width = strtol(optarg, NULL, 0);
5885 if (bus_width < 0) {
5886 warnx("bus width %d is < 0", bus_width);
5888 goto ratecontrol_bailout;
5890 change_settings = 1;
5896 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5898 * Grab path inquiry information, so we can determine whether
5899 * or not the initiator is capable of the things that the user
5902 ccb->ccb_h.func_code = XPT_PATH_INQ;
5903 if (cam_send_ccb(device, ccb) < 0) {
5904 perror("error sending XPT_PATH_INQ CCB");
5905 if (arglist & CAM_ARG_VERBOSE) {
5906 cam_error_print(device, ccb, CAM_ESF_ALL,
5907 CAM_EPF_ALL, stderr);
5910 goto ratecontrol_bailout;
5912 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5913 warnx("XPT_PATH_INQ CCB failed");
5914 if (arglist & CAM_ARG_VERBOSE) {
5915 cam_error_print(device, ccb, CAM_ESF_ALL,
5916 CAM_EPF_ALL, stderr);
5919 goto ratecontrol_bailout;
5921 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5922 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5924 fprintf(stdout, "%s parameters:\n",
5925 user_settings ? "User" : "Current");
5927 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5929 goto ratecontrol_bailout;
5931 if (arglist & CAM_ARG_VERBOSE)
5934 if (change_settings) {
5935 int didsettings = 0;
5936 struct ccb_trans_settings_spi *spi = NULL;
5937 struct ccb_trans_settings_pata *pata = NULL;
5938 struct ccb_trans_settings_sata *sata = NULL;
5939 struct ccb_trans_settings_ata *ata = NULL;
5940 struct ccb_trans_settings_scsi *scsi = NULL;
5942 if (ccb->cts.transport == XPORT_SPI)
5943 spi = &ccb->cts.xport_specific.spi;
5944 if (ccb->cts.transport == XPORT_ATA)
5945 pata = &ccb->cts.xport_specific.ata;
5946 if (ccb->cts.transport == XPORT_SATA)
5947 sata = &ccb->cts.xport_specific.sata;
5948 if (ccb->cts.protocol == PROTO_ATA)
5949 ata = &ccb->cts.proto_specific.ata;
5950 if (ccb->cts.protocol == PROTO_SCSI)
5951 scsi = &ccb->cts.proto_specific.scsi;
5952 ccb->cts.xport_specific.valid = 0;
5953 ccb->cts.proto_specific.valid = 0;
5954 if (spi && disc_enable != -1) {
5955 spi->valid |= CTS_SPI_VALID_DISC;
5956 if (disc_enable == 0)
5957 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5959 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5962 if (tag_enable != -1) {
5963 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5964 warnx("HBA does not support tagged queueing, "
5965 "so you cannot modify tag settings");
5967 goto ratecontrol_bailout;
5970 ata->valid |= CTS_SCSI_VALID_TQ;
5971 if (tag_enable == 0)
5972 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5974 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5977 scsi->valid |= CTS_SCSI_VALID_TQ;
5978 if (tag_enable == 0)
5979 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5981 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5985 if (spi && offset != -1) {
5986 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5987 warnx("HBA is not capable of changing offset");
5989 goto ratecontrol_bailout;
5991 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5992 spi->sync_offset = offset;
5995 if (spi && syncrate != -1) {
5996 int prelim_sync_period;
5998 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5999 warnx("HBA is not capable of changing "
6002 goto ratecontrol_bailout;
6004 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6006 * The sync rate the user gives us is in MHz.
6007 * We need to translate it into KHz for this
6012 * Next, we calculate a "preliminary" sync period
6013 * in tenths of a nanosecond.
6016 prelim_sync_period = 0;
6018 prelim_sync_period = 10000000 / syncrate;
6020 scsi_calc_syncparam(prelim_sync_period);
6023 if (sata && syncrate != -1) {
6024 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6025 warnx("HBA is not capable of changing "
6028 goto ratecontrol_bailout;
6030 if (!user_settings) {
6031 warnx("You can modify only user rate "
6032 "settings for SATA");
6034 goto ratecontrol_bailout;
6036 sata->revision = ata_speed2revision(syncrate * 100);
6037 if (sata->revision < 0) {
6038 warnx("Invalid rate %f", syncrate);
6040 goto ratecontrol_bailout;
6042 sata->valid |= CTS_SATA_VALID_REVISION;
6045 if ((pata || sata) && mode != -1) {
6046 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6047 warnx("HBA is not capable of changing "
6050 goto ratecontrol_bailout;
6052 if (!user_settings) {
6053 warnx("You can modify only user mode "
6054 "settings for ATA/SATA");
6056 goto ratecontrol_bailout;
6060 pata->valid |= CTS_ATA_VALID_MODE;
6063 sata->valid |= CTS_SATA_VALID_MODE;
6068 * The bus_width argument goes like this:
6072 * Therefore, if you shift the number of bits given on the
6073 * command line right by 4, you should get the correct
6076 if (spi && bus_width != -1) {
6078 * We might as well validate things here with a
6079 * decipherable error message, rather than what
6080 * will probably be an indecipherable error message
6081 * by the time it gets back to us.
6083 if ((bus_width == 16)
6084 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6085 warnx("HBA does not support 16 bit bus width");
6087 goto ratecontrol_bailout;
6088 } else if ((bus_width == 32)
6089 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6090 warnx("HBA does not support 32 bit bus width");
6092 goto ratecontrol_bailout;
6093 } else if ((bus_width != 8)
6094 && (bus_width != 16)
6095 && (bus_width != 32)) {
6096 warnx("Invalid bus width %d", bus_width);
6098 goto ratecontrol_bailout;
6100 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6101 spi->bus_width = bus_width >> 4;
6104 if (didsettings == 0) {
6105 goto ratecontrol_bailout;
6107 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6108 if (cam_send_ccb(device, ccb) < 0) {
6109 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
6110 if (arglist & CAM_ARG_VERBOSE) {
6111 cam_error_print(device, ccb, CAM_ESF_ALL,
6112 CAM_EPF_ALL, stderr);
6115 goto ratecontrol_bailout;
6117 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6118 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6119 if (arglist & CAM_ARG_VERBOSE) {
6120 cam_error_print(device, ccb, CAM_ESF_ALL,
6121 CAM_EPF_ALL, stderr);
6124 goto ratecontrol_bailout;
6128 retval = testunitready(device, task_attr, retry_count, timeout,
6129 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6131 * If the TUR didn't succeed, just bail.
6135 fprintf(stderr, "Test Unit Ready failed\n");
6136 goto ratecontrol_bailout;
6139 if ((change_settings || send_tur) && !quiet &&
6140 (ccb->cts.transport == XPORT_ATA ||
6141 ccb->cts.transport == XPORT_SATA || send_tur)) {
6142 fprintf(stdout, "New parameters:\n");
6143 retval = get_print_cts(device, user_settings, 0, NULL);
6146 ratecontrol_bailout:
6152 scsiformat(struct cam_device *device, int argc, char **argv,
6153 char *combinedopt, int task_attr, int retry_count, int timeout)
6157 int ycount = 0, quiet = 0;
6158 int error = 0, retval = 0;
6159 int use_timeout = 10800 * 1000;
6161 struct format_defect_list_header fh;
6162 u_int8_t *data_ptr = NULL;
6163 u_int32_t dxfer_len = 0;
6165 int num_warnings = 0;
6168 ccb = cam_getccb(device);
6171 warnx("scsiformat: error allocating ccb");
6175 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6177 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6198 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6199 "following device:\n");
6201 error = scsidoinquiry(device, argc, argv, combinedopt,
6202 task_attr, retry_count, timeout);
6205 warnx("scsiformat: error sending inquiry");
6206 goto scsiformat_bailout;
6211 if (!get_confirmation()) {
6213 goto scsiformat_bailout;
6218 use_timeout = timeout;
6221 fprintf(stdout, "Current format timeout is %d seconds\n",
6222 use_timeout / 1000);
6226 * If the user hasn't disabled questions and didn't specify a
6227 * timeout on the command line, ask them if they want the current
6231 && (timeout == 0)) {
6233 int new_timeout = 0;
6235 fprintf(stdout, "Enter new timeout in seconds or press\n"
6236 "return to keep the current timeout [%d] ",
6237 use_timeout / 1000);
6239 if (fgets(str, sizeof(str), stdin) != NULL) {
6241 new_timeout = atoi(str);
6244 if (new_timeout != 0) {
6245 use_timeout = new_timeout * 1000;
6246 fprintf(stdout, "Using new timeout value %d\n",
6247 use_timeout / 1000);
6252 * Keep this outside the if block below to silence any unused
6253 * variable warnings.
6255 bzero(&fh, sizeof(fh));
6258 * If we're in immediate mode, we've got to include the format
6261 if (immediate != 0) {
6262 fh.byte2 = FU_DLH_IMMED;
6263 data_ptr = (u_int8_t *)&fh;
6264 dxfer_len = sizeof(fh);
6265 byte2 = FU_FMT_DATA;
6266 } else if (quiet == 0) {
6267 fprintf(stdout, "Formatting...");
6271 scsi_format_unit(&ccb->csio,
6272 /* retries */ retry_count,
6274 /* tag_action */ task_attr,
6277 /* data_ptr */ data_ptr,
6278 /* dxfer_len */ dxfer_len,
6279 /* sense_len */ SSD_FULL_SIZE,
6280 /* timeout */ use_timeout);
6282 /* Disable freezing the device queue */
6283 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6285 if (arglist & CAM_ARG_ERR_RECOVER)
6286 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6288 if (((retval = cam_send_ccb(device, ccb)) < 0)
6289 || ((immediate == 0)
6290 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6291 const char errstr[] = "error sending format command";
6298 if (arglist & CAM_ARG_VERBOSE) {
6299 cam_error_print(device, ccb, CAM_ESF_ALL,
6300 CAM_EPF_ALL, stderr);
6303 goto scsiformat_bailout;
6307 * If we ran in non-immediate mode, we already checked for errors
6308 * above and printed out any necessary information. If we're in
6309 * immediate mode, we need to loop through and get status
6310 * information periodically.
6312 if (immediate == 0) {
6314 fprintf(stdout, "Format Complete\n");
6316 goto scsiformat_bailout;
6323 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6326 * There's really no need to do error recovery or
6327 * retries here, since we're just going to sit in a
6328 * loop and wait for the device to finish formatting.
6330 scsi_test_unit_ready(&ccb->csio,
6333 /* tag_action */ task_attr,
6334 /* sense_len */ SSD_FULL_SIZE,
6335 /* timeout */ 5000);
6337 /* Disable freezing the device queue */
6338 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6340 retval = cam_send_ccb(device, ccb);
6343 * If we get an error from the ioctl, bail out. SCSI
6344 * errors are expected.
6347 warn("error sending CAMIOCOMMAND ioctl");
6348 if (arglist & CAM_ARG_VERBOSE) {
6349 cam_error_print(device, ccb, CAM_ESF_ALL,
6350 CAM_EPF_ALL, stderr);
6353 goto scsiformat_bailout;
6356 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6358 if ((status != CAM_REQ_CMP)
6359 && (status == CAM_SCSI_STATUS_ERROR)
6360 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6361 struct scsi_sense_data *sense;
6362 int error_code, sense_key, asc, ascq;
6364 sense = &ccb->csio.sense_data;
6365 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6366 ccb->csio.sense_resid, &error_code, &sense_key,
6367 &asc, &ascq, /*show_errors*/ 1);
6370 * According to the SCSI-2 and SCSI-3 specs, a
6371 * drive that is in the middle of a format should
6372 * return NOT READY with an ASC of "logical unit
6373 * not ready, format in progress". The sense key
6374 * specific bytes will then be a progress indicator.
6376 if ((sense_key == SSD_KEY_NOT_READY)
6377 && (asc == 0x04) && (ascq == 0x04)) {
6380 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6381 ccb->csio.sense_resid, sks) == 0)
6384 u_int64_t percentage;
6386 val = scsi_2btoul(&sks[1]);
6387 percentage = 10000ull * val;
6390 "\rFormatting: %ju.%02u %% "
6392 (uintmax_t)(percentage /
6394 (unsigned)((percentage /
6398 } else if ((quiet == 0)
6399 && (++num_warnings <= 1)) {
6400 warnx("Unexpected SCSI Sense Key "
6401 "Specific value returned "
6403 scsi_sense_print(device, &ccb->csio,
6405 warnx("Unable to print status "
6406 "information, but format will "
6408 warnx("will exit when format is "
6413 warnx("Unexpected SCSI error during format");
6414 cam_error_print(device, ccb, CAM_ESF_ALL,
6415 CAM_EPF_ALL, stderr);
6417 goto scsiformat_bailout;
6420 } else if (status != CAM_REQ_CMP) {
6421 warnx("Unexpected CAM status %#x", status);
6422 if (arglist & CAM_ARG_VERBOSE)
6423 cam_error_print(device, ccb, CAM_ESF_ALL,
6424 CAM_EPF_ALL, stderr);
6426 goto scsiformat_bailout;
6429 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6432 fprintf(stdout, "\nFormat Complete\n");
6442 scsisanitize(struct cam_device *device, int argc, char **argv,
6443 char *combinedopt, int task_attr, int retry_count, int timeout)
6446 u_int8_t action = 0;
6448 int ycount = 0, quiet = 0;
6449 int error = 0, retval = 0;
6450 int use_timeout = 10800 * 1000;
6456 const char *pattern = NULL;
6457 u_int8_t *data_ptr = NULL;
6458 u_int32_t dxfer_len = 0;
6460 int num_warnings = 0;
6463 ccb = cam_getccb(device);
6466 warnx("scsisanitize: error allocating ccb");
6470 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6472 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6475 if (strcasecmp(optarg, "overwrite") == 0)
6476 action = SSZ_SERVICE_ACTION_OVERWRITE;
6477 else if (strcasecmp(optarg, "block") == 0)
6478 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6479 else if (strcasecmp(optarg, "crypto") == 0)
6480 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6481 else if (strcasecmp(optarg, "exitfailure") == 0)
6482 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6484 warnx("invalid service operation \"%s\"",
6487 goto scsisanitize_bailout;
6491 passes = strtol(optarg, NULL, 0);
6492 if (passes < 1 || passes > 31) {
6493 warnx("invalid passes value %d", passes);
6495 goto scsisanitize_bailout;
6526 warnx("an action is required");
6528 goto scsisanitize_bailout;
6529 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6530 struct scsi_sanitize_parameter_list *pl;
6534 if (pattern == NULL) {
6535 warnx("overwrite action requires -P argument");
6537 goto scsisanitize_bailout;
6539 fd = open(pattern, O_RDONLY);
6541 warn("cannot open pattern file %s", pattern);
6543 goto scsisanitize_bailout;
6545 if (fstat(fd, &sb) < 0) {
6546 warn("cannot stat pattern file %s", pattern);
6548 goto scsisanitize_bailout;
6551 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6552 warnx("pattern file size exceeds maximum value %d",
6553 SSZPL_MAX_PATTERN_LENGTH);
6555 goto scsisanitize_bailout;
6557 dxfer_len = sizeof(*pl) + sz;
6558 data_ptr = calloc(1, dxfer_len);
6559 if (data_ptr == NULL) {
6560 warnx("cannot allocate parameter list buffer");
6562 goto scsisanitize_bailout;
6565 amt = read(fd, data_ptr + sizeof(*pl), sz);
6567 warn("cannot read pattern file");
6569 goto scsisanitize_bailout;
6570 } else if (amt != sz) {
6571 warnx("short pattern file read");
6573 goto scsisanitize_bailout;
6576 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6582 pl->byte1 |= SSZPL_INVERT;
6583 scsi_ulto2b(sz, pl->length);
6589 else if (invert != 0)
6591 else if (pattern != NULL)
6596 warnx("%s argument only valid with overwrite "
6599 goto scsisanitize_bailout;
6604 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6605 "following device:\n");
6607 error = scsidoinquiry(device, argc, argv, combinedopt,
6608 task_attr, retry_count, timeout);
6611 warnx("scsisanitize: error sending inquiry");
6612 goto scsisanitize_bailout;
6617 if (!get_confirmation()) {
6619 goto scsisanitize_bailout;
6624 use_timeout = timeout;
6627 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6628 use_timeout / 1000);
6632 * If the user hasn't disabled questions and didn't specify a
6633 * timeout on the command line, ask them if they want the current
6637 && (timeout == 0)) {
6639 int new_timeout = 0;
6641 fprintf(stdout, "Enter new timeout in seconds or press\n"
6642 "return to keep the current timeout [%d] ",
6643 use_timeout / 1000);
6645 if (fgets(str, sizeof(str), stdin) != NULL) {
6647 new_timeout = atoi(str);
6650 if (new_timeout != 0) {
6651 use_timeout = new_timeout * 1000;
6652 fprintf(stdout, "Using new timeout value %d\n",
6653 use_timeout / 1000);
6659 byte2 |= SSZ_UNRESTRICTED_EXIT;
6663 scsi_sanitize(&ccb->csio,
6664 /* retries */ retry_count,
6666 /* tag_action */ task_attr,
6669 /* data_ptr */ data_ptr,
6670 /* dxfer_len */ dxfer_len,
6671 /* sense_len */ SSD_FULL_SIZE,
6672 /* timeout */ use_timeout);
6674 /* Disable freezing the device queue */
6675 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6677 if (arglist & CAM_ARG_ERR_RECOVER)
6678 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6680 if (cam_send_ccb(device, ccb) < 0) {
6681 warn("error sending sanitize command");
6683 goto scsisanitize_bailout;
6686 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6687 struct scsi_sense_data *sense;
6688 int error_code, sense_key, asc, ascq;
6690 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6691 CAM_SCSI_STATUS_ERROR) {
6692 sense = &ccb->csio.sense_data;
6693 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6694 ccb->csio.sense_resid, &error_code, &sense_key,
6695 &asc, &ascq, /*show_errors*/ 1);
6697 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6698 asc == 0x20 && ascq == 0x00)
6699 warnx("sanitize is not supported by "
6702 warnx("error sanitizing this device");
6704 warnx("error sanitizing this device");
6706 if (arglist & CAM_ARG_VERBOSE) {
6707 cam_error_print(device, ccb, CAM_ESF_ALL,
6708 CAM_EPF_ALL, stderr);
6711 goto scsisanitize_bailout;
6715 * If we ran in non-immediate mode, we already checked for errors
6716 * above and printed out any necessary information. If we're in
6717 * immediate mode, we need to loop through and get status
6718 * information periodically.
6720 if (immediate == 0) {
6722 fprintf(stdout, "Sanitize Complete\n");
6724 goto scsisanitize_bailout;
6731 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6734 * There's really no need to do error recovery or
6735 * retries here, since we're just going to sit in a
6736 * loop and wait for the device to finish sanitizing.
6738 scsi_test_unit_ready(&ccb->csio,
6741 /* tag_action */ task_attr,
6742 /* sense_len */ SSD_FULL_SIZE,
6743 /* timeout */ 5000);
6745 /* Disable freezing the device queue */
6746 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6748 retval = cam_send_ccb(device, ccb);
6751 * If we get an error from the ioctl, bail out. SCSI
6752 * errors are expected.
6755 warn("error sending CAMIOCOMMAND ioctl");
6756 if (arglist & CAM_ARG_VERBOSE) {
6757 cam_error_print(device, ccb, CAM_ESF_ALL,
6758 CAM_EPF_ALL, stderr);
6761 goto scsisanitize_bailout;
6764 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6766 if ((status != CAM_REQ_CMP)
6767 && (status == CAM_SCSI_STATUS_ERROR)
6768 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6769 struct scsi_sense_data *sense;
6770 int error_code, sense_key, asc, ascq;
6772 sense = &ccb->csio.sense_data;
6773 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6774 ccb->csio.sense_resid, &error_code, &sense_key,
6775 &asc, &ascq, /*show_errors*/ 1);
6778 * According to the SCSI-3 spec, a drive that is in the
6779 * middle of a sanitize should return NOT READY with an
6780 * ASC of "logical unit not ready, sanitize in
6781 * progress". The sense key specific bytes will then
6782 * be a progress indicator.
6784 if ((sense_key == SSD_KEY_NOT_READY)
6785 && (asc == 0x04) && (ascq == 0x1b)) {
6788 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6789 ccb->csio.sense_resid, sks) == 0)
6792 u_int64_t percentage;
6794 val = scsi_2btoul(&sks[1]);
6795 percentage = 10000 * val;
6798 "\rSanitizing: %ju.%02u %% "
6800 (uintmax_t)(percentage /
6802 (unsigned)((percentage /
6806 } else if ((quiet == 0)
6807 && (++num_warnings <= 1)) {
6808 warnx("Unexpected SCSI Sense Key "
6809 "Specific value returned "
6810 "during sanitize:");
6811 scsi_sense_print(device, &ccb->csio,
6813 warnx("Unable to print status "
6814 "information, but sanitze will "
6816 warnx("will exit when sanitize is "
6821 warnx("Unexpected SCSI error during sanitize");
6822 cam_error_print(device, ccb, CAM_ESF_ALL,
6823 CAM_EPF_ALL, stderr);
6825 goto scsisanitize_bailout;
6828 } else if (status != CAM_REQ_CMP) {
6829 warnx("Unexpected CAM status %#x", status);
6830 if (arglist & CAM_ARG_VERBOSE)
6831 cam_error_print(device, ccb, CAM_ESF_ALL,
6832 CAM_EPF_ALL, stderr);
6834 goto scsisanitize_bailout;
6836 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6839 fprintf(stdout, "\nSanitize Complete\n");
6841 scsisanitize_bailout:
6844 if (data_ptr != NULL)
6852 scsireportluns(struct cam_device *device, int argc, char **argv,
6853 char *combinedopt, int task_attr, int retry_count, int timeout)
6856 int c, countonly, lunsonly;
6857 struct scsi_report_luns_data *lundata;
6859 uint8_t report_type;
6860 uint32_t list_len, i, j;
6865 report_type = RPL_REPORT_DEFAULT;
6866 ccb = cam_getccb(device);
6869 warnx("%s: error allocating ccb", __func__);
6873 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6878 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6887 if (strcasecmp(optarg, "default") == 0)
6888 report_type = RPL_REPORT_DEFAULT;
6889 else if (strcasecmp(optarg, "wellknown") == 0)
6890 report_type = RPL_REPORT_WELLKNOWN;
6891 else if (strcasecmp(optarg, "all") == 0)
6892 report_type = RPL_REPORT_ALL;
6894 warnx("%s: invalid report type \"%s\"",
6905 if ((countonly != 0)
6906 && (lunsonly != 0)) {
6907 warnx("%s: you can only specify one of -c or -l", __func__);
6912 * According to SPC-4, the allocation length must be at least 16
6913 * bytes -- enough for the header and one LUN.
6915 alloc_len = sizeof(*lundata) + 8;
6919 lundata = malloc(alloc_len);
6921 if (lundata == NULL) {
6922 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6927 scsi_report_luns(&ccb->csio,
6928 /*retries*/ retry_count,
6930 /*tag_action*/ task_attr,
6931 /*select_report*/ report_type,
6932 /*rpl_buf*/ lundata,
6933 /*alloc_len*/ alloc_len,
6934 /*sense_len*/ SSD_FULL_SIZE,
6935 /*timeout*/ timeout ? timeout : 5000);
6937 /* Disable freezing the device queue */
6938 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6940 if (arglist & CAM_ARG_ERR_RECOVER)
6941 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6943 if (cam_send_ccb(device, ccb) < 0) {
6944 warn("error sending REPORT LUNS command");
6946 if (arglist & CAM_ARG_VERBOSE)
6947 cam_error_print(device, ccb, CAM_ESF_ALL,
6948 CAM_EPF_ALL, stderr);
6954 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6955 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6961 list_len = scsi_4btoul(lundata->length);
6964 * If we need to list the LUNs, and our allocation
6965 * length was too short, reallocate and retry.
6967 if ((countonly == 0)
6968 && (list_len > (alloc_len - sizeof(*lundata)))) {
6969 alloc_len = list_len + sizeof(*lundata);
6975 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6976 ((list_len / 8) > 1) ? "s" : "");
6981 for (i = 0; i < (list_len / 8); i++) {
6985 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6987 fprintf(stdout, ",");
6988 switch (lundata->luns[i].lundata[j] &
6989 RPL_LUNDATA_ATYP_MASK) {
6990 case RPL_LUNDATA_ATYP_PERIPH:
6991 if ((lundata->luns[i].lundata[j] &
6992 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6993 fprintf(stdout, "%d:",
6994 lundata->luns[i].lundata[j] &
6995 RPL_LUNDATA_PERIPH_BUS_MASK);
6997 && ((lundata->luns[i].lundata[j+2] &
6998 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7001 fprintf(stdout, "%d",
7002 lundata->luns[i].lundata[j+1]);
7004 case RPL_LUNDATA_ATYP_FLAT: {
7006 tmplun[0] = lundata->luns[i].lundata[j] &
7007 RPL_LUNDATA_FLAT_LUN_MASK;
7008 tmplun[1] = lundata->luns[i].lundata[j+1];
7010 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7014 case RPL_LUNDATA_ATYP_LUN:
7015 fprintf(stdout, "%d:%d:%d",
7016 (lundata->luns[i].lundata[j+1] &
7017 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7018 lundata->luns[i].lundata[j] &
7019 RPL_LUNDATA_LUN_TARG_MASK,
7020 lundata->luns[i].lundata[j+1] &
7021 RPL_LUNDATA_LUN_LUN_MASK);
7023 case RPL_LUNDATA_ATYP_EXTLUN: {
7024 int field_len_code, eam_code;
7026 eam_code = lundata->luns[i].lundata[j] &
7027 RPL_LUNDATA_EXT_EAM_MASK;
7028 field_len_code = (lundata->luns[i].lundata[j] &
7029 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7031 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7032 && (field_len_code == 0x00)) {
7033 fprintf(stdout, "%d",
7034 lundata->luns[i].lundata[j+1]);
7035 } else if ((eam_code ==
7036 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7037 && (field_len_code == 0x03)) {
7041 * This format takes up all 8 bytes.
7042 * If we aren't starting at offset 0,
7046 fprintf(stdout, "Invalid "
7049 "specified format", j);
7053 bzero(tmp_lun, sizeof(tmp_lun));
7054 bcopy(&lundata->luns[i].lundata[j+1],
7055 &tmp_lun[1], sizeof(tmp_lun) - 1);
7056 fprintf(stdout, "%#jx",
7057 (intmax_t)scsi_8btou64(tmp_lun));
7060 fprintf(stderr, "Unknown Extended LUN"
7061 "Address method %#x, length "
7062 "code %#x", eam_code,
7069 fprintf(stderr, "Unknown LUN address method "
7070 "%#x\n", lundata->luns[i].lundata[0] &
7071 RPL_LUNDATA_ATYP_MASK);
7075 * For the flat addressing method, there are no
7076 * other levels after it.
7081 fprintf(stdout, "\n");
7094 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7095 char *combinedopt, int task_attr, int retry_count, int timeout)
7098 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
7099 struct scsi_read_capacity_data rcap;
7100 struct scsi_read_capacity_data_long rcaplong;
7114 ccb = cam_getccb(device);
7117 warnx("%s: error allocating ccb", __func__);
7121 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7123 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7150 if ((blocksizeonly != 0)
7151 && (numblocks != 0)) {
7152 warnx("%s: you can only specify one of -b or -N", __func__);
7157 if ((blocksizeonly != 0)
7158 && (sizeonly != 0)) {
7159 warnx("%s: you can only specify one of -b or -s", __func__);
7166 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7172 && (blocksizeonly != 0)) {
7173 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7178 scsi_read_capacity(&ccb->csio,
7179 /*retries*/ retry_count,
7181 /*tag_action*/ task_attr,
7184 /*timeout*/ timeout ? timeout : 5000);
7186 /* Disable freezing the device queue */
7187 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7189 if (arglist & CAM_ARG_ERR_RECOVER)
7190 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7192 if (cam_send_ccb(device, ccb) < 0) {
7193 warn("error sending READ CAPACITY command");
7195 if (arglist & CAM_ARG_VERBOSE)
7196 cam_error_print(device, ccb, CAM_ESF_ALL,
7197 CAM_EPF_ALL, stderr);
7203 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7204 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7209 maxsector = scsi_4btoul(rcap.addr);
7210 block_len = scsi_4btoul(rcap.length);
7213 * A last block of 2^32-1 means that the true capacity is over 2TB,
7214 * and we need to issue the long READ CAPACITY to get the real
7215 * capacity. Otherwise, we're all set.
7217 if (maxsector != 0xffffffff)
7220 scsi_read_capacity_16(&ccb->csio,
7221 /*retries*/ retry_count,
7223 /*tag_action*/ task_attr,
7227 /*rcap_buf*/ (uint8_t *)&rcaplong,
7228 /*rcap_buf_len*/ sizeof(rcaplong),
7229 /*sense_len*/ SSD_FULL_SIZE,
7230 /*timeout*/ timeout ? timeout : 5000);
7232 /* Disable freezing the device queue */
7233 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7235 if (arglist & CAM_ARG_ERR_RECOVER)
7236 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7238 if (cam_send_ccb(device, ccb) < 0) {
7239 warn("error sending READ CAPACITY (16) command");
7241 if (arglist & CAM_ARG_VERBOSE)
7242 cam_error_print(device, ccb, CAM_ESF_ALL,
7243 CAM_EPF_ALL, stderr);
7249 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7250 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7255 maxsector = scsi_8btou64(rcaplong.addr);
7256 block_len = scsi_4btoul(rcaplong.length);
7259 if (blocksizeonly == 0) {
7261 * Humanize implies !quiet, and also implies numblocks.
7263 if (humanize != 0) {
7268 tmpbytes = (maxsector + 1) * block_len;
7269 ret = humanize_number(tmpstr, sizeof(tmpstr),
7270 tmpbytes, "", HN_AUTOSCALE,
7273 HN_DIVISOR_1000 : 0));
7275 warnx("%s: humanize_number failed!", __func__);
7279 fprintf(stdout, "Device Size: %s%s", tmpstr,
7280 (sizeonly == 0) ? ", " : "\n");
7281 } else if (numblocks != 0) {
7282 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7283 "Blocks: " : "", (uintmax_t)maxsector + 1,
7284 (sizeonly == 0) ? ", " : "\n");
7286 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7287 "Last Block: " : "", (uintmax_t)maxsector,
7288 (sizeonly == 0) ? ", " : "\n");
7292 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7293 "Block Length: " : "", block_len, (quiet == 0) ?
7302 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7303 int retry_count, int timeout)
7307 uint8_t *smp_request = NULL, *smp_response = NULL;
7308 int request_size = 0, response_size = 0;
7309 int fd_request = 0, fd_response = 0;
7310 char *datastr = NULL;
7311 struct get_hook hook;
7316 * Note that at the moment we don't support sending SMP CCBs to
7317 * devices that aren't probed by CAM.
7319 ccb = cam_getccb(device);
7321 warnx("%s: error allocating CCB", __func__);
7325 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7327 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7330 arglist |= CAM_ARG_CMD_IN;
7331 response_size = strtol(optarg, NULL, 0);
7332 if (response_size <= 0) {
7333 warnx("invalid number of response bytes %d",
7336 goto smpcmd_bailout;
7338 hook.argc = argc - optind;
7339 hook.argv = argv + optind;
7342 datastr = cget(&hook, NULL);
7344 * If the user supplied "-" instead of a format, he
7345 * wants the data to be written to stdout.
7347 if ((datastr != NULL)
7348 && (datastr[0] == '-'))
7351 smp_response = (u_int8_t *)malloc(response_size);
7352 if (smp_response == NULL) {
7353 warn("can't malloc memory for SMP response");
7355 goto smpcmd_bailout;
7359 arglist |= CAM_ARG_CMD_OUT;
7360 request_size = strtol(optarg, NULL, 0);
7361 if (request_size <= 0) {
7362 warnx("invalid number of request bytes %d",
7365 goto smpcmd_bailout;
7367 hook.argc = argc - optind;
7368 hook.argv = argv + optind;
7370 datastr = cget(&hook, NULL);
7371 smp_request = (u_int8_t *)malloc(request_size);
7372 if (smp_request == NULL) {
7373 warn("can't malloc memory for SMP request");
7375 goto smpcmd_bailout;
7377 bzero(smp_request, request_size);
7379 * If the user supplied "-" instead of a format, he
7380 * wants the data to be read from stdin.
7382 if ((datastr != NULL)
7383 && (datastr[0] == '-'))
7386 buff_encode_visit(smp_request, request_size,
7397 * If fd_data is set, and we're writing to the device, we need to
7398 * read the data the user wants written from stdin.
7400 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7402 int amt_to_read = request_size;
7403 u_int8_t *buf_ptr = smp_request;
7405 for (amt_read = 0; amt_to_read > 0;
7406 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7407 if (amt_read == -1) {
7408 warn("error reading data from stdin");
7410 goto smpcmd_bailout;
7412 amt_to_read -= amt_read;
7413 buf_ptr += amt_read;
7417 if (((arglist & CAM_ARG_CMD_IN) == 0)
7418 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7419 warnx("%s: need both the request (-r) and response (-R) "
7420 "arguments", __func__);
7422 goto smpcmd_bailout;
7425 flags |= CAM_DEV_QFRZDIS;
7427 cam_fill_smpio(&ccb->smpio,
7428 /*retries*/ retry_count,
7431 /*smp_request*/ smp_request,
7432 /*smp_request_len*/ request_size,
7433 /*smp_response*/ smp_response,
7434 /*smp_response_len*/ response_size,
7435 /*timeout*/ timeout ? timeout : 5000);
7437 ccb->smpio.flags = SMP_FLAG_NONE;
7439 if (((retval = cam_send_ccb(device, ccb)) < 0)
7440 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7441 const char warnstr[] = "error sending command";
7448 if (arglist & CAM_ARG_VERBOSE) {
7449 cam_error_print(device, ccb, CAM_ESF_ALL,
7450 CAM_EPF_ALL, stderr);
7454 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7455 && (response_size > 0)) {
7456 if (fd_response == 0) {
7457 buff_decode_visit(smp_response, response_size,
7458 datastr, arg_put, NULL);
7459 fprintf(stdout, "\n");
7461 ssize_t amt_written;
7462 int amt_to_write = response_size;
7463 u_int8_t *buf_ptr = smp_response;
7465 for (amt_written = 0; (amt_to_write > 0) &&
7466 (amt_written = write(STDOUT_FILENO, buf_ptr,
7467 amt_to_write)) > 0;){
7468 amt_to_write -= amt_written;
7469 buf_ptr += amt_written;
7471 if (amt_written == -1) {
7472 warn("error writing data to stdout");
7474 goto smpcmd_bailout;
7475 } else if ((amt_written == 0)
7476 && (amt_to_write > 0)) {
7477 warnx("only wrote %u bytes out of %u",
7478 response_size - amt_to_write,
7487 if (smp_request != NULL)
7490 if (smp_response != NULL)
7497 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7498 int retry_count, int timeout)
7502 int32_t mmc_opcode = 0, mmc_arg = 0;
7503 int32_t mmc_flags = -1;
7506 int is_bw_4 = 0, is_bw_1 = 0;
7507 int is_highspeed = 0, is_stdspeed = 0;
7508 int is_info_request = 0;
7510 uint8_t mmc_data_byte = 0;
7512 /* For IO_RW_EXTENDED command */
7513 uint8_t *mmc_data = NULL;
7514 struct mmc_data mmc_d;
7515 int mmc_data_len = 0;
7518 * Note that at the moment we don't support sending SMP CCBs to
7519 * devices that aren't probed by CAM.
7521 ccb = cam_getccb(device);
7523 warnx("%s: error allocating CCB", __func__);
7527 bzero(&(&ccb->ccb_h)[1],
7528 sizeof(union ccb) - sizeof(struct ccb_hdr));
7530 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7539 if (!strcmp(optarg, "high"))
7545 is_info_request = 1;
7548 mmc_opcode = strtol(optarg, NULL, 0);
7549 if (mmc_opcode < 0) {
7550 warnx("invalid MMC opcode %d",
7553 goto mmccmd_bailout;
7557 mmc_arg = strtol(optarg, NULL, 0);
7559 warnx("invalid MMC arg %d",
7562 goto mmccmd_bailout;
7566 mmc_flags = strtol(optarg, NULL, 0);
7567 if (mmc_flags < 0) {
7568 warnx("invalid MMC flags %d",
7571 goto mmccmd_bailout;
7575 mmc_data_len = strtol(optarg, NULL, 0);
7576 if (mmc_data_len <= 0) {
7577 warnx("invalid MMC data len %d",
7580 goto mmccmd_bailout;
7587 mmc_data_byte = strtol(optarg, NULL, 0);
7593 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7595 /* If flags are left default, supply the right flags */
7597 switch (mmc_opcode) {
7598 case MMC_GO_IDLE_STATE:
7599 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7601 case IO_SEND_OP_COND:
7602 mmc_flags = MMC_RSP_R4;
7604 case SD_SEND_RELATIVE_ADDR:
7605 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7607 case MMC_SELECT_CARD:
7608 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7609 mmc_arg = mmc_arg << 16;
7611 case SD_IO_RW_DIRECT:
7612 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7613 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7615 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7617 case SD_IO_RW_EXTENDED:
7618 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7619 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7620 int len_arg = mmc_data_len;
7621 if (mmc_data_len == 512)
7625 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7627 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7630 mmc_flags = MMC_RSP_R1;
7634 // Switch bus width instead of sending IO command
7635 if (is_bw_4 || is_bw_1) {
7636 struct ccb_trans_settings_mmc *cts;
7637 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7638 ccb->ccb_h.flags = 0;
7639 cts = &ccb->cts.proto_specific.mmc;
7640 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7641 cts->ios_valid = MMC_BW;
7642 if (((retval = cam_send_ccb(device, ccb)) < 0)
7643 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7644 warn("Error sending command");
7646 printf("Parameters set OK\n");
7652 // Switch bus speed instead of sending IO command
7653 if (is_stdspeed || is_highspeed) {
7654 struct ccb_trans_settings_mmc *cts;
7655 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7656 ccb->ccb_h.flags = 0;
7657 cts = &ccb->cts.proto_specific.mmc;
7658 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
7659 cts->ios_valid = MMC_BT;
7660 if (((retval = cam_send_ccb(device, ccb)) < 0)
7661 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7662 warn("Error sending command");
7664 printf("Speed set OK (HS: %d)\n", is_highspeed);
7670 // Get information about controller and its settings
7671 if (is_info_request) {
7672 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
7673 ccb->ccb_h.flags = 0;
7674 struct ccb_trans_settings_mmc *cts;
7675 cts = &ccb->cts.proto_specific.mmc;
7676 if (((retval = cam_send_ccb(device, ccb)) < 0)
7677 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7678 warn("Error sending command");
7681 printf("Host controller information\n");
7682 printf("Host OCR: 0x%x\n", cts->host_ocr);
7683 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
7684 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
7685 printf("Supported bus width: ");
7686 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
7688 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
7690 printf("\nCurrent settings:\n");
7691 printf("Bus width: ");
7692 switch (cts->ios.bus_width) {
7703 printf("Freq: %d.%03d MHz%s\n",
7704 cts->ios.clock / 1000000,
7705 (cts->ios.clock / 1000) % 1000,
7706 cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : "");
7710 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
7712 if (mmc_data_len > 0) {
7713 flags |= CAM_DIR_IN;
7714 mmc_data = malloc(mmc_data_len);
7715 memset(mmc_data, 0, mmc_data_len);
7716 mmc_d.len = mmc_data_len;
7717 mmc_d.data = mmc_data;
7718 mmc_d.flags = MMC_DATA_READ;
7719 } else flags |= CAM_DIR_NONE;
7721 cam_fill_mmcio(&ccb->mmcio,
7722 /*retries*/ retry_count,
7725 /*mmc_opcode*/ mmc_opcode,
7726 /*mmc_arg*/ mmc_arg,
7727 /*mmc_flags*/ mmc_flags,
7728 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
7729 /*timeout*/ timeout ? timeout : 5000);
7731 if (((retval = cam_send_ccb(device, ccb)) < 0)
7732 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7733 const char warnstr[] = "error sending command";
7740 if (arglist & CAM_ARG_VERBOSE) {
7741 cam_error_print(device, ccb, CAM_ESF_ALL,
7742 CAM_EPF_ALL, stderr);
7746 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
7747 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
7748 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
7749 ccb->mmcio.cmd.resp[1],
7750 ccb->mmcio.cmd.resp[2],
7751 ccb->mmcio.cmd.resp[3]);
7753 switch (mmc_opcode) {
7754 case SD_IO_RW_DIRECT:
7755 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
7756 SD_R5_DATA(ccb->mmcio.cmd.resp),
7757 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
7759 case SD_IO_RW_EXTENDED:
7760 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
7761 hexdump(mmc_data, mmc_data_len, NULL, 0);
7763 case SD_SEND_RELATIVE_ADDR:
7764 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
7767 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
7774 if (mmc_data_len > 0 && mmc_data != NULL)
7781 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7782 char *combinedopt, int retry_count, int timeout)
7785 struct smp_report_general_request *request = NULL;
7786 struct smp_report_general_response *response = NULL;
7787 struct sbuf *sb = NULL;
7789 int c, long_response = 0;
7793 * Note that at the moment we don't support sending SMP CCBs to
7794 * devices that aren't probed by CAM.
7796 ccb = cam_getccb(device);
7798 warnx("%s: error allocating CCB", __func__);
7802 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7804 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7813 request = malloc(sizeof(*request));
7814 if (request == NULL) {
7815 warn("%s: unable to allocate %zd bytes", __func__,
7821 response = malloc(sizeof(*response));
7822 if (response == NULL) {
7823 warn("%s: unable to allocate %zd bytes", __func__,
7830 smp_report_general(&ccb->smpio,
7834 /*request_len*/ sizeof(*request),
7835 (uint8_t *)response,
7836 /*response_len*/ sizeof(*response),
7837 /*long_response*/ long_response,
7840 if (((retval = cam_send_ccb(device, ccb)) < 0)
7841 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7842 const char warnstr[] = "error sending command";
7849 if (arglist & CAM_ARG_VERBOSE) {
7850 cam_error_print(device, ccb, CAM_ESF_ALL,
7851 CAM_EPF_ALL, stderr);
7858 * If the device supports the long response bit, try again and see
7859 * if we can get all of the data.
7861 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7862 && (long_response == 0)) {
7863 ccb->ccb_h.status = CAM_REQ_INPROG;
7864 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7870 * XXX KDM detect and decode SMP errors here.
7872 sb = sbuf_new_auto();
7874 warnx("%s: error allocating sbuf", __func__);
7878 smp_report_general_sbuf(response, sizeof(*response), sb);
7880 if (sbuf_finish(sb) != 0) {
7881 warnx("%s: sbuf_finish", __func__);
7885 printf("%s", sbuf_data(sb));
7891 if (request != NULL)
7894 if (response != NULL)
7903 static struct camcontrol_opts phy_ops[] = {
7904 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7905 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7906 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7907 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7908 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7909 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7910 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7911 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7912 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7917 smpphycontrol(struct cam_device *device, int argc, char **argv,
7918 char *combinedopt, int retry_count, int timeout)
7921 struct smp_phy_control_request *request = NULL;
7922 struct smp_phy_control_response *response = NULL;
7923 int long_response = 0;
7926 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7928 uint64_t attached_dev_name = 0;
7929 int dev_name_set = 0;
7930 uint32_t min_plr = 0, max_plr = 0;
7931 uint32_t pp_timeout_val = 0;
7932 int slumber_partial = 0;
7933 int set_pp_timeout_val = 0;
7937 * Note that at the moment we don't support sending SMP CCBs to
7938 * devices that aren't probed by CAM.
7940 ccb = cam_getccb(device);
7942 warnx("%s: error allocating CCB", __func__);
7946 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7948 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7956 if (strcasecmp(optarg, "enable") == 0)
7958 else if (strcasecmp(optarg, "disable") == 0)
7961 warnx("%s: Invalid argument %s", __func__,
7968 slumber_partial |= enable <<
7969 SMP_PC_SAS_SLUMBER_SHIFT;
7972 slumber_partial |= enable <<
7973 SMP_PC_SAS_PARTIAL_SHIFT;
7976 slumber_partial |= enable <<
7977 SMP_PC_SATA_SLUMBER_SHIFT;
7980 slumber_partial |= enable <<
7981 SMP_PC_SATA_PARTIAL_SHIFT;
7984 warnx("%s: programmer error", __func__);
7987 break; /*NOTREACHED*/
7992 attached_dev_name = (uintmax_t)strtoumax(optarg,
8001 * We don't do extensive checking here, so this
8002 * will continue to work when new speeds come out.
8004 min_plr = strtoul(optarg, NULL, 0);
8006 || (min_plr > 0xf)) {
8007 warnx("%s: invalid link rate %x",
8015 * We don't do extensive checking here, so this
8016 * will continue to work when new speeds come out.
8018 max_plr = strtoul(optarg, NULL, 0);
8020 || (max_plr > 0xf)) {
8021 warnx("%s: invalid link rate %x",
8028 camcontrol_optret optreturn;
8029 cam_argmask argnums;
8032 if (phy_op_set != 0) {
8033 warnx("%s: only one phy operation argument "
8034 "(-o) allowed", __func__);
8042 * Allow the user to specify the phy operation
8043 * numerically, as well as with a name. This will
8044 * future-proof it a bit, so options that are added
8045 * in future specs can be used.
8047 if (isdigit(optarg[0])) {
8048 phy_operation = strtoul(optarg, NULL, 0);
8049 if ((phy_operation == 0)
8050 || (phy_operation > 0xff)) {
8051 warnx("%s: invalid phy operation %#x",
8052 __func__, phy_operation);
8058 optreturn = getoption(phy_ops, optarg, &phy_operation,
8061 if (optreturn == CC_OR_AMBIGUOUS) {
8062 warnx("%s: ambiguous option %s", __func__,
8067 } else if (optreturn == CC_OR_NOT_FOUND) {
8068 warnx("%s: option %s not found", __func__,
8080 pp_timeout_val = strtoul(optarg, NULL, 0);
8081 if (pp_timeout_val > 15) {
8082 warnx("%s: invalid partial pathway timeout "
8083 "value %u, need a value less than 16",
8084 __func__, pp_timeout_val);
8088 set_pp_timeout_val = 1;
8096 warnx("%s: a PHY (-p phy) argument is required",__func__);
8101 if (((dev_name_set != 0)
8102 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8103 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8104 && (dev_name_set == 0))) {
8105 warnx("%s: -d name and -o setdevname arguments both "
8106 "required to set device name", __func__);
8111 request = malloc(sizeof(*request));
8112 if (request == NULL) {
8113 warn("%s: unable to allocate %zd bytes", __func__,
8119 response = malloc(sizeof(*response));
8120 if (response == NULL) {
8121 warn("%s: unable to allocate %zd bytes", __func__,
8127 smp_phy_control(&ccb->smpio,
8132 (uint8_t *)response,
8135 /*expected_exp_change_count*/ 0,
8138 (set_pp_timeout_val != 0) ? 1 : 0,
8146 if (((retval = cam_send_ccb(device, ccb)) < 0)
8147 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8148 const char warnstr[] = "error sending command";
8155 if (arglist & CAM_ARG_VERBOSE) {
8157 * Use CAM_EPF_NORMAL so we only get one line of
8158 * SMP command decoding.
8160 cam_error_print(device, ccb, CAM_ESF_ALL,
8161 CAM_EPF_NORMAL, stderr);
8167 /* XXX KDM print out something here for success? */
8172 if (request != NULL)
8175 if (response != NULL)
8182 smpmaninfo(struct cam_device *device, int argc, char **argv,
8183 char *combinedopt, int retry_count, int timeout)
8186 struct smp_report_manuf_info_request request;
8187 struct smp_report_manuf_info_response response;
8188 struct sbuf *sb = NULL;
8189 int long_response = 0;
8194 * Note that at the moment we don't support sending SMP CCBs to
8195 * devices that aren't probed by CAM.
8197 ccb = cam_getccb(device);
8199 warnx("%s: error allocating CCB", __func__);
8203 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8205 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8214 bzero(&request, sizeof(request));
8215 bzero(&response, sizeof(response));
8217 smp_report_manuf_info(&ccb->smpio,
8222 (uint8_t *)&response,
8227 if (((retval = cam_send_ccb(device, ccb)) < 0)
8228 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8229 const char warnstr[] = "error sending command";
8236 if (arglist & CAM_ARG_VERBOSE) {
8237 cam_error_print(device, ccb, CAM_ESF_ALL,
8238 CAM_EPF_ALL, stderr);
8244 sb = sbuf_new_auto();
8246 warnx("%s: error allocating sbuf", __func__);
8250 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8252 if (sbuf_finish(sb) != 0) {
8253 warnx("%s: sbuf_finish", __func__);
8257 printf("%s", sbuf_data(sb));
8271 getdevid(struct cam_devitem *item)
8274 union ccb *ccb = NULL;
8276 struct cam_device *dev;
8278 dev = cam_open_btl(item->dev_match.path_id,
8279 item->dev_match.target_id,
8280 item->dev_match.target_lun, O_RDWR, NULL);
8283 warnx("%s", cam_errbuf);
8288 item->device_id_len = 0;
8290 ccb = cam_getccb(dev);
8292 warnx("%s: error allocating CCB", __func__);
8297 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8300 * On the first try, we just probe for the size of the data, and
8301 * then allocate that much memory and try again.
8304 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8305 ccb->ccb_h.flags = CAM_DIR_IN;
8306 ccb->cdai.flags = CDAI_FLAG_NONE;
8307 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8308 ccb->cdai.bufsiz = item->device_id_len;
8309 if (item->device_id_len != 0)
8310 ccb->cdai.buf = (uint8_t *)item->device_id;
8312 if (cam_send_ccb(dev, ccb) < 0) {
8313 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8318 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8319 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8324 if (item->device_id_len == 0) {
8326 * This is our first time through. Allocate the buffer,
8327 * and then go back to get the data.
8329 if (ccb->cdai.provsiz == 0) {
8330 warnx("%s: invalid .provsiz field returned with "
8331 "XPT_GDEV_ADVINFO CCB", __func__);
8335 item->device_id_len = ccb->cdai.provsiz;
8336 item->device_id = malloc(item->device_id_len);
8337 if (item->device_id == NULL) {
8338 warn("%s: unable to allocate %d bytes", __func__,
8339 item->device_id_len);
8343 ccb->ccb_h.status = CAM_REQ_INPROG;
8349 cam_close_device(dev);
8358 * XXX KDM merge this code with getdevtree()?
8361 buildbusdevlist(struct cam_devlist *devlist)
8364 int bufsize, fd = -1;
8365 struct dev_match_pattern *patterns;
8366 struct cam_devitem *item = NULL;
8367 int skip_device = 0;
8370 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8371 warn("couldn't open %s", XPT_DEVICE);
8375 bzero(&ccb, sizeof(union ccb));
8377 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8378 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8379 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8381 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8382 bufsize = sizeof(struct dev_match_result) * 100;
8383 ccb.cdm.match_buf_len = bufsize;
8384 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8385 if (ccb.cdm.matches == NULL) {
8386 warnx("can't malloc memory for matches");
8390 ccb.cdm.num_matches = 0;
8391 ccb.cdm.num_patterns = 2;
8392 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8393 ccb.cdm.num_patterns;
8395 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8396 if (patterns == NULL) {
8397 warnx("can't malloc memory for patterns");
8402 ccb.cdm.patterns = patterns;
8403 bzero(patterns, ccb.cdm.pattern_buf_len);
8405 patterns[0].type = DEV_MATCH_DEVICE;
8406 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8407 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8408 patterns[1].type = DEV_MATCH_PERIPH;
8409 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8410 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8413 * We do the ioctl multiple times if necessary, in case there are
8414 * more than 100 nodes in the EDT.
8419 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8420 warn("error sending CAMIOCOMMAND ioctl");
8425 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8426 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8427 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8428 warnx("got CAM error %#x, CDM error %d\n",
8429 ccb.ccb_h.status, ccb.cdm.status);
8434 for (i = 0; i < ccb.cdm.num_matches; i++) {
8435 switch (ccb.cdm.matches[i].type) {
8436 case DEV_MATCH_DEVICE: {
8437 struct device_match_result *dev_result;
8440 &ccb.cdm.matches[i].result.device_result;
8442 if (dev_result->flags &
8443 DEV_RESULT_UNCONFIGURED) {
8449 item = malloc(sizeof(*item));
8451 warn("%s: unable to allocate %zd bytes",
8452 __func__, sizeof(*item));
8456 bzero(item, sizeof(*item));
8457 bcopy(dev_result, &item->dev_match,
8458 sizeof(*dev_result));
8459 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8462 if (getdevid(item) != 0) {
8468 case DEV_MATCH_PERIPH: {
8469 struct periph_match_result *periph_result;
8472 &ccb.cdm.matches[i].result.periph_result;
8474 if (skip_device != 0)
8476 item->num_periphs++;
8477 item->periph_matches = realloc(
8478 item->periph_matches,
8480 sizeof(struct periph_match_result));
8481 if (item->periph_matches == NULL) {
8482 warn("%s: error allocating periph "
8487 bcopy(periph_result, &item->periph_matches[
8488 item->num_periphs - 1],
8489 sizeof(*periph_result));
8493 fprintf(stderr, "%s: unexpected match "
8494 "type %d\n", __func__,
8495 ccb.cdm.matches[i].type);
8498 break; /*NOTREACHED*/
8501 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8502 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8510 free(ccb.cdm.matches);
8513 freebusdevlist(devlist);
8519 freebusdevlist(struct cam_devlist *devlist)
8521 struct cam_devitem *item, *item2;
8523 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8524 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8526 free(item->device_id);
8527 free(item->periph_matches);
8532 static struct cam_devitem *
8533 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8535 struct cam_devitem *item;
8537 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8538 struct scsi_vpd_id_descriptor *idd;
8541 * XXX KDM look for LUN IDs as well?
8543 idd = scsi_get_devid(item->device_id,
8544 item->device_id_len,
8545 scsi_devid_is_sas_target);
8549 if (scsi_8btou64(idd->identifier) == sasaddr)
8557 smpphylist(struct cam_device *device, int argc, char **argv,
8558 char *combinedopt, int retry_count, int timeout)
8560 struct smp_report_general_request *rgrequest = NULL;
8561 struct smp_report_general_response *rgresponse = NULL;
8562 struct smp_discover_request *disrequest = NULL;
8563 struct smp_discover_response *disresponse = NULL;
8564 struct cam_devlist devlist;
8566 int long_response = 0;
8573 * Note that at the moment we don't support sending SMP CCBs to
8574 * devices that aren't probed by CAM.
8576 ccb = cam_getccb(device);
8578 warnx("%s: error allocating CCB", __func__);
8582 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8583 STAILQ_INIT(&devlist.dev_queue);
8585 rgrequest = malloc(sizeof(*rgrequest));
8586 if (rgrequest == NULL) {
8587 warn("%s: unable to allocate %zd bytes", __func__,
8588 sizeof(*rgrequest));
8593 rgresponse = malloc(sizeof(*rgresponse));
8594 if (rgresponse == NULL) {
8595 warn("%s: unable to allocate %zd bytes", __func__,
8596 sizeof(*rgresponse));
8601 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8614 smp_report_general(&ccb->smpio,
8618 /*request_len*/ sizeof(*rgrequest),
8619 (uint8_t *)rgresponse,
8620 /*response_len*/ sizeof(*rgresponse),
8621 /*long_response*/ long_response,
8624 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8626 if (((retval = cam_send_ccb(device, ccb)) < 0)
8627 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8628 const char warnstr[] = "error sending command";
8635 if (arglist & CAM_ARG_VERBOSE) {
8636 cam_error_print(device, ccb, CAM_ESF_ALL,
8637 CAM_EPF_ALL, stderr);
8643 num_phys = rgresponse->num_phys;
8645 if (num_phys == 0) {
8647 fprintf(stdout, "%s: No Phys reported\n", __func__);
8652 devlist.path_id = device->path_id;
8654 retval = buildbusdevlist(&devlist);
8659 fprintf(stdout, "%d PHYs:\n", num_phys);
8660 fprintf(stdout, "PHY Attached SAS Address\n");
8663 disrequest = malloc(sizeof(*disrequest));
8664 if (disrequest == NULL) {
8665 warn("%s: unable to allocate %zd bytes", __func__,
8666 sizeof(*disrequest));
8671 disresponse = malloc(sizeof(*disresponse));
8672 if (disresponse == NULL) {
8673 warn("%s: unable to allocate %zd bytes", __func__,
8674 sizeof(*disresponse));
8679 for (i = 0; i < num_phys; i++) {
8680 struct cam_devitem *item;
8681 struct device_match_result *dev_match;
8682 char vendor[16], product[48], revision[16];
8686 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8688 ccb->ccb_h.status = CAM_REQ_INPROG;
8689 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8691 smp_discover(&ccb->smpio,
8695 sizeof(*disrequest),
8696 (uint8_t *)disresponse,
8697 sizeof(*disresponse),
8699 /*ignore_zone_group*/ 0,
8703 if (((retval = cam_send_ccb(device, ccb)) < 0)
8704 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
8705 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
8706 const char warnstr[] = "error sending command";
8713 if (arglist & CAM_ARG_VERBOSE) {
8714 cam_error_print(device, ccb, CAM_ESF_ALL,
8715 CAM_EPF_ALL, stderr);
8721 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
8723 fprintf(stdout, "%3d <vacant>\n", i);
8727 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
8730 item = findsasdevice(&devlist,
8731 scsi_8btou64(disresponse->attached_sas_address));
8735 || (item != NULL)) {
8736 fprintf(stdout, "%3d 0x%016jx", i,
8737 (uintmax_t)scsi_8btou64(
8738 disresponse->attached_sas_address));
8740 fprintf(stdout, "\n");
8743 } else if (quiet != 0)
8746 dev_match = &item->dev_match;
8748 if (dev_match->protocol == PROTO_SCSI) {
8749 cam_strvis(vendor, dev_match->inq_data.vendor,
8750 sizeof(dev_match->inq_data.vendor),
8752 cam_strvis(product, dev_match->inq_data.product,
8753 sizeof(dev_match->inq_data.product),
8755 cam_strvis(revision, dev_match->inq_data.revision,
8756 sizeof(dev_match->inq_data.revision),
8758 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8760 } else if ((dev_match->protocol == PROTO_ATA)
8761 || (dev_match->protocol == PROTO_SATAPM)) {
8762 cam_strvis(product, dev_match->ident_data.model,
8763 sizeof(dev_match->ident_data.model),
8765 cam_strvis(revision, dev_match->ident_data.revision,
8766 sizeof(dev_match->ident_data.revision),
8768 sprintf(tmpstr, "<%s %s>", product, revision);
8770 sprintf(tmpstr, "<>");
8772 fprintf(stdout, " %-33s ", tmpstr);
8775 * If we have 0 periphs, that's a bug...
8777 if (item->num_periphs == 0) {
8778 fprintf(stdout, "\n");
8782 fprintf(stdout, "(");
8783 for (j = 0; j < item->num_periphs; j++) {
8785 fprintf(stdout, ",");
8787 fprintf(stdout, "%s%d",
8788 item->periph_matches[j].periph_name,
8789 item->periph_matches[j].unit_number);
8792 fprintf(stdout, ")\n");
8806 freebusdevlist(&devlist);
8812 atapm(struct cam_device *device, int argc, char **argv,
8813 char *combinedopt, int retry_count, int timeout)
8821 ccb = cam_getccb(device);
8824 warnx("%s: error allocating ccb", __func__);
8828 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8837 if (strcmp(argv[1], "idle") == 0) {
8839 cmd = ATA_IDLE_IMMEDIATE;
8842 } else if (strcmp(argv[1], "standby") == 0) {
8844 cmd = ATA_STANDBY_IMMEDIATE;
8846 cmd = ATA_STANDBY_CMD;
8854 else if (t <= (240 * 5))
8856 else if (t <= (252 * 5))
8857 /* special encoding for 21 minutes */
8859 else if (t <= (11 * 30 * 60))
8860 sc = (t - 1) / (30 * 60) + 241;
8864 retval = ata_do_28bit_cmd(device,
8866 /*retries*/retry_count,
8867 /*flags*/CAM_DIR_NONE,
8868 /*protocol*/AP_PROTO_NON_DATA,
8869 /*tag_action*/MSG_SIMPLE_Q_TAG,
8876 /*timeout*/timeout ? timeout : 30 * 1000,
8884 ataaxm(struct cam_device *device, int argc, char **argv,
8885 char *combinedopt, int retry_count, int timeout)
8893 ccb = cam_getccb(device);
8896 warnx("%s: error allocating ccb", __func__);
8900 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8910 if (strcmp(argv[1], "apm") == 0) {
8926 retval = ata_do_28bit_cmd(device,
8928 /*retries*/retry_count,
8929 /*flags*/CAM_DIR_NONE,
8930 /*protocol*/AP_PROTO_NON_DATA,
8931 /*tag_action*/MSG_SIMPLE_Q_TAG,
8932 /*command*/ATA_SETFEATURES,
8938 /*timeout*/timeout ? timeout : 30 * 1000,
8946 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
8947 int show_sa_errors, int sa_set, int service_action,
8948 int timeout_desc, int task_attr, int retry_count, int timeout,
8949 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
8951 union ccb *ccb = NULL;
8952 uint8_t *buf = NULL;
8953 uint32_t alloc_len = 0, num_opcodes;
8954 uint32_t valid_len = 0;
8955 uint32_t avail_len = 0;
8956 struct scsi_report_supported_opcodes_all *all_hdr;
8957 struct scsi_report_supported_opcodes_one *one;
8962 * Make it clear that we haven't yet allocated or filled anything.
8967 ccb = cam_getccb(device);
8969 warnx("couldn't allocate CCB");
8974 /* cam_getccb cleans up the header, caller has to zero the payload */
8975 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8977 if (opcode_set != 0) {
8978 options |= RSO_OPTIONS_OC;
8980 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
8983 alloc_len = sizeof(*all_hdr) + (num_opcodes *
8984 sizeof(struct scsi_report_supported_opcodes_descr));
8987 if (timeout_desc != 0) {
8988 options |= RSO_RCTD;
8989 alloc_len += num_opcodes *
8990 sizeof(struct scsi_report_supported_opcodes_timeout);
8994 options |= RSO_OPTIONS_OC_SA;
8995 if (show_sa_errors != 0)
8996 options &= ~RSO_OPTIONS_OC;
9005 buf = malloc(alloc_len);
9007 warn("Unable to allocate %u bytes", alloc_len);
9011 bzero(buf, alloc_len);
9013 scsi_report_supported_opcodes(&ccb->csio,
9014 /*retries*/ retry_count,
9016 /*tag_action*/ task_attr,
9017 /*options*/ options,
9018 /*req_opcode*/ opcode,
9019 /*req_service_action*/ service_action,
9021 /*dxfer_len*/ alloc_len,
9022 /*sense_len*/ SSD_FULL_SIZE,
9023 /*timeout*/ timeout ? timeout : 10000);
9025 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9027 if (retry_count != 0)
9028 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9030 if (cam_send_ccb(device, ccb) < 0) {
9031 perror("error sending REPORT SUPPORTED OPERATION CODES");
9036 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9037 if (verbosemode != 0)
9038 cam_error_print(device, ccb, CAM_ESF_ALL,
9039 CAM_EPF_ALL, stderr);
9044 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9046 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9047 && (valid_len >= sizeof(*all_hdr))) {
9048 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9049 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9050 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9051 && (valid_len >= sizeof(*one))) {
9052 uint32_t cdb_length;
9054 one = (struct scsi_report_supported_opcodes_one *)buf;
9055 cdb_length = scsi_2btoul(one->cdb_length);
9056 avail_len = sizeof(*one) + cdb_length;
9057 if (one->support & RSO_ONE_CTDP) {
9058 struct scsi_report_supported_opcodes_timeout *td;
9060 td = (struct scsi_report_supported_opcodes_timeout *)
9062 if (valid_len >= (avail_len + sizeof(td->length))) {
9063 avail_len += scsi_2btoul(td->length) +
9066 avail_len += sizeof(*td);
9072 * avail_len could be zero if we didn't get enough data back from
9073 * thet target to determine
9075 if ((avail_len != 0)
9076 && (avail_len > valid_len)) {
9077 alloc_len = avail_len;
9081 *fill_len = valid_len;
9093 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9094 int req_sa, uint8_t *buf, uint32_t valid_len)
9096 struct scsi_report_supported_opcodes_one *one;
9097 struct scsi_report_supported_opcodes_timeout *td;
9098 uint32_t cdb_len = 0, td_len = 0;
9099 const char *op_desc = NULL;
9103 one = (struct scsi_report_supported_opcodes_one *)buf;
9106 * If we don't have the full single opcode descriptor, no point in
9109 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9111 warnx("Only %u bytes returned, not enough to verify support",
9117 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9119 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9122 printf(", SA 0x%x", req_sa);
9125 switch (one->support & RSO_ONE_SUP_MASK) {
9126 case RSO_ONE_SUP_UNAVAIL:
9127 printf("No command support information currently available\n");
9129 case RSO_ONE_SUP_NOT_SUP:
9130 printf("Command not supported\n");
9133 break; /*NOTREACHED*/
9134 case RSO_ONE_SUP_AVAIL:
9135 printf("Command is supported, complies with a SCSI standard\n");
9137 case RSO_ONE_SUP_VENDOR:
9138 printf("Command is supported, vendor-specific "
9139 "implementation\n");
9142 printf("Unknown command support flags 0x%#x\n",
9143 one->support & RSO_ONE_SUP_MASK);
9148 * If we don't have the CDB length, it isn't exactly an error, the
9149 * command probably isn't supported.
9151 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9155 cdb_len = scsi_2btoul(one->cdb_length);
9158 * If our valid data doesn't include the full reported length,
9159 * return. The caller should have detected this and adjusted his
9160 * allocation length to get all of the available data.
9162 if (valid_len < sizeof(*one) + cdb_len) {
9168 * If all we have is the opcode, there is no point in printing out
9176 printf("CDB usage bitmap:");
9177 for (i = 0; i < cdb_len; i++) {
9178 printf(" %02x", one->cdb_usage[i]);
9183 * If we don't have a timeout descriptor, we're done.
9185 if ((one->support & RSO_ONE_CTDP) == 0)
9189 * If we don't have enough valid length to include the timeout
9190 * descriptor length, we're done.
9192 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9195 td = (struct scsi_report_supported_opcodes_timeout *)
9196 &buf[sizeof(*one) + cdb_len];
9197 td_len = scsi_2btoul(td->length);
9198 td_len += sizeof(td->length);
9201 * If we don't have the full timeout descriptor, we're done.
9203 if (td_len < sizeof(*td))
9207 * If we don't have enough valid length to contain the full timeout
9208 * descriptor, we're done.
9210 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9213 printf("Timeout information:\n");
9214 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9215 printf("Nominal timeout: %u seconds\n",
9216 scsi_4btoul(td->nominal_time));
9217 printf("Recommended timeout: %u seconds\n",
9218 scsi_4btoul(td->recommended_time));
9225 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9228 struct scsi_report_supported_opcodes_all *hdr;
9229 struct scsi_report_supported_opcodes_descr *desc;
9230 uint32_t avail_len = 0, used_len = 0;
9234 if (valid_len < sizeof(*hdr)) {
9235 warnx("%s: not enough returned data (%u bytes) opcode list",
9236 __func__, valid_len);
9240 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9241 avail_len = scsi_4btoul(hdr->length);
9242 avail_len += sizeof(hdr->length);
9244 * Take the lesser of the amount of data the drive claims is
9245 * available, and the amount of data the HBA says was returned.
9247 avail_len = MIN(avail_len, valid_len);
9249 used_len = sizeof(hdr->length);
9251 printf("%-6s %4s %8s ",
9252 "Opcode", "SA", "CDB len" );
9255 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9256 printf(" Description\n");
9258 while ((avail_len - used_len) > sizeof(*desc)) {
9259 struct scsi_report_supported_opcodes_timeout *td;
9261 const char *op_desc = NULL;
9263 cur_ptr = &buf[used_len];
9264 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9266 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9267 if (op_desc == NULL)
9268 op_desc = "UNKNOWN";
9270 printf("0x%02x %#4x %8u ", desc->opcode,
9271 scsi_2btoul(desc->service_action),
9272 scsi_2btoul(desc->cdb_length));
9274 used_len += sizeof(*desc);
9276 if ((desc->flags & RSO_CTDP) == 0) {
9277 printf(" %s\n", op_desc);
9282 * If we don't have enough space to fit a timeout
9283 * descriptor, then we're done.
9285 if (avail_len - used_len < sizeof(*td)) {
9286 used_len = avail_len;
9287 printf(" %s\n", op_desc);
9290 cur_ptr = &buf[used_len];
9291 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9292 td_len = scsi_2btoul(td->length);
9293 td_len += sizeof(td->length);
9297 * If the given timeout descriptor length is less than what
9298 * we understand, skip it.
9300 if (td_len < sizeof(*td)) {
9301 printf(" %s\n", op_desc);
9305 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9306 scsi_4btoul(td->nominal_time),
9307 scsi_4btoul(td->recommended_time), op_desc);
9314 scsiopcodes(struct cam_device *device, int argc, char **argv,
9315 char *combinedopt, int task_attr, int retry_count, int timeout,
9319 uint32_t opcode = 0, service_action = 0;
9320 int td_set = 0, opcode_set = 0, sa_set = 0;
9321 int show_sa_errors = 1;
9322 uint32_t valid_len = 0;
9323 uint8_t *buf = NULL;
9327 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9333 opcode = strtoul(optarg, &endptr, 0);
9334 if (*endptr != '\0') {
9335 warnx("Invalid opcode \"%s\", must be a number",
9340 if (opcode > 0xff) {
9341 warnx("Invalid opcode 0x%#x, must be between"
9342 "0 and 0xff inclusive", opcode);
9349 service_action = strtoul(optarg, &endptr, 0);
9350 if (*endptr != '\0') {
9351 warnx("Invalid service action \"%s\", must "
9352 "be a number", optarg);
9356 if (service_action > 0xffff) {
9357 warnx("Invalid service action 0x%#x, must "
9358 "be between 0 and 0xffff inclusive",
9373 && (opcode_set == 0)) {
9374 warnx("You must specify an opcode with -o if a service "
9379 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9380 sa_set, service_action, td_set, task_attr,
9381 retry_count, timeout, verbosemode, &valid_len,
9386 if ((opcode_set != 0)
9388 retval = scsiprintoneopcode(device, opcode, sa_set,
9389 service_action, buf, valid_len);
9391 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9400 #endif /* MINIMALISTIC */
9403 scsireprobe(struct cam_device *device)
9408 ccb = cam_getccb(device);
9411 warnx("%s: error allocating ccb", __func__);
9415 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9417 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9419 if (cam_send_ccb(device, ccb) < 0) {
9420 warn("error sending XPT_REPROBE_LUN CCB");
9425 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9426 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9438 usage(int printlong)
9441 fprintf(printlong ? stdout : stderr,
9442 "usage: camcontrol <command> [device id][generic args][command args]\n"
9443 " camcontrol devlist [-b] [-v]\n"
9444 #ifndef MINIMALISTIC
9445 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9446 " camcontrol tur [dev_id][generic args]\n"
9447 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9448 " camcontrol identify [dev_id][generic args] [-v]\n"
9449 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9450 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9452 " camcontrol start [dev_id][generic args]\n"
9453 " camcontrol stop [dev_id][generic args]\n"
9454 " camcontrol load [dev_id][generic args]\n"
9455 " camcontrol eject [dev_id][generic args]\n"
9456 " camcontrol reprobe [dev_id][generic args]\n"
9457 #endif /* MINIMALISTIC */
9458 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9459 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9460 #ifndef MINIMALISTIC
9461 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9462 " [-q][-s][-S offset][-X]\n"
9463 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9464 " [-P pagectl][-e | -b][-d]\n"
9465 " camcontrol cmd [dev_id][generic args]\n"
9466 " <-a cmd [args] | -c cmd [args]>\n"
9467 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9468 " camcontrol smpcmd [dev_id][generic args]\n"
9469 " <-r len fmt [args]> <-R len fmt [args]>\n"
9470 " camcontrol smprg [dev_id][generic args][-l]\n"
9471 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9472 " [-o operation][-d name][-m rate][-M rate]\n"
9473 " [-T pp_timeout][-a enable|disable]\n"
9474 " [-A enable|disable][-s enable|disable]\n"
9475 " [-S enable|disable]\n"
9476 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9477 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9478 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9479 " <all|bus[:target[:lun]]|off>\n"
9480 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9481 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9482 " [-D <enable|disable>][-M mode][-O offset]\n"
9483 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9484 " [-U][-W bus_width]\n"
9485 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9486 " camcontrol sanitize [dev_id][generic args]\n"
9487 " [-a overwrite|block|crypto|exitfailure]\n"
9488 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9490 " camcontrol idle [dev_id][generic args][-t time]\n"
9491 " camcontrol standby [dev_id][generic args][-t time]\n"
9492 " camcontrol sleep [dev_id][generic args]\n"
9493 " camcontrol apm [dev_id][generic args][-l level]\n"
9494 " camcontrol aam [dev_id][generic args][-l level]\n"
9495 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9497 " camcontrol security [dev_id][generic args]\n"
9498 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9499 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9500 " [-U <user|master>] [-y]\n"
9501 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9502 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9503 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9504 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9505 " [-s scope][-S][-T type][-U]\n"
9506 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9507 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9508 " [-p part][-s start][-T type][-V vol]\n"
9509 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9511 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9512 " [-o rep_opts] [-P print_opts]\n"
9513 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9514 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9515 " [-S power_src] [-T timer]\n"
9516 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9517 " <-s <-f format -T time | -U >>\n"
9519 #endif /* MINIMALISTIC */
9520 " camcontrol help\n");
9523 #ifndef MINIMALISTIC
9525 "Specify one of the following options:\n"
9526 "devlist list all CAM devices\n"
9527 "periphlist list all CAM peripheral drivers attached to a device\n"
9528 "tur send a test unit ready to the named device\n"
9529 "inquiry send a SCSI inquiry command to the named device\n"
9530 "identify send a ATA identify command to the named device\n"
9531 "reportluns send a SCSI report luns command to the device\n"
9532 "readcap send a SCSI read capacity command to the device\n"
9533 "start send a Start Unit command to the device\n"
9534 "stop send a Stop Unit command to the device\n"
9535 "load send a Start Unit command to the device with the load bit set\n"
9536 "eject send a Stop Unit command to the device with the eject bit set\n"
9537 "reprobe update capacity information of the given device\n"
9538 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9539 "reset reset all buses, the given bus, bus:target:lun or device\n"
9540 "defects read the defect list of the specified device\n"
9541 "modepage display or edit (-e) the given mode page\n"
9542 "cmd send the given SCSI command, may need -i or -o as well\n"
9543 "smpcmd send the given SMP command, requires -o and -i\n"
9544 "smprg send the SMP Report General command\n"
9545 "smppc send the SMP PHY Control command, requires -p\n"
9546 "smpphylist display phys attached to a SAS expander\n"
9547 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9548 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9549 "tags report or set the number of transaction slots for a device\n"
9550 "negotiate report or set device negotiation parameters\n"
9551 "format send the SCSI FORMAT UNIT command to the named device\n"
9552 "sanitize send the SCSI SANITIZE command to the named device\n"
9553 "idle send the ATA IDLE command to the named device\n"
9554 "standby send the ATA STANDBY command to the named device\n"
9555 "sleep send the ATA SLEEP command to the named device\n"
9556 "fwdownload program firmware of the named device with the given image\n"
9557 "security report or send ATA security commands to the named device\n"
9558 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9559 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9560 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9561 "zone manage Zoned Block (Shingled) devices\n"
9562 "epc send ATA Extended Power Conditions commands\n"
9563 "timestamp report or set the device's timestamp\n"
9564 "help this message\n"
9565 "Device Identifiers:\n"
9566 "bus:target specify the bus and target, lun defaults to 0\n"
9567 "bus:target:lun specify the bus, target and lun\n"
9568 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
9569 "Generic arguments:\n"
9570 "-v be verbose, print out sense information\n"
9571 "-t timeout command timeout in seconds, overrides default timeout\n"
9572 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
9573 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
9574 "-E have the kernel attempt to perform SCSI error recovery\n"
9575 "-C count specify the SCSI command retry count (needs -E to work)\n"
9576 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
9577 "modepage arguments:\n"
9578 "-l list all available mode pages\n"
9579 "-m page specify the mode page to view or edit\n"
9580 "-e edit the specified mode page\n"
9581 "-b force view to binary mode\n"
9582 "-d disable block descriptors for mode sense\n"
9583 "-P pgctl page control field 0-3\n"
9584 "defects arguments:\n"
9585 "-f format specify defect list format (block, bfi or phys)\n"
9586 "-G get the grown defect list\n"
9587 "-P get the permanent defect list\n"
9588 "inquiry arguments:\n"
9589 "-D get the standard inquiry data\n"
9590 "-S get the serial number\n"
9591 "-R get the transfer rate, etc.\n"
9592 "reportluns arguments:\n"
9593 "-c only report a count of available LUNs\n"
9594 "-l only print out luns, and not a count\n"
9595 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
9596 "readcap arguments\n"
9597 "-b only report the blocksize\n"
9598 "-h human readable device size, base 2\n"
9599 "-H human readable device size, base 10\n"
9600 "-N print the number of blocks instead of last block\n"
9601 "-q quiet, print numbers only\n"
9602 "-s only report the last block/device size\n"
9604 "-c cdb [args] specify the SCSI CDB\n"
9605 "-i len fmt specify input data and input data format\n"
9606 "-o len fmt [args] specify output data and output data fmt\n"
9607 "smpcmd arguments:\n"
9608 "-r len fmt [args] specify the SMP command to be sent\n"
9609 "-R len fmt [args] specify SMP response format\n"
9610 "smprg arguments:\n"
9611 "-l specify the long response format\n"
9612 "smppc arguments:\n"
9613 "-p phy specify the PHY to operate on\n"
9614 "-l specify the long request/response format\n"
9615 "-o operation specify the phy control operation\n"
9616 "-d name set the attached device name\n"
9617 "-m rate set the minimum physical link rate\n"
9618 "-M rate set the maximum physical link rate\n"
9619 "-T pp_timeout set the partial pathway timeout value\n"
9620 "-a enable|disable enable or disable SATA slumber\n"
9621 "-A enable|disable enable or disable SATA partial phy power\n"
9622 "-s enable|disable enable or disable SAS slumber\n"
9623 "-S enable|disable enable or disable SAS partial phy power\n"
9624 "smpphylist arguments:\n"
9625 "-l specify the long response format\n"
9626 "-q only print phys with attached devices\n"
9627 "smpmaninfo arguments:\n"
9628 "-l specify the long response format\n"
9629 "debug arguments:\n"
9630 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
9631 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
9632 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
9633 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
9635 "-N tags specify the number of tags to use for this device\n"
9636 "-q be quiet, don't report the number of tags\n"
9637 "-v report a number of tag-related parameters\n"
9638 "negotiate arguments:\n"
9639 "-a send a test unit ready after negotiation\n"
9640 "-c report/set current negotiation settings\n"
9641 "-D <arg> \"enable\" or \"disable\" disconnection\n"
9642 "-M mode set ATA mode\n"
9643 "-O offset set command delay offset\n"
9644 "-q be quiet, don't report anything\n"
9645 "-R syncrate synchronization rate in MHz\n"
9646 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
9647 "-U report/set user negotiation settings\n"
9648 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
9649 "-v also print a Path Inquiry CCB for the controller\n"
9650 "format arguments:\n"
9651 "-q be quiet, don't print status messages\n"
9652 "-r run in report only mode\n"
9653 "-w don't send immediate format command\n"
9654 "-y don't ask any questions\n"
9655 "sanitize arguments:\n"
9656 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
9657 "-c passes overwrite passes to perform (1 to 31)\n"
9658 "-I invert overwrite pattern after each pass\n"
9659 "-P pattern path to overwrite pattern file\n"
9660 "-q be quiet, don't print status messages\n"
9661 "-r run in report only mode\n"
9662 "-U run operation in unrestricted completion exit mode\n"
9663 "-w don't send immediate sanitize command\n"
9664 "-y don't ask any questions\n"
9665 "idle/standby arguments:\n"
9666 "-t <arg> number of seconds before respective state.\n"
9667 "fwdownload arguments:\n"
9668 "-f fw_image path to firmware image file\n"
9669 "-q don't print informational messages, only errors\n"
9670 "-s run in simulation mode\n"
9671 "-v print info for every firmware segment sent to device\n"
9672 "-y don't ask any questions\n"
9673 "security arguments:\n"
9674 "-d pwd disable security using the given password for the selected\n"
9676 "-e pwd erase the device using the given pwd for the selected user\n"
9677 "-f freeze the security configuration of the specified device\n"
9678 "-h pwd enhanced erase the device using the given pwd for the\n"
9680 "-k pwd unlock the device using the given pwd for the selected\n"
9682 "-l <high|maximum> specifies which security level to set: high or maximum\n"
9683 "-q be quiet, do not print any status messages\n"
9684 "-s pwd password the device (enable security) using the given\n"
9685 " pwd for the selected user\n"
9686 "-T timeout overrides the timeout (seconds) used for erase operation\n"
9687 "-U <user|master> specifies which user to set: user or master\n"
9688 "-y don't ask any questions\n"
9690 "-f freeze the HPA configuration of the device\n"
9691 "-l lock the HPA configuration of the device\n"
9692 "-P make the HPA max sectors persist\n"
9693 "-p pwd Set the HPA configuration password required for unlock\n"
9695 "-q be quiet, do not print any status messages\n"
9696 "-s sectors configures the maximum user accessible sectors of the\n"
9698 "-U pwd unlock the HPA configuration of the device\n"
9699 "-y don't ask any questions\n"
9700 "persist arguments:\n"
9701 "-i action specify read_keys, read_reservation, report_cap, or\n"
9702 " read_full_status\n"
9703 "-o action specify register, register_ignore, reserve, release,\n"
9704 " clear, preempt, preempt_abort, register_move, replace_lost\n"
9705 "-a set the All Target Ports (ALL_TG_PT) bit\n"
9706 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
9707 "-k key specify the Reservation Key\n"
9708 "-K sa_key specify the Service Action Reservation Key\n"
9709 "-p set the Activate Persist Through Power Loss bit\n"
9710 "-R rtp specify the Relative Target Port\n"
9711 "-s scope specify the scope: lun, extent, element or a number\n"
9712 "-S specify Transport ID for register, requires -I\n"
9713 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
9714 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
9715 "-U unregister the current initiator for register_move\n"
9716 "attrib arguments:\n"
9717 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
9719 "-w attr specify an attribute to write, one -w argument per attr\n"
9720 "-a attr_num only display this attribute number\n"
9721 "-c get cached attributes\n"
9722 "-e elem_addr request attributes for the given element in a changer\n"
9723 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
9724 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
9725 " field_none, field_desc, field_num, field_size, field_rw\n"
9726 "-p partition request attributes for the given partition\n"
9727 "-s start_attr request attributes starting at the given number\n"
9728 "-T elem_type specify the element type (used with -e)\n"
9729 "-V logical_vol specify the logical volume ID\n"
9730 "opcodes arguments:\n"
9731 "-o opcode specify the individual opcode to list\n"
9732 "-s service_action specify the service action for the opcode\n"
9733 "-N do not return SCSI error for unsupported SA\n"
9734 "-T request nominal and recommended timeout values\n"
9736 "-c cmd required: rz, open, close, finish, or rwp\n"
9737 "-a apply the action to all zones\n"
9738 "-l LBA specify the zone starting LBA\n"
9739 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
9740 " closed, full, ro, offline, reset, nonseq, nonwp\n"
9741 "-P print_opt report zones printing: normal, summary, script\n"
9743 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
9744 " source, status, list\n"
9745 "-d disable power mode (timer, state)\n"
9746 "-D delayed entry (goto)\n"
9747 "-e enable power mode (timer, state)\n"
9748 "-H hold power mode (goto)\n"
9749 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
9751 "-P only display power mode (status)\n"
9752 "-r rst_src restore settings from: default, saved (restore)\n"
9753 "-s save mode (timer, state, restore)\n"
9754 "-S power_src set power source: battery, nonbattery (source)\n"
9755 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
9756 "timestamp arguments:\n"
9757 "-r report the timestamp of the device\n"
9758 "-f format report the timestamp of the device with the given\n"
9759 " strftime(3) format string\n"
9760 "-m report the timestamp of the device as milliseconds since\n"
9761 " January 1st, 1970\n"
9762 "-U report the time with UTC instead of the local time zone\n"
9763 "-s set the timestamp of the device\n"
9764 "-f format the format of the time string passed into strptime(3)\n"
9765 "-T time the time value passed into strptime(3)\n"
9766 "-U set the timestamp of the device to UTC time\n"
9768 #endif /* MINIMALISTIC */
9772 main(int argc, char **argv)
9775 char *device = NULL;
9777 struct cam_device *cam_dev = NULL;
9778 int timeout = 0, retry_count = 1;
9779 camcontrol_optret optreturn;
9781 const char *mainopt = "C:En:Q:t:u:v";
9782 const char *subopt = NULL;
9783 char combinedopt[256];
9784 int error = 0, optstart = 2;
9785 int task_attr = MSG_SIMPLE_Q_TAG;
9787 #ifndef MINIMALISTIC
9791 #endif /* MINIMALISTIC */
9793 cmdlist = CAM_CMD_NONE;
9794 arglist = CAM_ARG_NONE;
9802 * Get the base option.
9804 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
9806 if (optreturn == CC_OR_AMBIGUOUS) {
9807 warnx("ambiguous option %s", argv[1]);
9810 } else if (optreturn == CC_OR_NOT_FOUND) {
9811 warnx("option %s not found", argv[1]);
9817 * Ahh, getopt(3) is a pain.
9819 * This is a gross hack. There really aren't many other good
9820 * options (excuse the pun) for parsing options in a situation like
9821 * this. getopt is kinda braindead, so you end up having to run
9822 * through the options twice, and give each invocation of getopt
9823 * the option string for the other invocation.
9825 * You would think that you could just have two groups of options.
9826 * The first group would get parsed by the first invocation of
9827 * getopt, and the second group would get parsed by the second
9828 * invocation of getopt. It doesn't quite work out that way. When
9829 * the first invocation of getopt finishes, it leaves optind pointing
9830 * to the argument _after_ the first argument in the second group.
9831 * So when the second invocation of getopt comes around, it doesn't
9832 * recognize the first argument it gets and then bails out.
9834 * A nice alternative would be to have a flag for getopt that says
9835 * "just keep parsing arguments even when you encounter an unknown
9836 * argument", but there isn't one. So there's no real clean way to
9837 * easily parse two sets of arguments without having one invocation
9838 * of getopt know about the other.
9840 * Without this hack, the first invocation of getopt would work as
9841 * long as the generic arguments are first, but the second invocation
9842 * (in the subfunction) would fail in one of two ways. In the case
9843 * where you don't set optreset, it would fail because optind may be
9844 * pointing to the argument after the one it should be pointing at.
9845 * In the case where you do set optreset, and reset optind, it would
9846 * fail because getopt would run into the first set of options, which
9847 * it doesn't understand.
9849 * All of this would "sort of" work if you could somehow figure out
9850 * whether optind had been incremented one option too far. The
9851 * mechanics of that, however, are more daunting than just giving
9852 * both invocations all of the expect options for either invocation.
9854 * Needless to say, I wouldn't mind if someone invented a better
9855 * (non-GPL!) command line parsing interface than getopt. I
9856 * wouldn't mind if someone added more knobs to getopt to make it
9857 * work better. Who knows, I may talk myself into doing it someday,
9858 * if the standards weenies let me. As it is, it just leads to
9859 * hackery like this and causes people to avoid it in some cases.
9861 * KDM, September 8th, 1998
9864 sprintf(combinedopt, "%s%s", mainopt, subopt);
9866 sprintf(combinedopt, "%s", mainopt);
9869 * For these options we do not parse optional device arguments and
9870 * we do not open a passthrough device.
9872 if ((cmdlist == CAM_CMD_RESCAN)
9873 || (cmdlist == CAM_CMD_RESET)
9874 || (cmdlist == CAM_CMD_DEVTREE)
9875 || (cmdlist == CAM_CMD_USAGE)
9876 || (cmdlist == CAM_CMD_DEBUG))
9879 #ifndef MINIMALISTIC
9881 && (argc > 2 && argv[2][0] != '-')) {
9885 if (isdigit(argv[2][0])) {
9886 /* device specified as bus:target[:lun] */
9887 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9889 errx(1, "numeric device specification must "
9890 "be either bus:target, or "
9892 /* default to 0 if lun was not specified */
9893 if ((arglist & CAM_ARG_LUN) == 0) {
9895 arglist |= CAM_ARG_LUN;
9899 if (cam_get_device(argv[2], name, sizeof name, &unit)
9901 errx(1, "%s", cam_errbuf);
9902 device = strdup(name);
9903 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
9907 #endif /* MINIMALISTIC */
9909 * Start getopt processing at argv[2/3], since we've already
9910 * accepted argv[1..2] as the command name, and as a possible
9916 * Now we run through the argument list looking for generic
9917 * options, and ignoring options that possibly belong to
9920 while ((c = getopt(argc, argv, combinedopt))!= -1){
9923 retry_count = strtol(optarg, NULL, 0);
9924 if (retry_count < 0)
9925 errx(1, "retry count %d is < 0",
9927 arglist |= CAM_ARG_RETRIES;
9930 arglist |= CAM_ARG_ERR_RECOVER;
9933 arglist |= CAM_ARG_DEVICE;
9935 while (isspace(*tstr) && (*tstr != '\0'))
9937 device = (char *)strdup(tstr);
9941 int table_entry = 0;
9944 while (isspace(*tstr) && (*tstr != '\0'))
9946 if (isdigit(*tstr)) {
9947 task_attr = strtol(tstr, &endptr, 0);
9948 if (*endptr != '\0') {
9949 errx(1, "Invalid queue option "
9954 scsi_nv_status status;
9956 table_size = sizeof(task_attrs) /
9957 sizeof(task_attrs[0]);
9958 status = scsi_get_nv(task_attrs,
9959 table_size, tstr, &table_entry,
9960 SCSI_NV_FLAG_IG_CASE);
9961 if (status == SCSI_NV_FOUND)
9962 task_attr = task_attrs[
9965 errx(1, "%s option %s",
9966 (status == SCSI_NV_AMBIGUOUS)?
9967 "ambiguous" : "invalid",
9974 timeout = strtol(optarg, NULL, 0);
9976 errx(1, "invalid timeout %d", timeout);
9977 /* Convert the timeout from seconds to ms */
9979 arglist |= CAM_ARG_TIMEOUT;
9982 arglist |= CAM_ARG_UNIT;
9983 unit = strtol(optarg, NULL, 0);
9986 arglist |= CAM_ARG_VERBOSE;
9993 #ifndef MINIMALISTIC
9995 * For most commands we'll want to open the passthrough device
9996 * associated with the specified device. In the case of the rescan
9997 * commands, we don't use a passthrough device at all, just the
9998 * transport layer device.
10000 if (devopen == 1) {
10001 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10002 && (((arglist & CAM_ARG_DEVICE) == 0)
10003 || ((arglist & CAM_ARG_UNIT) == 0))) {
10004 errx(1, "subcommand \"%s\" requires a valid device "
10005 "identifier", argv[1]);
10008 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10009 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10010 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10012 errx(1,"%s", cam_errbuf);
10014 #endif /* MINIMALISTIC */
10017 * Reset optind to 2, and reset getopt, so these routines can parse
10018 * the arguments again.
10024 #ifndef MINIMALISTIC
10025 case CAM_CMD_DEVLIST:
10026 error = getdevlist(cam_dev);
10029 error = atahpa(cam_dev, retry_count, timeout,
10030 argc, argv, combinedopt);
10032 #endif /* MINIMALISTIC */
10033 case CAM_CMD_DEVTREE:
10034 error = getdevtree(argc, argv, combinedopt);
10036 #ifndef MINIMALISTIC
10038 error = testunitready(cam_dev, task_attr, retry_count,
10041 case CAM_CMD_INQUIRY:
10042 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10043 task_attr, retry_count, timeout);
10045 case CAM_CMD_IDENTIFY:
10046 error = ataidentify(cam_dev, retry_count, timeout);
10048 case CAM_CMD_STARTSTOP:
10049 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10050 arglist & CAM_ARG_EJECT, task_attr,
10051 retry_count, timeout);
10053 #endif /* MINIMALISTIC */
10054 case CAM_CMD_RESCAN:
10055 error = dorescan_or_reset(argc, argv, 1);
10057 case CAM_CMD_RESET:
10058 error = dorescan_or_reset(argc, argv, 0);
10060 #ifndef MINIMALISTIC
10061 case CAM_CMD_READ_DEFECTS:
10062 error = readdefects(cam_dev, argc, argv, combinedopt,
10063 task_attr, retry_count, timeout);
10065 case CAM_CMD_MODE_PAGE:
10066 modepage(cam_dev, argc, argv, combinedopt,
10067 task_attr, retry_count, timeout);
10069 case CAM_CMD_SCSI_CMD:
10070 error = scsicmd(cam_dev, argc, argv, combinedopt,
10071 task_attr, retry_count, timeout);
10073 case CAM_CMD_MMCSD_CMD:
10074 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10075 retry_count, timeout);
10077 case CAM_CMD_SMP_CMD:
10078 error = smpcmd(cam_dev, argc, argv, combinedopt,
10079 retry_count, timeout);
10081 case CAM_CMD_SMP_RG:
10082 error = smpreportgeneral(cam_dev, argc, argv,
10083 combinedopt, retry_count,
10086 case CAM_CMD_SMP_PC:
10087 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10088 retry_count, timeout);
10090 case CAM_CMD_SMP_PHYLIST:
10091 error = smpphylist(cam_dev, argc, argv, combinedopt,
10092 retry_count, timeout);
10094 case CAM_CMD_SMP_MANINFO:
10095 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10096 retry_count, timeout);
10098 case CAM_CMD_DEBUG:
10099 error = camdebug(argc, argv, combinedopt);
10102 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10105 error = ratecontrol(cam_dev, task_attr, retry_count,
10106 timeout, argc, argv, combinedopt);
10108 case CAM_CMD_FORMAT:
10109 error = scsiformat(cam_dev, argc, argv,
10110 combinedopt, task_attr, retry_count,
10113 case CAM_CMD_REPORTLUNS:
10114 error = scsireportluns(cam_dev, argc, argv,
10115 combinedopt, task_attr,
10116 retry_count, timeout);
10118 case CAM_CMD_READCAP:
10119 error = scsireadcapacity(cam_dev, argc, argv,
10120 combinedopt, task_attr,
10121 retry_count, timeout);
10124 case CAM_CMD_STANDBY:
10125 case CAM_CMD_SLEEP:
10126 error = atapm(cam_dev, argc, argv,
10127 combinedopt, retry_count, timeout);
10131 error = ataaxm(cam_dev, argc, argv,
10132 combinedopt, retry_count, timeout);
10134 case CAM_CMD_SECURITY:
10135 error = atasecurity(cam_dev, retry_count, timeout,
10136 argc, argv, combinedopt);
10138 case CAM_CMD_DOWNLOAD_FW:
10139 error = fwdownload(cam_dev, argc, argv, combinedopt,
10140 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10143 case CAM_CMD_SANITIZE:
10144 error = scsisanitize(cam_dev, argc, argv,
10145 combinedopt, task_attr,
10146 retry_count, timeout);
10148 case CAM_CMD_PERSIST:
10149 error = scsipersist(cam_dev, argc, argv, combinedopt,
10150 task_attr, retry_count, timeout,
10151 arglist & CAM_ARG_VERBOSE,
10152 arglist & CAM_ARG_ERR_RECOVER);
10154 case CAM_CMD_ATTRIB:
10155 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10156 task_attr, retry_count, timeout,
10157 arglist & CAM_ARG_VERBOSE,
10158 arglist & CAM_ARG_ERR_RECOVER);
10160 case CAM_CMD_OPCODES:
10161 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10162 task_attr, retry_count, timeout,
10163 arglist & CAM_ARG_VERBOSE);
10165 case CAM_CMD_REPROBE:
10166 error = scsireprobe(cam_dev);
10169 error = zone(cam_dev, argc, argv, combinedopt,
10170 task_attr, retry_count, timeout,
10171 arglist & CAM_ARG_VERBOSE);
10174 error = epc(cam_dev, argc, argv, combinedopt,
10175 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10177 case CAM_CMD_TIMESTAMP:
10178 error = timestamp(cam_dev, argc, argv, combinedopt,
10179 task_attr, retry_count, timeout,
10180 arglist & CAM_ARG_VERBOSE);
10182 #endif /* MINIMALISTIC */
10183 case CAM_CMD_USAGE:
10192 if (cam_dev != NULL)
10193 cam_close_device(cam_dev);