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");
5170 if (cts->protocol == PROTO_NVME) {
5171 struct ccb_trans_settings_nvme *nvmex =
5172 &cts->xport_specific.nvme;
5174 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5175 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5176 NVME_MAJOR(nvmex->spec),
5177 NVME_MINOR(nvmex->spec));
5179 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5180 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5181 nvmex->lanes, nvmex->max_lanes);
5182 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5183 nvmex->speed, nvmex->max_speed);
5189 * Get a path inquiry CCB for the specified device.
5192 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5197 ccb = cam_getccb(device);
5199 warnx("get_cpi: couldn't allocate CCB");
5202 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5203 ccb->ccb_h.func_code = XPT_PATH_INQ;
5204 if (cam_send_ccb(device, ccb) < 0) {
5205 warn("get_cpi: error sending Path Inquiry CCB");
5206 if (arglist & CAM_ARG_VERBOSE)
5207 cam_error_print(device, ccb, CAM_ESF_ALL,
5208 CAM_EPF_ALL, stderr);
5210 goto get_cpi_bailout;
5212 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5213 if (arglist & CAM_ARG_VERBOSE)
5214 cam_error_print(device, ccb, CAM_ESF_ALL,
5215 CAM_EPF_ALL, stderr);
5217 goto get_cpi_bailout;
5219 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5227 * Get a get device CCB for the specified device.
5230 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5235 ccb = cam_getccb(device);
5237 warnx("get_cgd: couldn't allocate CCB");
5240 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5241 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5242 if (cam_send_ccb(device, ccb) < 0) {
5243 warn("get_cgd: error sending Path Inquiry CCB");
5244 if (arglist & CAM_ARG_VERBOSE)
5245 cam_error_print(device, ccb, CAM_ESF_ALL,
5246 CAM_EPF_ALL, stderr);
5248 goto get_cgd_bailout;
5250 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5251 if (arglist & CAM_ARG_VERBOSE)
5252 cam_error_print(device, ccb, CAM_ESF_ALL,
5253 CAM_EPF_ALL, stderr);
5255 goto get_cgd_bailout;
5257 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5265 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5269 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5270 int timeout, int verbosemode)
5272 union ccb *ccb = NULL;
5273 struct scsi_vpd_supported_page_list sup_pages;
5277 ccb = cam_getccb(dev);
5279 warn("Unable to allocate CCB");
5284 /* cam_getccb cleans up the header, caller has to zero the payload */
5285 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5287 bzero(&sup_pages, sizeof(sup_pages));
5289 scsi_inquiry(&ccb->csio,
5290 /*retries*/ retry_count,
5292 /* tag_action */ MSG_SIMPLE_Q_TAG,
5293 /* inq_buf */ (u_int8_t *)&sup_pages,
5294 /* inq_len */ sizeof(sup_pages),
5296 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5297 /* sense_len */ SSD_FULL_SIZE,
5298 /* timeout */ timeout ? timeout : 5000);
5300 /* Disable freezing the device queue */
5301 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5303 if (retry_count != 0)
5304 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5306 if (cam_send_ccb(dev, ccb) < 0) {
5313 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5314 if (verbosemode != 0)
5315 cam_error_print(dev, ccb, CAM_ESF_ALL,
5316 CAM_EPF_ALL, stderr);
5321 for (i = 0; i < sup_pages.length; i++) {
5322 if (sup_pages.list[i] == page_id) {
5335 * devtype is filled in with the type of device.
5336 * Returns 0 for success, non-zero for failure.
5339 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5340 int verbosemode, camcontrol_devtype *devtype)
5342 struct ccb_getdev cgd;
5345 retval = get_cgd(dev, &cgd);
5349 switch (cgd.protocol) {
5355 *devtype = CC_DT_ATA;
5357 break; /*NOTREACHED*/
5359 *devtype = CC_DT_UNKNOWN;
5361 break; /*NOTREACHED*/
5365 * Check for the ATA Information VPD page (0x89). If this is an
5366 * ATA device behind a SCSI to ATA translation layer, this VPD page
5367 * should be present.
5369 * If that VPD page isn't present, or we get an error back from the
5370 * INQUIRY command, we'll just treat it as a normal SCSI device.
5372 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5373 timeout, verbosemode);
5375 *devtype = CC_DT_ATA_BEHIND_SCSI;
5377 *devtype = CC_DT_SCSI;
5386 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5387 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5388 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5389 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5390 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5391 int is48bit, camcontrol_devtype devtype)
5395 if (devtype == CC_DT_ATA) {
5396 cam_fill_ataio(&ccb->ataio,
5397 /*retries*/ retry_count,
5400 /*tag_action*/ tag_action,
5401 /*data_ptr*/ data_ptr,
5402 /*dxfer_len*/ dxfer_len,
5403 /*timeout*/ timeout);
5404 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5405 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5408 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5411 if (auxiliary != 0) {
5412 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5413 ccb->ataio.aux = auxiliary;
5416 if (ata_flags & AP_FLAG_CHK_COND)
5417 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5419 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5420 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5421 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5422 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5424 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5425 protocol |= AP_EXTEND;
5427 retval = scsi_ata_pass(&ccb->csio,
5428 /*retries*/ retry_count,
5431 /*tag_action*/ tag_action,
5432 /*protocol*/ protocol,
5433 /*ata_flags*/ ata_flags,
5434 /*features*/ features,
5435 /*sector_count*/ sector_count,
5437 /*command*/ command,
5440 /*auxiliary*/ auxiliary,
5442 /*data_ptr*/ data_ptr,
5443 /*dxfer_len*/ dxfer_len,
5444 /*cdb_storage*/ cdb_storage,
5445 /*cdb_storage_len*/ cdb_storage_len,
5446 /*minimum_cmd_size*/ 0,
5447 /*sense_len*/ sense_len,
5448 /*timeout*/ timeout);
5455 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5456 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5460 switch (ccb->ccb_h.func_code) {
5463 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5466 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5467 * or 16 byte, and need to see what
5469 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5470 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5472 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5473 if ((opcode != ATA_PASS_12)
5474 && (opcode != ATA_PASS_16)) {
5476 warnx("%s: unsupported opcode %02x", __func__, opcode);
5480 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5482 /* Note: the _ccb() variant returns 0 for an error */
5489 switch (error_code) {
5490 case SSD_DESC_CURRENT_ERROR:
5491 case SSD_DESC_DEFERRED_ERROR: {
5492 struct scsi_sense_data_desc *sense;
5493 struct scsi_sense_ata_ret_desc *desc;
5496 sense = (struct scsi_sense_data_desc *)
5497 &ccb->csio.sense_data;
5499 desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len -
5500 ccb->csio.sense_resid, SSD_DESC_ATA);
5501 if (desc_ptr == NULL) {
5502 cam_error_print(dev, ccb, CAM_ESF_ALL,
5503 CAM_EPF_ALL, stderr);
5507 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5509 *error = desc->error;
5510 *count = (desc->count_15_8 << 8) |
5512 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5513 ((uint64_t)desc->lba_39_32 << 32) |
5514 ((uint64_t)desc->lba_31_24 << 24) |
5515 (desc->lba_23_16 << 16) |
5516 (desc->lba_15_8 << 8) |
5518 *device = desc->device;
5519 *status = desc->status;
5522 * If the extend bit isn't set, the result is for a
5523 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5524 * command without the extend bit set. This means
5525 * that the device is supposed to return 28-bit
5526 * status. The count field is only 8 bits, and the
5527 * LBA field is only 8 bits.
5529 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5535 case SSD_CURRENT_ERROR:
5536 case SSD_DEFERRED_ERROR: {
5538 struct scsi_sense_data_fixed *sense;
5541 * XXX KDM need to support fixed sense data.
5543 warnx("%s: Fixed sense data not supported yet",
5547 break; /*NOTREACHED*/
5558 struct ata_res *res;
5561 * In this case, we have an ATA command, and we need to
5562 * fill in the requested values from the result register
5565 res = &ccb->ataio.res;
5566 *error = res->error;
5567 *status = res->status;
5568 *device = res->device;
5569 *count = res->sector_count;
5570 *lba = (res->lba_high << 16) |
5571 (res->lba_mid << 8) |
5573 if (res->flags & CAM_ATAIO_48BIT) {
5574 *count |= (res->sector_count_exp << 8);
5575 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5576 ((uint64_t)res->lba_mid_exp << 32) |
5577 ((uint64_t)res->lba_high_exp << 40);
5579 *lba |= (res->device & 0xf) << 24;
5592 cpi_print(struct ccb_pathinq *cpi)
5594 char adapter_str[1024];
5597 snprintf(adapter_str, sizeof(adapter_str),
5598 "%s%d:", cpi->dev_name, cpi->unit_number);
5600 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5603 for (i = 1; i < UINT8_MAX; i = i << 1) {
5606 if ((i & cpi->hba_inquiry) == 0)
5609 fprintf(stdout, "%s supports ", adapter_str);
5613 str = "MDP message";
5616 str = "32 bit wide SCSI";
5619 str = "16 bit wide SCSI";
5622 str = "SDTR message";
5625 str = "linked CDBs";
5628 str = "tag queue messages";
5631 str = "soft reset alternative";
5634 str = "SATA Port Multiplier";
5637 str = "unknown PI bit set";
5640 fprintf(stdout, "%s\n", str);
5643 for (i = 1; i < UINT32_MAX; i = i << 1) {
5646 if ((i & cpi->hba_misc) == 0)
5649 fprintf(stdout, "%s ", adapter_str);
5653 str = "can understand ata_ext requests";
5656 str = "64bit extended LUNs supported";
5659 str = "bus scans from high ID to low ID";
5662 str = "removable devices not included in scan";
5664 case PIM_NOINITIATOR:
5665 str = "initiator role not supported";
5667 case PIM_NOBUSRESET:
5668 str = "user has disabled initial BUS RESET or"
5669 " controller is in target/mixed mode";
5672 str = "do not send 6-byte commands";
5675 str = "scan bus sequentially";
5678 str = "unmapped I/O supported";
5681 str = "does its own scanning";
5684 str = "unknown PIM bit set";
5687 fprintf(stdout, "%s\n", str);
5690 for (i = 1; i < UINT16_MAX; i = i << 1) {
5693 if ((i & cpi->target_sprt) == 0)
5696 fprintf(stdout, "%s supports ", adapter_str);
5699 str = "target mode processor mode";
5702 str = "target mode phase cog. mode";
5704 case PIT_DISCONNECT:
5705 str = "disconnects in target mode";
5708 str = "terminate I/O message in target mode";
5711 str = "group 6 commands in target mode";
5714 str = "group 7 commands in target mode";
5717 str = "unknown PIT bit set";
5721 fprintf(stdout, "%s\n", str);
5723 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5725 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5727 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5729 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5730 adapter_str, cpi->hpath_id);
5731 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5733 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5734 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5735 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5736 adapter_str, cpi->hba_vendor);
5737 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5738 adapter_str, cpi->hba_device);
5739 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5740 adapter_str, cpi->hba_subvendor);
5741 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5742 adapter_str, cpi->hba_subdevice);
5743 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5744 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5745 if (cpi->base_transfer_speed > 1000)
5746 fprintf(stdout, "%d.%03dMB/sec\n",
5747 cpi->base_transfer_speed / 1000,
5748 cpi->base_transfer_speed % 1000);
5750 fprintf(stdout, "%dKB/sec\n",
5751 (cpi->base_transfer_speed % 1000) * 1000);
5752 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5753 adapter_str, cpi->maxio);
5757 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5758 struct ccb_trans_settings *cts)
5764 ccb = cam_getccb(device);
5767 warnx("get_print_cts: error allocating ccb");
5771 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5773 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5775 if (user_settings == 0)
5776 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5778 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5780 if (cam_send_ccb(device, ccb) < 0) {
5781 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5782 if (arglist & CAM_ARG_VERBOSE)
5783 cam_error_print(device, ccb, CAM_ESF_ALL,
5784 CAM_EPF_ALL, stderr);
5786 goto get_print_cts_bailout;
5789 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5790 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5791 if (arglist & CAM_ARG_VERBOSE)
5792 cam_error_print(device, ccb, CAM_ESF_ALL,
5793 CAM_EPF_ALL, stderr);
5795 goto get_print_cts_bailout;
5799 cts_print(device, &ccb->cts);
5802 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5804 get_print_cts_bailout:
5812 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
5813 int timeout, int argc, char **argv, char *combinedopt)
5817 int user_settings = 0;
5819 int disc_enable = -1, tag_enable = -1;
5822 double syncrate = -1;
5825 int change_settings = 0, send_tur = 0;
5826 struct ccb_pathinq cpi;
5828 ccb = cam_getccb(device);
5830 warnx("ratecontrol: error allocating ccb");
5833 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5842 if (strncasecmp(optarg, "enable", 6) == 0)
5844 else if (strncasecmp(optarg, "disable", 7) == 0)
5847 warnx("-D argument \"%s\" is unknown", optarg);
5849 goto ratecontrol_bailout;
5851 change_settings = 1;
5854 mode = ata_string2mode(optarg);
5856 warnx("unknown mode '%s'", optarg);
5858 goto ratecontrol_bailout;
5860 change_settings = 1;
5863 offset = strtol(optarg, NULL, 0);
5865 warnx("offset value %d is < 0", offset);
5867 goto ratecontrol_bailout;
5869 change_settings = 1;
5875 syncrate = atof(optarg);
5877 warnx("sync rate %f is < 0", syncrate);
5879 goto ratecontrol_bailout;
5881 change_settings = 1;
5884 if (strncasecmp(optarg, "enable", 6) == 0)
5886 else if (strncasecmp(optarg, "disable", 7) == 0)
5889 warnx("-T argument \"%s\" is unknown", optarg);
5891 goto ratecontrol_bailout;
5893 change_settings = 1;
5899 bus_width = strtol(optarg, NULL, 0);
5900 if (bus_width < 0) {
5901 warnx("bus width %d is < 0", bus_width);
5903 goto ratecontrol_bailout;
5905 change_settings = 1;
5911 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5913 * Grab path inquiry information, so we can determine whether
5914 * or not the initiator is capable of the things that the user
5917 ccb->ccb_h.func_code = XPT_PATH_INQ;
5918 if (cam_send_ccb(device, ccb) < 0) {
5919 perror("error sending XPT_PATH_INQ CCB");
5920 if (arglist & CAM_ARG_VERBOSE) {
5921 cam_error_print(device, ccb, CAM_ESF_ALL,
5922 CAM_EPF_ALL, stderr);
5925 goto ratecontrol_bailout;
5927 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5928 warnx("XPT_PATH_INQ CCB failed");
5929 if (arglist & CAM_ARG_VERBOSE) {
5930 cam_error_print(device, ccb, CAM_ESF_ALL,
5931 CAM_EPF_ALL, stderr);
5934 goto ratecontrol_bailout;
5936 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5937 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5939 fprintf(stdout, "%s parameters:\n",
5940 user_settings ? "User" : "Current");
5942 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5944 goto ratecontrol_bailout;
5946 if (arglist & CAM_ARG_VERBOSE)
5949 if (change_settings) {
5950 int didsettings = 0;
5951 struct ccb_trans_settings_spi *spi = NULL;
5952 struct ccb_trans_settings_pata *pata = NULL;
5953 struct ccb_trans_settings_sata *sata = NULL;
5954 struct ccb_trans_settings_ata *ata = NULL;
5955 struct ccb_trans_settings_scsi *scsi = NULL;
5957 if (ccb->cts.transport == XPORT_SPI)
5958 spi = &ccb->cts.xport_specific.spi;
5959 if (ccb->cts.transport == XPORT_ATA)
5960 pata = &ccb->cts.xport_specific.ata;
5961 if (ccb->cts.transport == XPORT_SATA)
5962 sata = &ccb->cts.xport_specific.sata;
5963 if (ccb->cts.protocol == PROTO_ATA)
5964 ata = &ccb->cts.proto_specific.ata;
5965 if (ccb->cts.protocol == PROTO_SCSI)
5966 scsi = &ccb->cts.proto_specific.scsi;
5967 ccb->cts.xport_specific.valid = 0;
5968 ccb->cts.proto_specific.valid = 0;
5969 if (spi && disc_enable != -1) {
5970 spi->valid |= CTS_SPI_VALID_DISC;
5971 if (disc_enable == 0)
5972 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5974 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5977 if (tag_enable != -1) {
5978 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5979 warnx("HBA does not support tagged queueing, "
5980 "so you cannot modify tag settings");
5982 goto ratecontrol_bailout;
5985 ata->valid |= CTS_SCSI_VALID_TQ;
5986 if (tag_enable == 0)
5987 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5989 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5992 scsi->valid |= CTS_SCSI_VALID_TQ;
5993 if (tag_enable == 0)
5994 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5996 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6000 if (spi && offset != -1) {
6001 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6002 warnx("HBA is not capable of changing offset");
6004 goto ratecontrol_bailout;
6006 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6007 spi->sync_offset = offset;
6010 if (spi && syncrate != -1) {
6011 int prelim_sync_period;
6013 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6014 warnx("HBA is not capable of changing "
6017 goto ratecontrol_bailout;
6019 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6021 * The sync rate the user gives us is in MHz.
6022 * We need to translate it into KHz for this
6027 * Next, we calculate a "preliminary" sync period
6028 * in tenths of a nanosecond.
6031 prelim_sync_period = 0;
6033 prelim_sync_period = 10000000 / syncrate;
6035 scsi_calc_syncparam(prelim_sync_period);
6038 if (sata && syncrate != -1) {
6039 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6040 warnx("HBA is not capable of changing "
6043 goto ratecontrol_bailout;
6045 if (!user_settings) {
6046 warnx("You can modify only user rate "
6047 "settings for SATA");
6049 goto ratecontrol_bailout;
6051 sata->revision = ata_speed2revision(syncrate * 100);
6052 if (sata->revision < 0) {
6053 warnx("Invalid rate %f", syncrate);
6055 goto ratecontrol_bailout;
6057 sata->valid |= CTS_SATA_VALID_REVISION;
6060 if ((pata || sata) && mode != -1) {
6061 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6062 warnx("HBA is not capable of changing "
6065 goto ratecontrol_bailout;
6067 if (!user_settings) {
6068 warnx("You can modify only user mode "
6069 "settings for ATA/SATA");
6071 goto ratecontrol_bailout;
6075 pata->valid |= CTS_ATA_VALID_MODE;
6078 sata->valid |= CTS_SATA_VALID_MODE;
6083 * The bus_width argument goes like this:
6087 * Therefore, if you shift the number of bits given on the
6088 * command line right by 4, you should get the correct
6091 if (spi && bus_width != -1) {
6093 * We might as well validate things here with a
6094 * decipherable error message, rather than what
6095 * will probably be an indecipherable error message
6096 * by the time it gets back to us.
6098 if ((bus_width == 16)
6099 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6100 warnx("HBA does not support 16 bit bus width");
6102 goto ratecontrol_bailout;
6103 } else if ((bus_width == 32)
6104 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6105 warnx("HBA does not support 32 bit bus width");
6107 goto ratecontrol_bailout;
6108 } else if ((bus_width != 8)
6109 && (bus_width != 16)
6110 && (bus_width != 32)) {
6111 warnx("Invalid bus width %d", bus_width);
6113 goto ratecontrol_bailout;
6115 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6116 spi->bus_width = bus_width >> 4;
6119 if (didsettings == 0) {
6120 goto ratecontrol_bailout;
6122 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6123 if (cam_send_ccb(device, ccb) < 0) {
6124 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
6125 if (arglist & CAM_ARG_VERBOSE) {
6126 cam_error_print(device, ccb, CAM_ESF_ALL,
6127 CAM_EPF_ALL, stderr);
6130 goto ratecontrol_bailout;
6132 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6133 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6134 if (arglist & CAM_ARG_VERBOSE) {
6135 cam_error_print(device, ccb, CAM_ESF_ALL,
6136 CAM_EPF_ALL, stderr);
6139 goto ratecontrol_bailout;
6143 retval = testunitready(device, task_attr, retry_count, timeout,
6144 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6146 * If the TUR didn't succeed, just bail.
6150 fprintf(stderr, "Test Unit Ready failed\n");
6151 goto ratecontrol_bailout;
6154 if ((change_settings || send_tur) && !quiet &&
6155 (ccb->cts.transport == XPORT_ATA ||
6156 ccb->cts.transport == XPORT_SATA || send_tur)) {
6157 fprintf(stdout, "New parameters:\n");
6158 retval = get_print_cts(device, user_settings, 0, NULL);
6161 ratecontrol_bailout:
6167 scsiformat(struct cam_device *device, int argc, char **argv,
6168 char *combinedopt, int task_attr, int retry_count, int timeout)
6172 int ycount = 0, quiet = 0;
6173 int error = 0, retval = 0;
6174 int use_timeout = 10800 * 1000;
6176 struct format_defect_list_header fh;
6177 u_int8_t *data_ptr = NULL;
6178 u_int32_t dxfer_len = 0;
6180 int num_warnings = 0;
6183 ccb = cam_getccb(device);
6186 warnx("scsiformat: error allocating ccb");
6190 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6192 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6213 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6214 "following device:\n");
6216 error = scsidoinquiry(device, argc, argv, combinedopt,
6217 task_attr, retry_count, timeout);
6220 warnx("scsiformat: error sending inquiry");
6221 goto scsiformat_bailout;
6226 if (!get_confirmation()) {
6228 goto scsiformat_bailout;
6233 use_timeout = timeout;
6236 fprintf(stdout, "Current format timeout is %d seconds\n",
6237 use_timeout / 1000);
6241 * If the user hasn't disabled questions and didn't specify a
6242 * timeout on the command line, ask them if they want the current
6246 && (timeout == 0)) {
6248 int new_timeout = 0;
6250 fprintf(stdout, "Enter new timeout in seconds or press\n"
6251 "return to keep the current timeout [%d] ",
6252 use_timeout / 1000);
6254 if (fgets(str, sizeof(str), stdin) != NULL) {
6256 new_timeout = atoi(str);
6259 if (new_timeout != 0) {
6260 use_timeout = new_timeout * 1000;
6261 fprintf(stdout, "Using new timeout value %d\n",
6262 use_timeout / 1000);
6267 * Keep this outside the if block below to silence any unused
6268 * variable warnings.
6270 bzero(&fh, sizeof(fh));
6273 * If we're in immediate mode, we've got to include the format
6276 if (immediate != 0) {
6277 fh.byte2 = FU_DLH_IMMED;
6278 data_ptr = (u_int8_t *)&fh;
6279 dxfer_len = sizeof(fh);
6280 byte2 = FU_FMT_DATA;
6281 } else if (quiet == 0) {
6282 fprintf(stdout, "Formatting...");
6286 scsi_format_unit(&ccb->csio,
6287 /* retries */ retry_count,
6289 /* tag_action */ task_attr,
6292 /* data_ptr */ data_ptr,
6293 /* dxfer_len */ dxfer_len,
6294 /* sense_len */ SSD_FULL_SIZE,
6295 /* timeout */ use_timeout);
6297 /* Disable freezing the device queue */
6298 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6300 if (arglist & CAM_ARG_ERR_RECOVER)
6301 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6303 if (((retval = cam_send_ccb(device, ccb)) < 0)
6304 || ((immediate == 0)
6305 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6306 const char errstr[] = "error sending format command";
6313 if (arglist & CAM_ARG_VERBOSE) {
6314 cam_error_print(device, ccb, CAM_ESF_ALL,
6315 CAM_EPF_ALL, stderr);
6318 goto scsiformat_bailout;
6322 * If we ran in non-immediate mode, we already checked for errors
6323 * above and printed out any necessary information. If we're in
6324 * immediate mode, we need to loop through and get status
6325 * information periodically.
6327 if (immediate == 0) {
6329 fprintf(stdout, "Format Complete\n");
6331 goto scsiformat_bailout;
6338 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6341 * There's really no need to do error recovery or
6342 * retries here, since we're just going to sit in a
6343 * loop and wait for the device to finish formatting.
6345 scsi_test_unit_ready(&ccb->csio,
6348 /* tag_action */ task_attr,
6349 /* sense_len */ SSD_FULL_SIZE,
6350 /* timeout */ 5000);
6352 /* Disable freezing the device queue */
6353 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6355 retval = cam_send_ccb(device, ccb);
6358 * If we get an error from the ioctl, bail out. SCSI
6359 * errors are expected.
6362 warn("error sending CAMIOCOMMAND ioctl");
6363 if (arglist & CAM_ARG_VERBOSE) {
6364 cam_error_print(device, ccb, CAM_ESF_ALL,
6365 CAM_EPF_ALL, stderr);
6368 goto scsiformat_bailout;
6371 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6373 if ((status != CAM_REQ_CMP)
6374 && (status == CAM_SCSI_STATUS_ERROR)
6375 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6376 struct scsi_sense_data *sense;
6377 int error_code, sense_key, asc, ascq;
6379 sense = &ccb->csio.sense_data;
6380 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6381 ccb->csio.sense_resid, &error_code, &sense_key,
6382 &asc, &ascq, /*show_errors*/ 1);
6385 * According to the SCSI-2 and SCSI-3 specs, a
6386 * drive that is in the middle of a format should
6387 * return NOT READY with an ASC of "logical unit
6388 * not ready, format in progress". The sense key
6389 * specific bytes will then be a progress indicator.
6391 if ((sense_key == SSD_KEY_NOT_READY)
6392 && (asc == 0x04) && (ascq == 0x04)) {
6395 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6396 ccb->csio.sense_resid, sks) == 0)
6399 u_int64_t percentage;
6401 val = scsi_2btoul(&sks[1]);
6402 percentage = 10000ull * val;
6405 "\rFormatting: %ju.%02u %% "
6407 (uintmax_t)(percentage /
6409 (unsigned)((percentage /
6413 } else if ((quiet == 0)
6414 && (++num_warnings <= 1)) {
6415 warnx("Unexpected SCSI Sense Key "
6416 "Specific value returned "
6418 scsi_sense_print(device, &ccb->csio,
6420 warnx("Unable to print status "
6421 "information, but format will "
6423 warnx("will exit when format is "
6428 warnx("Unexpected SCSI error during format");
6429 cam_error_print(device, ccb, CAM_ESF_ALL,
6430 CAM_EPF_ALL, stderr);
6432 goto scsiformat_bailout;
6435 } else if (status != CAM_REQ_CMP) {
6436 warnx("Unexpected CAM status %#x", status);
6437 if (arglist & CAM_ARG_VERBOSE)
6438 cam_error_print(device, ccb, CAM_ESF_ALL,
6439 CAM_EPF_ALL, stderr);
6441 goto scsiformat_bailout;
6444 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6447 fprintf(stdout, "\nFormat Complete\n");
6457 scsisanitize(struct cam_device *device, int argc, char **argv,
6458 char *combinedopt, int task_attr, int retry_count, int timeout)
6461 u_int8_t action = 0;
6463 int ycount = 0, quiet = 0;
6464 int error = 0, retval = 0;
6465 int use_timeout = 10800 * 1000;
6471 const char *pattern = NULL;
6472 u_int8_t *data_ptr = NULL;
6473 u_int32_t dxfer_len = 0;
6475 int num_warnings = 0;
6478 ccb = cam_getccb(device);
6481 warnx("scsisanitize: error allocating ccb");
6485 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6487 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6490 if (strcasecmp(optarg, "overwrite") == 0)
6491 action = SSZ_SERVICE_ACTION_OVERWRITE;
6492 else if (strcasecmp(optarg, "block") == 0)
6493 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6494 else if (strcasecmp(optarg, "crypto") == 0)
6495 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6496 else if (strcasecmp(optarg, "exitfailure") == 0)
6497 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6499 warnx("invalid service operation \"%s\"",
6502 goto scsisanitize_bailout;
6506 passes = strtol(optarg, NULL, 0);
6507 if (passes < 1 || passes > 31) {
6508 warnx("invalid passes value %d", passes);
6510 goto scsisanitize_bailout;
6541 warnx("an action is required");
6543 goto scsisanitize_bailout;
6544 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6545 struct scsi_sanitize_parameter_list *pl;
6549 if (pattern == NULL) {
6550 warnx("overwrite action requires -P argument");
6552 goto scsisanitize_bailout;
6554 fd = open(pattern, O_RDONLY);
6556 warn("cannot open pattern file %s", pattern);
6558 goto scsisanitize_bailout;
6560 if (fstat(fd, &sb) < 0) {
6561 warn("cannot stat pattern file %s", pattern);
6563 goto scsisanitize_bailout;
6566 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6567 warnx("pattern file size exceeds maximum value %d",
6568 SSZPL_MAX_PATTERN_LENGTH);
6570 goto scsisanitize_bailout;
6572 dxfer_len = sizeof(*pl) + sz;
6573 data_ptr = calloc(1, dxfer_len);
6574 if (data_ptr == NULL) {
6575 warnx("cannot allocate parameter list buffer");
6577 goto scsisanitize_bailout;
6580 amt = read(fd, data_ptr + sizeof(*pl), sz);
6582 warn("cannot read pattern file");
6584 goto scsisanitize_bailout;
6585 } else if (amt != sz) {
6586 warnx("short pattern file read");
6588 goto scsisanitize_bailout;
6591 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6597 pl->byte1 |= SSZPL_INVERT;
6598 scsi_ulto2b(sz, pl->length);
6604 else if (invert != 0)
6606 else if (pattern != NULL)
6611 warnx("%s argument only valid with overwrite "
6614 goto scsisanitize_bailout;
6619 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6620 "following device:\n");
6622 error = scsidoinquiry(device, argc, argv, combinedopt,
6623 task_attr, retry_count, timeout);
6626 warnx("scsisanitize: error sending inquiry");
6627 goto scsisanitize_bailout;
6632 if (!get_confirmation()) {
6634 goto scsisanitize_bailout;
6639 use_timeout = timeout;
6642 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6643 use_timeout / 1000);
6647 * If the user hasn't disabled questions and didn't specify a
6648 * timeout on the command line, ask them if they want the current
6652 && (timeout == 0)) {
6654 int new_timeout = 0;
6656 fprintf(stdout, "Enter new timeout in seconds or press\n"
6657 "return to keep the current timeout [%d] ",
6658 use_timeout / 1000);
6660 if (fgets(str, sizeof(str), stdin) != NULL) {
6662 new_timeout = atoi(str);
6665 if (new_timeout != 0) {
6666 use_timeout = new_timeout * 1000;
6667 fprintf(stdout, "Using new timeout value %d\n",
6668 use_timeout / 1000);
6674 byte2 |= SSZ_UNRESTRICTED_EXIT;
6678 scsi_sanitize(&ccb->csio,
6679 /* retries */ retry_count,
6681 /* tag_action */ task_attr,
6684 /* data_ptr */ data_ptr,
6685 /* dxfer_len */ dxfer_len,
6686 /* sense_len */ SSD_FULL_SIZE,
6687 /* timeout */ use_timeout);
6689 /* Disable freezing the device queue */
6690 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6692 if (arglist & CAM_ARG_ERR_RECOVER)
6693 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6695 if (cam_send_ccb(device, ccb) < 0) {
6696 warn("error sending sanitize command");
6698 goto scsisanitize_bailout;
6701 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6702 struct scsi_sense_data *sense;
6703 int error_code, sense_key, asc, ascq;
6705 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6706 CAM_SCSI_STATUS_ERROR) {
6707 sense = &ccb->csio.sense_data;
6708 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6709 ccb->csio.sense_resid, &error_code, &sense_key,
6710 &asc, &ascq, /*show_errors*/ 1);
6712 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6713 asc == 0x20 && ascq == 0x00)
6714 warnx("sanitize is not supported by "
6717 warnx("error sanitizing this device");
6719 warnx("error sanitizing this device");
6721 if (arglist & CAM_ARG_VERBOSE) {
6722 cam_error_print(device, ccb, CAM_ESF_ALL,
6723 CAM_EPF_ALL, stderr);
6726 goto scsisanitize_bailout;
6730 * If we ran in non-immediate mode, we already checked for errors
6731 * above and printed out any necessary information. If we're in
6732 * immediate mode, we need to loop through and get status
6733 * information periodically.
6735 if (immediate == 0) {
6737 fprintf(stdout, "Sanitize Complete\n");
6739 goto scsisanitize_bailout;
6746 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6749 * There's really no need to do error recovery or
6750 * retries here, since we're just going to sit in a
6751 * loop and wait for the device to finish sanitizing.
6753 scsi_test_unit_ready(&ccb->csio,
6756 /* tag_action */ task_attr,
6757 /* sense_len */ SSD_FULL_SIZE,
6758 /* timeout */ 5000);
6760 /* Disable freezing the device queue */
6761 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6763 retval = cam_send_ccb(device, ccb);
6766 * If we get an error from the ioctl, bail out. SCSI
6767 * errors are expected.
6770 warn("error sending CAMIOCOMMAND ioctl");
6771 if (arglist & CAM_ARG_VERBOSE) {
6772 cam_error_print(device, ccb, CAM_ESF_ALL,
6773 CAM_EPF_ALL, stderr);
6776 goto scsisanitize_bailout;
6779 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6781 if ((status != CAM_REQ_CMP)
6782 && (status == CAM_SCSI_STATUS_ERROR)
6783 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6784 struct scsi_sense_data *sense;
6785 int error_code, sense_key, asc, ascq;
6787 sense = &ccb->csio.sense_data;
6788 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6789 ccb->csio.sense_resid, &error_code, &sense_key,
6790 &asc, &ascq, /*show_errors*/ 1);
6793 * According to the SCSI-3 spec, a drive that is in the
6794 * middle of a sanitize should return NOT READY with an
6795 * ASC of "logical unit not ready, sanitize in
6796 * progress". The sense key specific bytes will then
6797 * be a progress indicator.
6799 if ((sense_key == SSD_KEY_NOT_READY)
6800 && (asc == 0x04) && (ascq == 0x1b)) {
6803 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6804 ccb->csio.sense_resid, sks) == 0)
6807 u_int64_t percentage;
6809 val = scsi_2btoul(&sks[1]);
6810 percentage = 10000 * val;
6813 "\rSanitizing: %ju.%02u %% "
6815 (uintmax_t)(percentage /
6817 (unsigned)((percentage /
6821 } else if ((quiet == 0)
6822 && (++num_warnings <= 1)) {
6823 warnx("Unexpected SCSI Sense Key "
6824 "Specific value returned "
6825 "during sanitize:");
6826 scsi_sense_print(device, &ccb->csio,
6828 warnx("Unable to print status "
6829 "information, but sanitze will "
6831 warnx("will exit when sanitize is "
6836 warnx("Unexpected SCSI error during sanitize");
6837 cam_error_print(device, ccb, CAM_ESF_ALL,
6838 CAM_EPF_ALL, stderr);
6840 goto scsisanitize_bailout;
6843 } else if (status != CAM_REQ_CMP) {
6844 warnx("Unexpected CAM status %#x", status);
6845 if (arglist & CAM_ARG_VERBOSE)
6846 cam_error_print(device, ccb, CAM_ESF_ALL,
6847 CAM_EPF_ALL, stderr);
6849 goto scsisanitize_bailout;
6851 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6854 fprintf(stdout, "\nSanitize Complete\n");
6856 scsisanitize_bailout:
6859 if (data_ptr != NULL)
6867 scsireportluns(struct cam_device *device, int argc, char **argv,
6868 char *combinedopt, int task_attr, int retry_count, int timeout)
6871 int c, countonly, lunsonly;
6872 struct scsi_report_luns_data *lundata;
6874 uint8_t report_type;
6875 uint32_t list_len, i, j;
6880 report_type = RPL_REPORT_DEFAULT;
6881 ccb = cam_getccb(device);
6884 warnx("%s: error allocating ccb", __func__);
6888 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6893 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6902 if (strcasecmp(optarg, "default") == 0)
6903 report_type = RPL_REPORT_DEFAULT;
6904 else if (strcasecmp(optarg, "wellknown") == 0)
6905 report_type = RPL_REPORT_WELLKNOWN;
6906 else if (strcasecmp(optarg, "all") == 0)
6907 report_type = RPL_REPORT_ALL;
6909 warnx("%s: invalid report type \"%s\"",
6920 if ((countonly != 0)
6921 && (lunsonly != 0)) {
6922 warnx("%s: you can only specify one of -c or -l", __func__);
6927 * According to SPC-4, the allocation length must be at least 16
6928 * bytes -- enough for the header and one LUN.
6930 alloc_len = sizeof(*lundata) + 8;
6934 lundata = malloc(alloc_len);
6936 if (lundata == NULL) {
6937 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6942 scsi_report_luns(&ccb->csio,
6943 /*retries*/ retry_count,
6945 /*tag_action*/ task_attr,
6946 /*select_report*/ report_type,
6947 /*rpl_buf*/ lundata,
6948 /*alloc_len*/ alloc_len,
6949 /*sense_len*/ SSD_FULL_SIZE,
6950 /*timeout*/ timeout ? timeout : 5000);
6952 /* Disable freezing the device queue */
6953 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6955 if (arglist & CAM_ARG_ERR_RECOVER)
6956 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6958 if (cam_send_ccb(device, ccb) < 0) {
6959 warn("error sending REPORT LUNS command");
6961 if (arglist & CAM_ARG_VERBOSE)
6962 cam_error_print(device, ccb, CAM_ESF_ALL,
6963 CAM_EPF_ALL, stderr);
6969 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6970 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6976 list_len = scsi_4btoul(lundata->length);
6979 * If we need to list the LUNs, and our allocation
6980 * length was too short, reallocate and retry.
6982 if ((countonly == 0)
6983 && (list_len > (alloc_len - sizeof(*lundata)))) {
6984 alloc_len = list_len + sizeof(*lundata);
6990 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6991 ((list_len / 8) > 1) ? "s" : "");
6996 for (i = 0; i < (list_len / 8); i++) {
7000 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7002 fprintf(stdout, ",");
7003 switch (lundata->luns[i].lundata[j] &
7004 RPL_LUNDATA_ATYP_MASK) {
7005 case RPL_LUNDATA_ATYP_PERIPH:
7006 if ((lundata->luns[i].lundata[j] &
7007 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7008 fprintf(stdout, "%d:",
7009 lundata->luns[i].lundata[j] &
7010 RPL_LUNDATA_PERIPH_BUS_MASK);
7012 && ((lundata->luns[i].lundata[j+2] &
7013 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7016 fprintf(stdout, "%d",
7017 lundata->luns[i].lundata[j+1]);
7019 case RPL_LUNDATA_ATYP_FLAT: {
7021 tmplun[0] = lundata->luns[i].lundata[j] &
7022 RPL_LUNDATA_FLAT_LUN_MASK;
7023 tmplun[1] = lundata->luns[i].lundata[j+1];
7025 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7029 case RPL_LUNDATA_ATYP_LUN:
7030 fprintf(stdout, "%d:%d:%d",
7031 (lundata->luns[i].lundata[j+1] &
7032 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7033 lundata->luns[i].lundata[j] &
7034 RPL_LUNDATA_LUN_TARG_MASK,
7035 lundata->luns[i].lundata[j+1] &
7036 RPL_LUNDATA_LUN_LUN_MASK);
7038 case RPL_LUNDATA_ATYP_EXTLUN: {
7039 int field_len_code, eam_code;
7041 eam_code = lundata->luns[i].lundata[j] &
7042 RPL_LUNDATA_EXT_EAM_MASK;
7043 field_len_code = (lundata->luns[i].lundata[j] &
7044 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7046 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7047 && (field_len_code == 0x00)) {
7048 fprintf(stdout, "%d",
7049 lundata->luns[i].lundata[j+1]);
7050 } else if ((eam_code ==
7051 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7052 && (field_len_code == 0x03)) {
7056 * This format takes up all 8 bytes.
7057 * If we aren't starting at offset 0,
7061 fprintf(stdout, "Invalid "
7064 "specified format", j);
7068 bzero(tmp_lun, sizeof(tmp_lun));
7069 bcopy(&lundata->luns[i].lundata[j+1],
7070 &tmp_lun[1], sizeof(tmp_lun) - 1);
7071 fprintf(stdout, "%#jx",
7072 (intmax_t)scsi_8btou64(tmp_lun));
7075 fprintf(stderr, "Unknown Extended LUN"
7076 "Address method %#x, length "
7077 "code %#x", eam_code,
7084 fprintf(stderr, "Unknown LUN address method "
7085 "%#x\n", lundata->luns[i].lundata[0] &
7086 RPL_LUNDATA_ATYP_MASK);
7090 * For the flat addressing method, there are no
7091 * other levels after it.
7096 fprintf(stdout, "\n");
7109 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7110 char *combinedopt, int task_attr, int retry_count, int timeout)
7113 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
7114 struct scsi_read_capacity_data rcap;
7115 struct scsi_read_capacity_data_long rcaplong;
7129 ccb = cam_getccb(device);
7132 warnx("%s: error allocating ccb", __func__);
7136 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7138 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7165 if ((blocksizeonly != 0)
7166 && (numblocks != 0)) {
7167 warnx("%s: you can only specify one of -b or -N", __func__);
7172 if ((blocksizeonly != 0)
7173 && (sizeonly != 0)) {
7174 warnx("%s: you can only specify one of -b or -s", __func__);
7181 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7187 && (blocksizeonly != 0)) {
7188 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7193 scsi_read_capacity(&ccb->csio,
7194 /*retries*/ retry_count,
7196 /*tag_action*/ task_attr,
7199 /*timeout*/ timeout ? timeout : 5000);
7201 /* Disable freezing the device queue */
7202 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7204 if (arglist & CAM_ARG_ERR_RECOVER)
7205 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7207 if (cam_send_ccb(device, ccb) < 0) {
7208 warn("error sending READ CAPACITY command");
7210 if (arglist & CAM_ARG_VERBOSE)
7211 cam_error_print(device, ccb, CAM_ESF_ALL,
7212 CAM_EPF_ALL, stderr);
7218 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7219 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7224 maxsector = scsi_4btoul(rcap.addr);
7225 block_len = scsi_4btoul(rcap.length);
7228 * A last block of 2^32-1 means that the true capacity is over 2TB,
7229 * and we need to issue the long READ CAPACITY to get the real
7230 * capacity. Otherwise, we're all set.
7232 if (maxsector != 0xffffffff)
7235 scsi_read_capacity_16(&ccb->csio,
7236 /*retries*/ retry_count,
7238 /*tag_action*/ task_attr,
7242 /*rcap_buf*/ (uint8_t *)&rcaplong,
7243 /*rcap_buf_len*/ sizeof(rcaplong),
7244 /*sense_len*/ SSD_FULL_SIZE,
7245 /*timeout*/ timeout ? timeout : 5000);
7247 /* Disable freezing the device queue */
7248 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7250 if (arglist & CAM_ARG_ERR_RECOVER)
7251 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7253 if (cam_send_ccb(device, ccb) < 0) {
7254 warn("error sending READ CAPACITY (16) command");
7256 if (arglist & CAM_ARG_VERBOSE)
7257 cam_error_print(device, ccb, CAM_ESF_ALL,
7258 CAM_EPF_ALL, stderr);
7264 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7265 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7270 maxsector = scsi_8btou64(rcaplong.addr);
7271 block_len = scsi_4btoul(rcaplong.length);
7274 if (blocksizeonly == 0) {
7276 * Humanize implies !quiet, and also implies numblocks.
7278 if (humanize != 0) {
7283 tmpbytes = (maxsector + 1) * block_len;
7284 ret = humanize_number(tmpstr, sizeof(tmpstr),
7285 tmpbytes, "", HN_AUTOSCALE,
7288 HN_DIVISOR_1000 : 0));
7290 warnx("%s: humanize_number failed!", __func__);
7294 fprintf(stdout, "Device Size: %s%s", tmpstr,
7295 (sizeonly == 0) ? ", " : "\n");
7296 } else if (numblocks != 0) {
7297 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7298 "Blocks: " : "", (uintmax_t)maxsector + 1,
7299 (sizeonly == 0) ? ", " : "\n");
7301 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7302 "Last Block: " : "", (uintmax_t)maxsector,
7303 (sizeonly == 0) ? ", " : "\n");
7307 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7308 "Block Length: " : "", block_len, (quiet == 0) ?
7317 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7318 int retry_count, int timeout)
7322 uint8_t *smp_request = NULL, *smp_response = NULL;
7323 int request_size = 0, response_size = 0;
7324 int fd_request = 0, fd_response = 0;
7325 char *datastr = NULL;
7326 struct get_hook hook;
7331 * Note that at the moment we don't support sending SMP CCBs to
7332 * devices that aren't probed by CAM.
7334 ccb = cam_getccb(device);
7336 warnx("%s: error allocating CCB", __func__);
7340 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7342 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7345 arglist |= CAM_ARG_CMD_IN;
7346 response_size = strtol(optarg, NULL, 0);
7347 if (response_size <= 0) {
7348 warnx("invalid number of response bytes %d",
7351 goto smpcmd_bailout;
7353 hook.argc = argc - optind;
7354 hook.argv = argv + optind;
7357 datastr = cget(&hook, NULL);
7359 * If the user supplied "-" instead of a format, he
7360 * wants the data to be written to stdout.
7362 if ((datastr != NULL)
7363 && (datastr[0] == '-'))
7366 smp_response = (u_int8_t *)malloc(response_size);
7367 if (smp_response == NULL) {
7368 warn("can't malloc memory for SMP response");
7370 goto smpcmd_bailout;
7374 arglist |= CAM_ARG_CMD_OUT;
7375 request_size = strtol(optarg, NULL, 0);
7376 if (request_size <= 0) {
7377 warnx("invalid number of request bytes %d",
7380 goto smpcmd_bailout;
7382 hook.argc = argc - optind;
7383 hook.argv = argv + optind;
7385 datastr = cget(&hook, NULL);
7386 smp_request = (u_int8_t *)malloc(request_size);
7387 if (smp_request == NULL) {
7388 warn("can't malloc memory for SMP request");
7390 goto smpcmd_bailout;
7392 bzero(smp_request, request_size);
7394 * If the user supplied "-" instead of a format, he
7395 * wants the data to be read from stdin.
7397 if ((datastr != NULL)
7398 && (datastr[0] == '-'))
7401 buff_encode_visit(smp_request, request_size,
7412 * If fd_data is set, and we're writing to the device, we need to
7413 * read the data the user wants written from stdin.
7415 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7417 int amt_to_read = request_size;
7418 u_int8_t *buf_ptr = smp_request;
7420 for (amt_read = 0; amt_to_read > 0;
7421 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7422 if (amt_read == -1) {
7423 warn("error reading data from stdin");
7425 goto smpcmd_bailout;
7427 amt_to_read -= amt_read;
7428 buf_ptr += amt_read;
7432 if (((arglist & CAM_ARG_CMD_IN) == 0)
7433 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7434 warnx("%s: need both the request (-r) and response (-R) "
7435 "arguments", __func__);
7437 goto smpcmd_bailout;
7440 flags |= CAM_DEV_QFRZDIS;
7442 cam_fill_smpio(&ccb->smpio,
7443 /*retries*/ retry_count,
7446 /*smp_request*/ smp_request,
7447 /*smp_request_len*/ request_size,
7448 /*smp_response*/ smp_response,
7449 /*smp_response_len*/ response_size,
7450 /*timeout*/ timeout ? timeout : 5000);
7452 ccb->smpio.flags = SMP_FLAG_NONE;
7454 if (((retval = cam_send_ccb(device, ccb)) < 0)
7455 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7456 const char warnstr[] = "error sending command";
7463 if (arglist & CAM_ARG_VERBOSE) {
7464 cam_error_print(device, ccb, CAM_ESF_ALL,
7465 CAM_EPF_ALL, stderr);
7469 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7470 && (response_size > 0)) {
7471 if (fd_response == 0) {
7472 buff_decode_visit(smp_response, response_size,
7473 datastr, arg_put, NULL);
7474 fprintf(stdout, "\n");
7476 ssize_t amt_written;
7477 int amt_to_write = response_size;
7478 u_int8_t *buf_ptr = smp_response;
7480 for (amt_written = 0; (amt_to_write > 0) &&
7481 (amt_written = write(STDOUT_FILENO, buf_ptr,
7482 amt_to_write)) > 0;){
7483 amt_to_write -= amt_written;
7484 buf_ptr += amt_written;
7486 if (amt_written == -1) {
7487 warn("error writing data to stdout");
7489 goto smpcmd_bailout;
7490 } else if ((amt_written == 0)
7491 && (amt_to_write > 0)) {
7492 warnx("only wrote %u bytes out of %u",
7493 response_size - amt_to_write,
7502 if (smp_request != NULL)
7505 if (smp_response != NULL)
7512 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7513 int retry_count, int timeout)
7517 int32_t mmc_opcode = 0, mmc_arg = 0;
7518 int32_t mmc_flags = -1;
7521 int is_bw_4 = 0, is_bw_1 = 0;
7522 int is_highspeed = 0, is_stdspeed = 0;
7523 int is_info_request = 0;
7525 uint8_t mmc_data_byte = 0;
7527 /* For IO_RW_EXTENDED command */
7528 uint8_t *mmc_data = NULL;
7529 struct mmc_data mmc_d;
7530 int mmc_data_len = 0;
7533 * Note that at the moment we don't support sending SMP CCBs to
7534 * devices that aren't probed by CAM.
7536 ccb = cam_getccb(device);
7538 warnx("%s: error allocating CCB", __func__);
7542 bzero(&(&ccb->ccb_h)[1],
7543 sizeof(union ccb) - sizeof(struct ccb_hdr));
7545 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7554 if (!strcmp(optarg, "high"))
7560 is_info_request = 1;
7563 mmc_opcode = strtol(optarg, NULL, 0);
7564 if (mmc_opcode < 0) {
7565 warnx("invalid MMC opcode %d",
7568 goto mmccmd_bailout;
7572 mmc_arg = strtol(optarg, NULL, 0);
7574 warnx("invalid MMC arg %d",
7577 goto mmccmd_bailout;
7581 mmc_flags = strtol(optarg, NULL, 0);
7582 if (mmc_flags < 0) {
7583 warnx("invalid MMC flags %d",
7586 goto mmccmd_bailout;
7590 mmc_data_len = strtol(optarg, NULL, 0);
7591 if (mmc_data_len <= 0) {
7592 warnx("invalid MMC data len %d",
7595 goto mmccmd_bailout;
7602 mmc_data_byte = strtol(optarg, NULL, 0);
7608 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7610 /* If flags are left default, supply the right flags */
7612 switch (mmc_opcode) {
7613 case MMC_GO_IDLE_STATE:
7614 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7616 case IO_SEND_OP_COND:
7617 mmc_flags = MMC_RSP_R4;
7619 case SD_SEND_RELATIVE_ADDR:
7620 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7622 case MMC_SELECT_CARD:
7623 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7624 mmc_arg = mmc_arg << 16;
7626 case SD_IO_RW_DIRECT:
7627 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7628 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7630 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7632 case SD_IO_RW_EXTENDED:
7633 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7634 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7635 int len_arg = mmc_data_len;
7636 if (mmc_data_len == 512)
7640 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7642 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7645 mmc_flags = MMC_RSP_R1;
7649 // Switch bus width instead of sending IO command
7650 if (is_bw_4 || is_bw_1) {
7651 struct ccb_trans_settings_mmc *cts;
7652 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7653 ccb->ccb_h.flags = 0;
7654 cts = &ccb->cts.proto_specific.mmc;
7655 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7656 cts->ios_valid = MMC_BW;
7657 if (((retval = cam_send_ccb(device, ccb)) < 0)
7658 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7659 warn("Error sending command");
7661 printf("Parameters set OK\n");
7667 // Switch bus speed instead of sending IO command
7668 if (is_stdspeed || is_highspeed) {
7669 struct ccb_trans_settings_mmc *cts;
7670 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7671 ccb->ccb_h.flags = 0;
7672 cts = &ccb->cts.proto_specific.mmc;
7673 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
7674 cts->ios_valid = MMC_BT;
7675 if (((retval = cam_send_ccb(device, ccb)) < 0)
7676 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7677 warn("Error sending command");
7679 printf("Speed set OK (HS: %d)\n", is_highspeed);
7685 // Get information about controller and its settings
7686 if (is_info_request) {
7687 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
7688 ccb->ccb_h.flags = 0;
7689 struct ccb_trans_settings_mmc *cts;
7690 cts = &ccb->cts.proto_specific.mmc;
7691 if (((retval = cam_send_ccb(device, ccb)) < 0)
7692 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7693 warn("Error sending command");
7696 printf("Host controller information\n");
7697 printf("Host OCR: 0x%x\n", cts->host_ocr);
7698 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
7699 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
7700 printf("Supported bus width: ");
7701 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
7703 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
7705 printf("\nCurrent settings:\n");
7706 printf("Bus width: ");
7707 switch (cts->ios.bus_width) {
7718 printf("Freq: %d.%03d MHz%s\n",
7719 cts->ios.clock / 1000000,
7720 (cts->ios.clock / 1000) % 1000,
7721 cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : "");
7725 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
7727 if (mmc_data_len > 0) {
7728 flags |= CAM_DIR_IN;
7729 mmc_data = malloc(mmc_data_len);
7730 memset(mmc_data, 0, mmc_data_len);
7731 mmc_d.len = mmc_data_len;
7732 mmc_d.data = mmc_data;
7733 mmc_d.flags = MMC_DATA_READ;
7734 } else flags |= CAM_DIR_NONE;
7736 cam_fill_mmcio(&ccb->mmcio,
7737 /*retries*/ retry_count,
7740 /*mmc_opcode*/ mmc_opcode,
7741 /*mmc_arg*/ mmc_arg,
7742 /*mmc_flags*/ mmc_flags,
7743 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
7744 /*timeout*/ timeout ? timeout : 5000);
7746 if (((retval = cam_send_ccb(device, ccb)) < 0)
7747 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7748 const char warnstr[] = "error sending command";
7755 if (arglist & CAM_ARG_VERBOSE) {
7756 cam_error_print(device, ccb, CAM_ESF_ALL,
7757 CAM_EPF_ALL, stderr);
7761 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
7762 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
7763 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
7764 ccb->mmcio.cmd.resp[1],
7765 ccb->mmcio.cmd.resp[2],
7766 ccb->mmcio.cmd.resp[3]);
7768 switch (mmc_opcode) {
7769 case SD_IO_RW_DIRECT:
7770 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
7771 SD_R5_DATA(ccb->mmcio.cmd.resp),
7772 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
7774 case SD_IO_RW_EXTENDED:
7775 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
7776 hexdump(mmc_data, mmc_data_len, NULL, 0);
7778 case SD_SEND_RELATIVE_ADDR:
7779 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
7782 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
7789 if (mmc_data_len > 0 && mmc_data != NULL)
7796 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7797 char *combinedopt, int retry_count, int timeout)
7800 struct smp_report_general_request *request = NULL;
7801 struct smp_report_general_response *response = NULL;
7802 struct sbuf *sb = NULL;
7804 int c, long_response = 0;
7808 * Note that at the moment we don't support sending SMP CCBs to
7809 * devices that aren't probed by CAM.
7811 ccb = cam_getccb(device);
7813 warnx("%s: error allocating CCB", __func__);
7817 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7819 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7828 request = malloc(sizeof(*request));
7829 if (request == NULL) {
7830 warn("%s: unable to allocate %zd bytes", __func__,
7836 response = malloc(sizeof(*response));
7837 if (response == NULL) {
7838 warn("%s: unable to allocate %zd bytes", __func__,
7845 smp_report_general(&ccb->smpio,
7849 /*request_len*/ sizeof(*request),
7850 (uint8_t *)response,
7851 /*response_len*/ sizeof(*response),
7852 /*long_response*/ long_response,
7855 if (((retval = cam_send_ccb(device, ccb)) < 0)
7856 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7857 const char warnstr[] = "error sending command";
7864 if (arglist & CAM_ARG_VERBOSE) {
7865 cam_error_print(device, ccb, CAM_ESF_ALL,
7866 CAM_EPF_ALL, stderr);
7873 * If the device supports the long response bit, try again and see
7874 * if we can get all of the data.
7876 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7877 && (long_response == 0)) {
7878 ccb->ccb_h.status = CAM_REQ_INPROG;
7879 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7885 * XXX KDM detect and decode SMP errors here.
7887 sb = sbuf_new_auto();
7889 warnx("%s: error allocating sbuf", __func__);
7893 smp_report_general_sbuf(response, sizeof(*response), sb);
7895 if (sbuf_finish(sb) != 0) {
7896 warnx("%s: sbuf_finish", __func__);
7900 printf("%s", sbuf_data(sb));
7906 if (request != NULL)
7909 if (response != NULL)
7918 static struct camcontrol_opts phy_ops[] = {
7919 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7920 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7921 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7922 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7923 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7924 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7925 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7926 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7927 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7932 smpphycontrol(struct cam_device *device, int argc, char **argv,
7933 char *combinedopt, int retry_count, int timeout)
7936 struct smp_phy_control_request *request = NULL;
7937 struct smp_phy_control_response *response = NULL;
7938 int long_response = 0;
7941 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7943 uint64_t attached_dev_name = 0;
7944 int dev_name_set = 0;
7945 uint32_t min_plr = 0, max_plr = 0;
7946 uint32_t pp_timeout_val = 0;
7947 int slumber_partial = 0;
7948 int set_pp_timeout_val = 0;
7952 * Note that at the moment we don't support sending SMP CCBs to
7953 * devices that aren't probed by CAM.
7955 ccb = cam_getccb(device);
7957 warnx("%s: error allocating CCB", __func__);
7961 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7963 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7971 if (strcasecmp(optarg, "enable") == 0)
7973 else if (strcasecmp(optarg, "disable") == 0)
7976 warnx("%s: Invalid argument %s", __func__,
7983 slumber_partial |= enable <<
7984 SMP_PC_SAS_SLUMBER_SHIFT;
7987 slumber_partial |= enable <<
7988 SMP_PC_SAS_PARTIAL_SHIFT;
7991 slumber_partial |= enable <<
7992 SMP_PC_SATA_SLUMBER_SHIFT;
7995 slumber_partial |= enable <<
7996 SMP_PC_SATA_PARTIAL_SHIFT;
7999 warnx("%s: programmer error", __func__);
8002 break; /*NOTREACHED*/
8007 attached_dev_name = (uintmax_t)strtoumax(optarg,
8016 * We don't do extensive checking here, so this
8017 * will continue to work when new speeds come out.
8019 min_plr = strtoul(optarg, NULL, 0);
8021 || (min_plr > 0xf)) {
8022 warnx("%s: invalid link rate %x",
8030 * We don't do extensive checking here, so this
8031 * will continue to work when new speeds come out.
8033 max_plr = strtoul(optarg, NULL, 0);
8035 || (max_plr > 0xf)) {
8036 warnx("%s: invalid link rate %x",
8043 camcontrol_optret optreturn;
8044 cam_argmask argnums;
8047 if (phy_op_set != 0) {
8048 warnx("%s: only one phy operation argument "
8049 "(-o) allowed", __func__);
8057 * Allow the user to specify the phy operation
8058 * numerically, as well as with a name. This will
8059 * future-proof it a bit, so options that are added
8060 * in future specs can be used.
8062 if (isdigit(optarg[0])) {
8063 phy_operation = strtoul(optarg, NULL, 0);
8064 if ((phy_operation == 0)
8065 || (phy_operation > 0xff)) {
8066 warnx("%s: invalid phy operation %#x",
8067 __func__, phy_operation);
8073 optreturn = getoption(phy_ops, optarg, &phy_operation,
8076 if (optreturn == CC_OR_AMBIGUOUS) {
8077 warnx("%s: ambiguous option %s", __func__,
8082 } else if (optreturn == CC_OR_NOT_FOUND) {
8083 warnx("%s: option %s not found", __func__,
8095 pp_timeout_val = strtoul(optarg, NULL, 0);
8096 if (pp_timeout_val > 15) {
8097 warnx("%s: invalid partial pathway timeout "
8098 "value %u, need a value less than 16",
8099 __func__, pp_timeout_val);
8103 set_pp_timeout_val = 1;
8111 warnx("%s: a PHY (-p phy) argument is required",__func__);
8116 if (((dev_name_set != 0)
8117 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8118 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8119 && (dev_name_set == 0))) {
8120 warnx("%s: -d name and -o setdevname arguments both "
8121 "required to set device name", __func__);
8126 request = malloc(sizeof(*request));
8127 if (request == NULL) {
8128 warn("%s: unable to allocate %zd bytes", __func__,
8134 response = malloc(sizeof(*response));
8135 if (response == NULL) {
8136 warn("%s: unable to allocate %zd bytes", __func__,
8142 smp_phy_control(&ccb->smpio,
8147 (uint8_t *)response,
8150 /*expected_exp_change_count*/ 0,
8153 (set_pp_timeout_val != 0) ? 1 : 0,
8161 if (((retval = cam_send_ccb(device, ccb)) < 0)
8162 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8163 const char warnstr[] = "error sending command";
8170 if (arglist & CAM_ARG_VERBOSE) {
8172 * Use CAM_EPF_NORMAL so we only get one line of
8173 * SMP command decoding.
8175 cam_error_print(device, ccb, CAM_ESF_ALL,
8176 CAM_EPF_NORMAL, stderr);
8182 /* XXX KDM print out something here for success? */
8187 if (request != NULL)
8190 if (response != NULL)
8197 smpmaninfo(struct cam_device *device, int argc, char **argv,
8198 char *combinedopt, int retry_count, int timeout)
8201 struct smp_report_manuf_info_request request;
8202 struct smp_report_manuf_info_response response;
8203 struct sbuf *sb = NULL;
8204 int long_response = 0;
8209 * Note that at the moment we don't support sending SMP CCBs to
8210 * devices that aren't probed by CAM.
8212 ccb = cam_getccb(device);
8214 warnx("%s: error allocating CCB", __func__);
8218 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8220 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8229 bzero(&request, sizeof(request));
8230 bzero(&response, sizeof(response));
8232 smp_report_manuf_info(&ccb->smpio,
8237 (uint8_t *)&response,
8242 if (((retval = cam_send_ccb(device, ccb)) < 0)
8243 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8244 const char warnstr[] = "error sending command";
8251 if (arglist & CAM_ARG_VERBOSE) {
8252 cam_error_print(device, ccb, CAM_ESF_ALL,
8253 CAM_EPF_ALL, stderr);
8259 sb = sbuf_new_auto();
8261 warnx("%s: error allocating sbuf", __func__);
8265 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8267 if (sbuf_finish(sb) != 0) {
8268 warnx("%s: sbuf_finish", __func__);
8272 printf("%s", sbuf_data(sb));
8286 getdevid(struct cam_devitem *item)
8289 union ccb *ccb = NULL;
8291 struct cam_device *dev;
8293 dev = cam_open_btl(item->dev_match.path_id,
8294 item->dev_match.target_id,
8295 item->dev_match.target_lun, O_RDWR, NULL);
8298 warnx("%s", cam_errbuf);
8303 item->device_id_len = 0;
8305 ccb = cam_getccb(dev);
8307 warnx("%s: error allocating CCB", __func__);
8312 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8315 * On the first try, we just probe for the size of the data, and
8316 * then allocate that much memory and try again.
8319 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8320 ccb->ccb_h.flags = CAM_DIR_IN;
8321 ccb->cdai.flags = CDAI_FLAG_NONE;
8322 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8323 ccb->cdai.bufsiz = item->device_id_len;
8324 if (item->device_id_len != 0)
8325 ccb->cdai.buf = (uint8_t *)item->device_id;
8327 if (cam_send_ccb(dev, ccb) < 0) {
8328 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8333 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8334 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8339 if (item->device_id_len == 0) {
8341 * This is our first time through. Allocate the buffer,
8342 * and then go back to get the data.
8344 if (ccb->cdai.provsiz == 0) {
8345 warnx("%s: invalid .provsiz field returned with "
8346 "XPT_GDEV_ADVINFO CCB", __func__);
8350 item->device_id_len = ccb->cdai.provsiz;
8351 item->device_id = malloc(item->device_id_len);
8352 if (item->device_id == NULL) {
8353 warn("%s: unable to allocate %d bytes", __func__,
8354 item->device_id_len);
8358 ccb->ccb_h.status = CAM_REQ_INPROG;
8364 cam_close_device(dev);
8373 * XXX KDM merge this code with getdevtree()?
8376 buildbusdevlist(struct cam_devlist *devlist)
8379 int bufsize, fd = -1;
8380 struct dev_match_pattern *patterns;
8381 struct cam_devitem *item = NULL;
8382 int skip_device = 0;
8385 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8386 warn("couldn't open %s", XPT_DEVICE);
8390 bzero(&ccb, sizeof(union ccb));
8392 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8393 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8394 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8396 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8397 bufsize = sizeof(struct dev_match_result) * 100;
8398 ccb.cdm.match_buf_len = bufsize;
8399 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8400 if (ccb.cdm.matches == NULL) {
8401 warnx("can't malloc memory for matches");
8405 ccb.cdm.num_matches = 0;
8406 ccb.cdm.num_patterns = 2;
8407 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8408 ccb.cdm.num_patterns;
8410 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8411 if (patterns == NULL) {
8412 warnx("can't malloc memory for patterns");
8417 ccb.cdm.patterns = patterns;
8418 bzero(patterns, ccb.cdm.pattern_buf_len);
8420 patterns[0].type = DEV_MATCH_DEVICE;
8421 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8422 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8423 patterns[1].type = DEV_MATCH_PERIPH;
8424 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8425 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8428 * We do the ioctl multiple times if necessary, in case there are
8429 * more than 100 nodes in the EDT.
8434 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8435 warn("error sending CAMIOCOMMAND ioctl");
8440 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8441 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8442 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8443 warnx("got CAM error %#x, CDM error %d\n",
8444 ccb.ccb_h.status, ccb.cdm.status);
8449 for (i = 0; i < ccb.cdm.num_matches; i++) {
8450 switch (ccb.cdm.matches[i].type) {
8451 case DEV_MATCH_DEVICE: {
8452 struct device_match_result *dev_result;
8455 &ccb.cdm.matches[i].result.device_result;
8457 if (dev_result->flags &
8458 DEV_RESULT_UNCONFIGURED) {
8464 item = malloc(sizeof(*item));
8466 warn("%s: unable to allocate %zd bytes",
8467 __func__, sizeof(*item));
8471 bzero(item, sizeof(*item));
8472 bcopy(dev_result, &item->dev_match,
8473 sizeof(*dev_result));
8474 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8477 if (getdevid(item) != 0) {
8483 case DEV_MATCH_PERIPH: {
8484 struct periph_match_result *periph_result;
8487 &ccb.cdm.matches[i].result.periph_result;
8489 if (skip_device != 0)
8491 item->num_periphs++;
8492 item->periph_matches = realloc(
8493 item->periph_matches,
8495 sizeof(struct periph_match_result));
8496 if (item->periph_matches == NULL) {
8497 warn("%s: error allocating periph "
8502 bcopy(periph_result, &item->periph_matches[
8503 item->num_periphs - 1],
8504 sizeof(*periph_result));
8508 fprintf(stderr, "%s: unexpected match "
8509 "type %d\n", __func__,
8510 ccb.cdm.matches[i].type);
8513 break; /*NOTREACHED*/
8516 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8517 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8525 free(ccb.cdm.matches);
8528 freebusdevlist(devlist);
8534 freebusdevlist(struct cam_devlist *devlist)
8536 struct cam_devitem *item, *item2;
8538 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8539 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8541 free(item->device_id);
8542 free(item->periph_matches);
8547 static struct cam_devitem *
8548 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8550 struct cam_devitem *item;
8552 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8553 struct scsi_vpd_id_descriptor *idd;
8556 * XXX KDM look for LUN IDs as well?
8558 idd = scsi_get_devid(item->device_id,
8559 item->device_id_len,
8560 scsi_devid_is_sas_target);
8564 if (scsi_8btou64(idd->identifier) == sasaddr)
8572 smpphylist(struct cam_device *device, int argc, char **argv,
8573 char *combinedopt, int retry_count, int timeout)
8575 struct smp_report_general_request *rgrequest = NULL;
8576 struct smp_report_general_response *rgresponse = NULL;
8577 struct smp_discover_request *disrequest = NULL;
8578 struct smp_discover_response *disresponse = NULL;
8579 struct cam_devlist devlist;
8581 int long_response = 0;
8588 * Note that at the moment we don't support sending SMP CCBs to
8589 * devices that aren't probed by CAM.
8591 ccb = cam_getccb(device);
8593 warnx("%s: error allocating CCB", __func__);
8597 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8598 STAILQ_INIT(&devlist.dev_queue);
8600 rgrequest = malloc(sizeof(*rgrequest));
8601 if (rgrequest == NULL) {
8602 warn("%s: unable to allocate %zd bytes", __func__,
8603 sizeof(*rgrequest));
8608 rgresponse = malloc(sizeof(*rgresponse));
8609 if (rgresponse == NULL) {
8610 warn("%s: unable to allocate %zd bytes", __func__,
8611 sizeof(*rgresponse));
8616 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8629 smp_report_general(&ccb->smpio,
8633 /*request_len*/ sizeof(*rgrequest),
8634 (uint8_t *)rgresponse,
8635 /*response_len*/ sizeof(*rgresponse),
8636 /*long_response*/ long_response,
8639 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8641 if (((retval = cam_send_ccb(device, ccb)) < 0)
8642 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8643 const char warnstr[] = "error sending command";
8650 if (arglist & CAM_ARG_VERBOSE) {
8651 cam_error_print(device, ccb, CAM_ESF_ALL,
8652 CAM_EPF_ALL, stderr);
8658 num_phys = rgresponse->num_phys;
8660 if (num_phys == 0) {
8662 fprintf(stdout, "%s: No Phys reported\n", __func__);
8667 devlist.path_id = device->path_id;
8669 retval = buildbusdevlist(&devlist);
8674 fprintf(stdout, "%d PHYs:\n", num_phys);
8675 fprintf(stdout, "PHY Attached SAS Address\n");
8678 disrequest = malloc(sizeof(*disrequest));
8679 if (disrequest == NULL) {
8680 warn("%s: unable to allocate %zd bytes", __func__,
8681 sizeof(*disrequest));
8686 disresponse = malloc(sizeof(*disresponse));
8687 if (disresponse == NULL) {
8688 warn("%s: unable to allocate %zd bytes", __func__,
8689 sizeof(*disresponse));
8694 for (i = 0; i < num_phys; i++) {
8695 struct cam_devitem *item;
8696 struct device_match_result *dev_match;
8697 char vendor[16], product[48], revision[16];
8701 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8703 ccb->ccb_h.status = CAM_REQ_INPROG;
8704 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8706 smp_discover(&ccb->smpio,
8710 sizeof(*disrequest),
8711 (uint8_t *)disresponse,
8712 sizeof(*disresponse),
8714 /*ignore_zone_group*/ 0,
8718 if (((retval = cam_send_ccb(device, ccb)) < 0)
8719 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
8720 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
8721 const char warnstr[] = "error sending command";
8728 if (arglist & CAM_ARG_VERBOSE) {
8729 cam_error_print(device, ccb, CAM_ESF_ALL,
8730 CAM_EPF_ALL, stderr);
8736 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
8738 fprintf(stdout, "%3d <vacant>\n", i);
8742 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
8745 item = findsasdevice(&devlist,
8746 scsi_8btou64(disresponse->attached_sas_address));
8750 || (item != NULL)) {
8751 fprintf(stdout, "%3d 0x%016jx", i,
8752 (uintmax_t)scsi_8btou64(
8753 disresponse->attached_sas_address));
8755 fprintf(stdout, "\n");
8758 } else if (quiet != 0)
8761 dev_match = &item->dev_match;
8763 if (dev_match->protocol == PROTO_SCSI) {
8764 cam_strvis(vendor, dev_match->inq_data.vendor,
8765 sizeof(dev_match->inq_data.vendor),
8767 cam_strvis(product, dev_match->inq_data.product,
8768 sizeof(dev_match->inq_data.product),
8770 cam_strvis(revision, dev_match->inq_data.revision,
8771 sizeof(dev_match->inq_data.revision),
8773 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8775 } else if ((dev_match->protocol == PROTO_ATA)
8776 || (dev_match->protocol == PROTO_SATAPM)) {
8777 cam_strvis(product, dev_match->ident_data.model,
8778 sizeof(dev_match->ident_data.model),
8780 cam_strvis(revision, dev_match->ident_data.revision,
8781 sizeof(dev_match->ident_data.revision),
8783 sprintf(tmpstr, "<%s %s>", product, revision);
8785 sprintf(tmpstr, "<>");
8787 fprintf(stdout, " %-33s ", tmpstr);
8790 * If we have 0 periphs, that's a bug...
8792 if (item->num_periphs == 0) {
8793 fprintf(stdout, "\n");
8797 fprintf(stdout, "(");
8798 for (j = 0; j < item->num_periphs; j++) {
8800 fprintf(stdout, ",");
8802 fprintf(stdout, "%s%d",
8803 item->periph_matches[j].periph_name,
8804 item->periph_matches[j].unit_number);
8807 fprintf(stdout, ")\n");
8821 freebusdevlist(&devlist);
8827 atapm(struct cam_device *device, int argc, char **argv,
8828 char *combinedopt, int retry_count, int timeout)
8836 ccb = cam_getccb(device);
8839 warnx("%s: error allocating ccb", __func__);
8843 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8852 if (strcmp(argv[1], "idle") == 0) {
8854 cmd = ATA_IDLE_IMMEDIATE;
8857 } else if (strcmp(argv[1], "standby") == 0) {
8859 cmd = ATA_STANDBY_IMMEDIATE;
8861 cmd = ATA_STANDBY_CMD;
8869 else if (t <= (240 * 5))
8871 else if (t <= (252 * 5))
8872 /* special encoding for 21 minutes */
8874 else if (t <= (11 * 30 * 60))
8875 sc = (t - 1) / (30 * 60) + 241;
8879 retval = ata_do_28bit_cmd(device,
8881 /*retries*/retry_count,
8882 /*flags*/CAM_DIR_NONE,
8883 /*protocol*/AP_PROTO_NON_DATA,
8884 /*tag_action*/MSG_SIMPLE_Q_TAG,
8891 /*timeout*/timeout ? timeout : 30 * 1000,
8899 ataaxm(struct cam_device *device, int argc, char **argv,
8900 char *combinedopt, int retry_count, int timeout)
8908 ccb = cam_getccb(device);
8911 warnx("%s: error allocating ccb", __func__);
8915 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8925 if (strcmp(argv[1], "apm") == 0) {
8941 retval = ata_do_28bit_cmd(device,
8943 /*retries*/retry_count,
8944 /*flags*/CAM_DIR_NONE,
8945 /*protocol*/AP_PROTO_NON_DATA,
8946 /*tag_action*/MSG_SIMPLE_Q_TAG,
8947 /*command*/ATA_SETFEATURES,
8953 /*timeout*/timeout ? timeout : 30 * 1000,
8961 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
8962 int show_sa_errors, int sa_set, int service_action,
8963 int timeout_desc, int task_attr, int retry_count, int timeout,
8964 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
8966 union ccb *ccb = NULL;
8967 uint8_t *buf = NULL;
8968 uint32_t alloc_len = 0, num_opcodes;
8969 uint32_t valid_len = 0;
8970 uint32_t avail_len = 0;
8971 struct scsi_report_supported_opcodes_all *all_hdr;
8972 struct scsi_report_supported_opcodes_one *one;
8977 * Make it clear that we haven't yet allocated or filled anything.
8982 ccb = cam_getccb(device);
8984 warnx("couldn't allocate CCB");
8989 /* cam_getccb cleans up the header, caller has to zero the payload */
8990 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8992 if (opcode_set != 0) {
8993 options |= RSO_OPTIONS_OC;
8995 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
8998 alloc_len = sizeof(*all_hdr) + (num_opcodes *
8999 sizeof(struct scsi_report_supported_opcodes_descr));
9002 if (timeout_desc != 0) {
9003 options |= RSO_RCTD;
9004 alloc_len += num_opcodes *
9005 sizeof(struct scsi_report_supported_opcodes_timeout);
9009 options |= RSO_OPTIONS_OC_SA;
9010 if (show_sa_errors != 0)
9011 options &= ~RSO_OPTIONS_OC;
9020 buf = malloc(alloc_len);
9022 warn("Unable to allocate %u bytes", alloc_len);
9026 bzero(buf, alloc_len);
9028 scsi_report_supported_opcodes(&ccb->csio,
9029 /*retries*/ retry_count,
9031 /*tag_action*/ task_attr,
9032 /*options*/ options,
9033 /*req_opcode*/ opcode,
9034 /*req_service_action*/ service_action,
9036 /*dxfer_len*/ alloc_len,
9037 /*sense_len*/ SSD_FULL_SIZE,
9038 /*timeout*/ timeout ? timeout : 10000);
9040 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9042 if (retry_count != 0)
9043 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9045 if (cam_send_ccb(device, ccb) < 0) {
9046 perror("error sending REPORT SUPPORTED OPERATION CODES");
9051 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9052 if (verbosemode != 0)
9053 cam_error_print(device, ccb, CAM_ESF_ALL,
9054 CAM_EPF_ALL, stderr);
9059 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9061 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9062 && (valid_len >= sizeof(*all_hdr))) {
9063 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9064 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9065 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9066 && (valid_len >= sizeof(*one))) {
9067 uint32_t cdb_length;
9069 one = (struct scsi_report_supported_opcodes_one *)buf;
9070 cdb_length = scsi_2btoul(one->cdb_length);
9071 avail_len = sizeof(*one) + cdb_length;
9072 if (one->support & RSO_ONE_CTDP) {
9073 struct scsi_report_supported_opcodes_timeout *td;
9075 td = (struct scsi_report_supported_opcodes_timeout *)
9077 if (valid_len >= (avail_len + sizeof(td->length))) {
9078 avail_len += scsi_2btoul(td->length) +
9081 avail_len += sizeof(*td);
9087 * avail_len could be zero if we didn't get enough data back from
9088 * thet target to determine
9090 if ((avail_len != 0)
9091 && (avail_len > valid_len)) {
9092 alloc_len = avail_len;
9096 *fill_len = valid_len;
9108 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9109 int req_sa, uint8_t *buf, uint32_t valid_len)
9111 struct scsi_report_supported_opcodes_one *one;
9112 struct scsi_report_supported_opcodes_timeout *td;
9113 uint32_t cdb_len = 0, td_len = 0;
9114 const char *op_desc = NULL;
9118 one = (struct scsi_report_supported_opcodes_one *)buf;
9121 * If we don't have the full single opcode descriptor, no point in
9124 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9126 warnx("Only %u bytes returned, not enough to verify support",
9132 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9134 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9137 printf(", SA 0x%x", req_sa);
9140 switch (one->support & RSO_ONE_SUP_MASK) {
9141 case RSO_ONE_SUP_UNAVAIL:
9142 printf("No command support information currently available\n");
9144 case RSO_ONE_SUP_NOT_SUP:
9145 printf("Command not supported\n");
9148 break; /*NOTREACHED*/
9149 case RSO_ONE_SUP_AVAIL:
9150 printf("Command is supported, complies with a SCSI standard\n");
9152 case RSO_ONE_SUP_VENDOR:
9153 printf("Command is supported, vendor-specific "
9154 "implementation\n");
9157 printf("Unknown command support flags 0x%#x\n",
9158 one->support & RSO_ONE_SUP_MASK);
9163 * If we don't have the CDB length, it isn't exactly an error, the
9164 * command probably isn't supported.
9166 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9170 cdb_len = scsi_2btoul(one->cdb_length);
9173 * If our valid data doesn't include the full reported length,
9174 * return. The caller should have detected this and adjusted his
9175 * allocation length to get all of the available data.
9177 if (valid_len < sizeof(*one) + cdb_len) {
9183 * If all we have is the opcode, there is no point in printing out
9191 printf("CDB usage bitmap:");
9192 for (i = 0; i < cdb_len; i++) {
9193 printf(" %02x", one->cdb_usage[i]);
9198 * If we don't have a timeout descriptor, we're done.
9200 if ((one->support & RSO_ONE_CTDP) == 0)
9204 * If we don't have enough valid length to include the timeout
9205 * descriptor length, we're done.
9207 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9210 td = (struct scsi_report_supported_opcodes_timeout *)
9211 &buf[sizeof(*one) + cdb_len];
9212 td_len = scsi_2btoul(td->length);
9213 td_len += sizeof(td->length);
9216 * If we don't have the full timeout descriptor, we're done.
9218 if (td_len < sizeof(*td))
9222 * If we don't have enough valid length to contain the full timeout
9223 * descriptor, we're done.
9225 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9228 printf("Timeout information:\n");
9229 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9230 printf("Nominal timeout: %u seconds\n",
9231 scsi_4btoul(td->nominal_time));
9232 printf("Recommended timeout: %u seconds\n",
9233 scsi_4btoul(td->recommended_time));
9240 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9243 struct scsi_report_supported_opcodes_all *hdr;
9244 struct scsi_report_supported_opcodes_descr *desc;
9245 uint32_t avail_len = 0, used_len = 0;
9249 if (valid_len < sizeof(*hdr)) {
9250 warnx("%s: not enough returned data (%u bytes) opcode list",
9251 __func__, valid_len);
9255 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9256 avail_len = scsi_4btoul(hdr->length);
9257 avail_len += sizeof(hdr->length);
9259 * Take the lesser of the amount of data the drive claims is
9260 * available, and the amount of data the HBA says was returned.
9262 avail_len = MIN(avail_len, valid_len);
9264 used_len = sizeof(hdr->length);
9266 printf("%-6s %4s %8s ",
9267 "Opcode", "SA", "CDB len" );
9270 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9271 printf(" Description\n");
9273 while ((avail_len - used_len) > sizeof(*desc)) {
9274 struct scsi_report_supported_opcodes_timeout *td;
9276 const char *op_desc = NULL;
9278 cur_ptr = &buf[used_len];
9279 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9281 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9282 if (op_desc == NULL)
9283 op_desc = "UNKNOWN";
9285 printf("0x%02x %#4x %8u ", desc->opcode,
9286 scsi_2btoul(desc->service_action),
9287 scsi_2btoul(desc->cdb_length));
9289 used_len += sizeof(*desc);
9291 if ((desc->flags & RSO_CTDP) == 0) {
9292 printf(" %s\n", op_desc);
9297 * If we don't have enough space to fit a timeout
9298 * descriptor, then we're done.
9300 if (avail_len - used_len < sizeof(*td)) {
9301 used_len = avail_len;
9302 printf(" %s\n", op_desc);
9305 cur_ptr = &buf[used_len];
9306 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9307 td_len = scsi_2btoul(td->length);
9308 td_len += sizeof(td->length);
9312 * If the given timeout descriptor length is less than what
9313 * we understand, skip it.
9315 if (td_len < sizeof(*td)) {
9316 printf(" %s\n", op_desc);
9320 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9321 scsi_4btoul(td->nominal_time),
9322 scsi_4btoul(td->recommended_time), op_desc);
9329 scsiopcodes(struct cam_device *device, int argc, char **argv,
9330 char *combinedopt, int task_attr, int retry_count, int timeout,
9334 uint32_t opcode = 0, service_action = 0;
9335 int td_set = 0, opcode_set = 0, sa_set = 0;
9336 int show_sa_errors = 1;
9337 uint32_t valid_len = 0;
9338 uint8_t *buf = NULL;
9342 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9348 opcode = strtoul(optarg, &endptr, 0);
9349 if (*endptr != '\0') {
9350 warnx("Invalid opcode \"%s\", must be a number",
9355 if (opcode > 0xff) {
9356 warnx("Invalid opcode 0x%#x, must be between"
9357 "0 and 0xff inclusive", opcode);
9364 service_action = strtoul(optarg, &endptr, 0);
9365 if (*endptr != '\0') {
9366 warnx("Invalid service action \"%s\", must "
9367 "be a number", optarg);
9371 if (service_action > 0xffff) {
9372 warnx("Invalid service action 0x%#x, must "
9373 "be between 0 and 0xffff inclusive",
9388 && (opcode_set == 0)) {
9389 warnx("You must specify an opcode with -o if a service "
9394 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9395 sa_set, service_action, td_set, task_attr,
9396 retry_count, timeout, verbosemode, &valid_len,
9401 if ((opcode_set != 0)
9403 retval = scsiprintoneopcode(device, opcode, sa_set,
9404 service_action, buf, valid_len);
9406 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9415 #endif /* MINIMALISTIC */
9418 scsireprobe(struct cam_device *device)
9423 ccb = cam_getccb(device);
9426 warnx("%s: error allocating ccb", __func__);
9430 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9432 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9434 if (cam_send_ccb(device, ccb) < 0) {
9435 warn("error sending XPT_REPROBE_LUN CCB");
9440 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9441 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9453 usage(int printlong)
9456 fprintf(printlong ? stdout : stderr,
9457 "usage: camcontrol <command> [device id][generic args][command args]\n"
9458 " camcontrol devlist [-b] [-v]\n"
9459 #ifndef MINIMALISTIC
9460 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9461 " camcontrol tur [dev_id][generic args]\n"
9462 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9463 " camcontrol identify [dev_id][generic args] [-v]\n"
9464 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9465 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9467 " camcontrol start [dev_id][generic args]\n"
9468 " camcontrol stop [dev_id][generic args]\n"
9469 " camcontrol load [dev_id][generic args]\n"
9470 " camcontrol eject [dev_id][generic args]\n"
9471 " camcontrol reprobe [dev_id][generic args]\n"
9472 #endif /* MINIMALISTIC */
9473 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9474 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9475 #ifndef MINIMALISTIC
9476 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9477 " [-q][-s][-S offset][-X]\n"
9478 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9479 " [-P pagectl][-e | -b][-d]\n"
9480 " camcontrol cmd [dev_id][generic args]\n"
9481 " <-a cmd [args] | -c cmd [args]>\n"
9482 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9483 " camcontrol smpcmd [dev_id][generic args]\n"
9484 " <-r len fmt [args]> <-R len fmt [args]>\n"
9485 " camcontrol smprg [dev_id][generic args][-l]\n"
9486 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9487 " [-o operation][-d name][-m rate][-M rate]\n"
9488 " [-T pp_timeout][-a enable|disable]\n"
9489 " [-A enable|disable][-s enable|disable]\n"
9490 " [-S enable|disable]\n"
9491 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9492 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9493 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9494 " <all|bus[:target[:lun]]|off>\n"
9495 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9496 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9497 " [-D <enable|disable>][-M mode][-O offset]\n"
9498 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9499 " [-U][-W bus_width]\n"
9500 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9501 " camcontrol sanitize [dev_id][generic args]\n"
9502 " [-a overwrite|block|crypto|exitfailure]\n"
9503 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9505 " camcontrol idle [dev_id][generic args][-t time]\n"
9506 " camcontrol standby [dev_id][generic args][-t time]\n"
9507 " camcontrol sleep [dev_id][generic args]\n"
9508 " camcontrol apm [dev_id][generic args][-l level]\n"
9509 " camcontrol aam [dev_id][generic args][-l level]\n"
9510 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9512 " camcontrol security [dev_id][generic args]\n"
9513 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9514 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9515 " [-U <user|master>] [-y]\n"
9516 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9517 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9518 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9519 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9520 " [-s scope][-S][-T type][-U]\n"
9521 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9522 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9523 " [-p part][-s start][-T type][-V vol]\n"
9524 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9526 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9527 " [-o rep_opts] [-P print_opts]\n"
9528 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9529 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9530 " [-S power_src] [-T timer]\n"
9531 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9532 " <-s <-f format -T time | -U >>\n"
9534 #endif /* MINIMALISTIC */
9535 " camcontrol help\n");
9538 #ifndef MINIMALISTIC
9540 "Specify one of the following options:\n"
9541 "devlist list all CAM devices\n"
9542 "periphlist list all CAM peripheral drivers attached to a device\n"
9543 "tur send a test unit ready to the named device\n"
9544 "inquiry send a SCSI inquiry command to the named device\n"
9545 "identify send a ATA identify command to the named device\n"
9546 "reportluns send a SCSI report luns command to the device\n"
9547 "readcap send a SCSI read capacity command to the device\n"
9548 "start send a Start Unit command to the device\n"
9549 "stop send a Stop Unit command to the device\n"
9550 "load send a Start Unit command to the device with the load bit set\n"
9551 "eject send a Stop Unit command to the device with the eject bit set\n"
9552 "reprobe update capacity information of the given device\n"
9553 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9554 "reset reset all buses, the given bus, bus:target:lun or device\n"
9555 "defects read the defect list of the specified device\n"
9556 "modepage display or edit (-e) the given mode page\n"
9557 "cmd send the given SCSI command, may need -i or -o as well\n"
9558 "smpcmd send the given SMP command, requires -o and -i\n"
9559 "smprg send the SMP Report General command\n"
9560 "smppc send the SMP PHY Control command, requires -p\n"
9561 "smpphylist display phys attached to a SAS expander\n"
9562 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9563 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9564 "tags report or set the number of transaction slots for a device\n"
9565 "negotiate report or set device negotiation parameters\n"
9566 "format send the SCSI FORMAT UNIT command to the named device\n"
9567 "sanitize send the SCSI SANITIZE command to the named device\n"
9568 "idle send the ATA IDLE command to the named device\n"
9569 "standby send the ATA STANDBY command to the named device\n"
9570 "sleep send the ATA SLEEP command to the named device\n"
9571 "fwdownload program firmware of the named device with the given image\n"
9572 "security report or send ATA security commands to the named device\n"
9573 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9574 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9575 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9576 "zone manage Zoned Block (Shingled) devices\n"
9577 "epc send ATA Extended Power Conditions commands\n"
9578 "timestamp report or set the device's timestamp\n"
9579 "help this message\n"
9580 "Device Identifiers:\n"
9581 "bus:target specify the bus and target, lun defaults to 0\n"
9582 "bus:target:lun specify the bus, target and lun\n"
9583 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
9584 "Generic arguments:\n"
9585 "-v be verbose, print out sense information\n"
9586 "-t timeout command timeout in seconds, overrides default timeout\n"
9587 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
9588 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
9589 "-E have the kernel attempt to perform SCSI error recovery\n"
9590 "-C count specify the SCSI command retry count (needs -E to work)\n"
9591 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
9592 "modepage arguments:\n"
9593 "-l list all available mode pages\n"
9594 "-m page specify the mode page to view or edit\n"
9595 "-e edit the specified mode page\n"
9596 "-b force view to binary mode\n"
9597 "-d disable block descriptors for mode sense\n"
9598 "-P pgctl page control field 0-3\n"
9599 "defects arguments:\n"
9600 "-f format specify defect list format (block, bfi or phys)\n"
9601 "-G get the grown defect list\n"
9602 "-P get the permanent defect list\n"
9603 "inquiry arguments:\n"
9604 "-D get the standard inquiry data\n"
9605 "-S get the serial number\n"
9606 "-R get the transfer rate, etc.\n"
9607 "reportluns arguments:\n"
9608 "-c only report a count of available LUNs\n"
9609 "-l only print out luns, and not a count\n"
9610 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
9611 "readcap arguments\n"
9612 "-b only report the blocksize\n"
9613 "-h human readable device size, base 2\n"
9614 "-H human readable device size, base 10\n"
9615 "-N print the number of blocks instead of last block\n"
9616 "-q quiet, print numbers only\n"
9617 "-s only report the last block/device size\n"
9619 "-c cdb [args] specify the SCSI CDB\n"
9620 "-i len fmt specify input data and input data format\n"
9621 "-o len fmt [args] specify output data and output data fmt\n"
9622 "smpcmd arguments:\n"
9623 "-r len fmt [args] specify the SMP command to be sent\n"
9624 "-R len fmt [args] specify SMP response format\n"
9625 "smprg arguments:\n"
9626 "-l specify the long response format\n"
9627 "smppc arguments:\n"
9628 "-p phy specify the PHY to operate on\n"
9629 "-l specify the long request/response format\n"
9630 "-o operation specify the phy control operation\n"
9631 "-d name set the attached device name\n"
9632 "-m rate set the minimum physical link rate\n"
9633 "-M rate set the maximum physical link rate\n"
9634 "-T pp_timeout set the partial pathway timeout value\n"
9635 "-a enable|disable enable or disable SATA slumber\n"
9636 "-A enable|disable enable or disable SATA partial phy power\n"
9637 "-s enable|disable enable or disable SAS slumber\n"
9638 "-S enable|disable enable or disable SAS partial phy power\n"
9639 "smpphylist arguments:\n"
9640 "-l specify the long response format\n"
9641 "-q only print phys with attached devices\n"
9642 "smpmaninfo arguments:\n"
9643 "-l specify the long response format\n"
9644 "debug arguments:\n"
9645 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
9646 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
9647 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
9648 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
9650 "-N tags specify the number of tags to use for this device\n"
9651 "-q be quiet, don't report the number of tags\n"
9652 "-v report a number of tag-related parameters\n"
9653 "negotiate arguments:\n"
9654 "-a send a test unit ready after negotiation\n"
9655 "-c report/set current negotiation settings\n"
9656 "-D <arg> \"enable\" or \"disable\" disconnection\n"
9657 "-M mode set ATA mode\n"
9658 "-O offset set command delay offset\n"
9659 "-q be quiet, don't report anything\n"
9660 "-R syncrate synchronization rate in MHz\n"
9661 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
9662 "-U report/set user negotiation settings\n"
9663 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
9664 "-v also print a Path Inquiry CCB for the controller\n"
9665 "format arguments:\n"
9666 "-q be quiet, don't print status messages\n"
9667 "-r run in report only mode\n"
9668 "-w don't send immediate format command\n"
9669 "-y don't ask any questions\n"
9670 "sanitize arguments:\n"
9671 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
9672 "-c passes overwrite passes to perform (1 to 31)\n"
9673 "-I invert overwrite pattern after each pass\n"
9674 "-P pattern path to overwrite pattern file\n"
9675 "-q be quiet, don't print status messages\n"
9676 "-r run in report only mode\n"
9677 "-U run operation in unrestricted completion exit mode\n"
9678 "-w don't send immediate sanitize command\n"
9679 "-y don't ask any questions\n"
9680 "idle/standby arguments:\n"
9681 "-t <arg> number of seconds before respective state.\n"
9682 "fwdownload arguments:\n"
9683 "-f fw_image path to firmware image file\n"
9684 "-q don't print informational messages, only errors\n"
9685 "-s run in simulation mode\n"
9686 "-v print info for every firmware segment sent to device\n"
9687 "-y don't ask any questions\n"
9688 "security arguments:\n"
9689 "-d pwd disable security using the given password for the selected\n"
9691 "-e pwd erase the device using the given pwd for the selected user\n"
9692 "-f freeze the security configuration of the specified device\n"
9693 "-h pwd enhanced erase the device using the given pwd for the\n"
9695 "-k pwd unlock the device using the given pwd for the selected\n"
9697 "-l <high|maximum> specifies which security level to set: high or maximum\n"
9698 "-q be quiet, do not print any status messages\n"
9699 "-s pwd password the device (enable security) using the given\n"
9700 " pwd for the selected user\n"
9701 "-T timeout overrides the timeout (seconds) used for erase operation\n"
9702 "-U <user|master> specifies which user to set: user or master\n"
9703 "-y don't ask any questions\n"
9705 "-f freeze the HPA configuration of the device\n"
9706 "-l lock the HPA configuration of the device\n"
9707 "-P make the HPA max sectors persist\n"
9708 "-p pwd Set the HPA configuration password required for unlock\n"
9710 "-q be quiet, do not print any status messages\n"
9711 "-s sectors configures the maximum user accessible sectors of the\n"
9713 "-U pwd unlock the HPA configuration of the device\n"
9714 "-y don't ask any questions\n"
9715 "persist arguments:\n"
9716 "-i action specify read_keys, read_reservation, report_cap, or\n"
9717 " read_full_status\n"
9718 "-o action specify register, register_ignore, reserve, release,\n"
9719 " clear, preempt, preempt_abort, register_move, replace_lost\n"
9720 "-a set the All Target Ports (ALL_TG_PT) bit\n"
9721 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
9722 "-k key specify the Reservation Key\n"
9723 "-K sa_key specify the Service Action Reservation Key\n"
9724 "-p set the Activate Persist Through Power Loss bit\n"
9725 "-R rtp specify the Relative Target Port\n"
9726 "-s scope specify the scope: lun, extent, element or a number\n"
9727 "-S specify Transport ID for register, requires -I\n"
9728 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
9729 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
9730 "-U unregister the current initiator for register_move\n"
9731 "attrib arguments:\n"
9732 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
9734 "-w attr specify an attribute to write, one -w argument per attr\n"
9735 "-a attr_num only display this attribute number\n"
9736 "-c get cached attributes\n"
9737 "-e elem_addr request attributes for the given element in a changer\n"
9738 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
9739 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
9740 " field_none, field_desc, field_num, field_size, field_rw\n"
9741 "-p partition request attributes for the given partition\n"
9742 "-s start_attr request attributes starting at the given number\n"
9743 "-T elem_type specify the element type (used with -e)\n"
9744 "-V logical_vol specify the logical volume ID\n"
9745 "opcodes arguments:\n"
9746 "-o opcode specify the individual opcode to list\n"
9747 "-s service_action specify the service action for the opcode\n"
9748 "-N do not return SCSI error for unsupported SA\n"
9749 "-T request nominal and recommended timeout values\n"
9751 "-c cmd required: rz, open, close, finish, or rwp\n"
9752 "-a apply the action to all zones\n"
9753 "-l LBA specify the zone starting LBA\n"
9754 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
9755 " closed, full, ro, offline, reset, nonseq, nonwp\n"
9756 "-P print_opt report zones printing: normal, summary, script\n"
9758 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
9759 " source, status, list\n"
9760 "-d disable power mode (timer, state)\n"
9761 "-D delayed entry (goto)\n"
9762 "-e enable power mode (timer, state)\n"
9763 "-H hold power mode (goto)\n"
9764 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
9766 "-P only display power mode (status)\n"
9767 "-r rst_src restore settings from: default, saved (restore)\n"
9768 "-s save mode (timer, state, restore)\n"
9769 "-S power_src set power source: battery, nonbattery (source)\n"
9770 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
9771 "timestamp arguments:\n"
9772 "-r report the timestamp of the device\n"
9773 "-f format report the timestamp of the device with the given\n"
9774 " strftime(3) format string\n"
9775 "-m report the timestamp of the device as milliseconds since\n"
9776 " January 1st, 1970\n"
9777 "-U report the time with UTC instead of the local time zone\n"
9778 "-s set the timestamp of the device\n"
9779 "-f format the format of the time string passed into strptime(3)\n"
9780 "-T time the time value passed into strptime(3)\n"
9781 "-U set the timestamp of the device to UTC time\n"
9783 #endif /* MINIMALISTIC */
9787 main(int argc, char **argv)
9790 char *device = NULL;
9792 struct cam_device *cam_dev = NULL;
9793 int timeout = 0, retry_count = 1;
9794 camcontrol_optret optreturn;
9796 const char *mainopt = "C:En:Q:t:u:v";
9797 const char *subopt = NULL;
9798 char combinedopt[256];
9799 int error = 0, optstart = 2;
9800 int task_attr = MSG_SIMPLE_Q_TAG;
9802 #ifndef MINIMALISTIC
9806 #endif /* MINIMALISTIC */
9808 cmdlist = CAM_CMD_NONE;
9809 arglist = CAM_ARG_NONE;
9817 * Get the base option.
9819 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
9821 if (optreturn == CC_OR_AMBIGUOUS) {
9822 warnx("ambiguous option %s", argv[1]);
9825 } else if (optreturn == CC_OR_NOT_FOUND) {
9826 warnx("option %s not found", argv[1]);
9832 * Ahh, getopt(3) is a pain.
9834 * This is a gross hack. There really aren't many other good
9835 * options (excuse the pun) for parsing options in a situation like
9836 * this. getopt is kinda braindead, so you end up having to run
9837 * through the options twice, and give each invocation of getopt
9838 * the option string for the other invocation.
9840 * You would think that you could just have two groups of options.
9841 * The first group would get parsed by the first invocation of
9842 * getopt, and the second group would get parsed by the second
9843 * invocation of getopt. It doesn't quite work out that way. When
9844 * the first invocation of getopt finishes, it leaves optind pointing
9845 * to the argument _after_ the first argument in the second group.
9846 * So when the second invocation of getopt comes around, it doesn't
9847 * recognize the first argument it gets and then bails out.
9849 * A nice alternative would be to have a flag for getopt that says
9850 * "just keep parsing arguments even when you encounter an unknown
9851 * argument", but there isn't one. So there's no real clean way to
9852 * easily parse two sets of arguments without having one invocation
9853 * of getopt know about the other.
9855 * Without this hack, the first invocation of getopt would work as
9856 * long as the generic arguments are first, but the second invocation
9857 * (in the subfunction) would fail in one of two ways. In the case
9858 * where you don't set optreset, it would fail because optind may be
9859 * pointing to the argument after the one it should be pointing at.
9860 * In the case where you do set optreset, and reset optind, it would
9861 * fail because getopt would run into the first set of options, which
9862 * it doesn't understand.
9864 * All of this would "sort of" work if you could somehow figure out
9865 * whether optind had been incremented one option too far. The
9866 * mechanics of that, however, are more daunting than just giving
9867 * both invocations all of the expect options for either invocation.
9869 * Needless to say, I wouldn't mind if someone invented a better
9870 * (non-GPL!) command line parsing interface than getopt. I
9871 * wouldn't mind if someone added more knobs to getopt to make it
9872 * work better. Who knows, I may talk myself into doing it someday,
9873 * if the standards weenies let me. As it is, it just leads to
9874 * hackery like this and causes people to avoid it in some cases.
9876 * KDM, September 8th, 1998
9879 sprintf(combinedopt, "%s%s", mainopt, subopt);
9881 sprintf(combinedopt, "%s", mainopt);
9884 * For these options we do not parse optional device arguments and
9885 * we do not open a passthrough device.
9887 if ((cmdlist == CAM_CMD_RESCAN)
9888 || (cmdlist == CAM_CMD_RESET)
9889 || (cmdlist == CAM_CMD_DEVTREE)
9890 || (cmdlist == CAM_CMD_USAGE)
9891 || (cmdlist == CAM_CMD_DEBUG))
9894 #ifndef MINIMALISTIC
9896 && (argc > 2 && argv[2][0] != '-')) {
9900 if (isdigit(argv[2][0])) {
9901 /* device specified as bus:target[:lun] */
9902 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9904 errx(1, "numeric device specification must "
9905 "be either bus:target, or "
9907 /* default to 0 if lun was not specified */
9908 if ((arglist & CAM_ARG_LUN) == 0) {
9910 arglist |= CAM_ARG_LUN;
9914 if (cam_get_device(argv[2], name, sizeof name, &unit)
9916 errx(1, "%s", cam_errbuf);
9917 device = strdup(name);
9918 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
9922 #endif /* MINIMALISTIC */
9924 * Start getopt processing at argv[2/3], since we've already
9925 * accepted argv[1..2] as the command name, and as a possible
9931 * Now we run through the argument list looking for generic
9932 * options, and ignoring options that possibly belong to
9935 while ((c = getopt(argc, argv, combinedopt))!= -1){
9938 retry_count = strtol(optarg, NULL, 0);
9939 if (retry_count < 0)
9940 errx(1, "retry count %d is < 0",
9942 arglist |= CAM_ARG_RETRIES;
9945 arglist |= CAM_ARG_ERR_RECOVER;
9948 arglist |= CAM_ARG_DEVICE;
9950 while (isspace(*tstr) && (*tstr != '\0'))
9952 device = (char *)strdup(tstr);
9956 int table_entry = 0;
9959 while (isspace(*tstr) && (*tstr != '\0'))
9961 if (isdigit(*tstr)) {
9962 task_attr = strtol(tstr, &endptr, 0);
9963 if (*endptr != '\0') {
9964 errx(1, "Invalid queue option "
9969 scsi_nv_status status;
9971 table_size = sizeof(task_attrs) /
9972 sizeof(task_attrs[0]);
9973 status = scsi_get_nv(task_attrs,
9974 table_size, tstr, &table_entry,
9975 SCSI_NV_FLAG_IG_CASE);
9976 if (status == SCSI_NV_FOUND)
9977 task_attr = task_attrs[
9980 errx(1, "%s option %s",
9981 (status == SCSI_NV_AMBIGUOUS)?
9982 "ambiguous" : "invalid",
9989 timeout = strtol(optarg, NULL, 0);
9991 errx(1, "invalid timeout %d", timeout);
9992 /* Convert the timeout from seconds to ms */
9994 arglist |= CAM_ARG_TIMEOUT;
9997 arglist |= CAM_ARG_UNIT;
9998 unit = strtol(optarg, NULL, 0);
10001 arglist |= CAM_ARG_VERBOSE;
10008 #ifndef MINIMALISTIC
10010 * For most commands we'll want to open the passthrough device
10011 * associated with the specified device. In the case of the rescan
10012 * commands, we don't use a passthrough device at all, just the
10013 * transport layer device.
10015 if (devopen == 1) {
10016 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10017 && (((arglist & CAM_ARG_DEVICE) == 0)
10018 || ((arglist & CAM_ARG_UNIT) == 0))) {
10019 errx(1, "subcommand \"%s\" requires a valid device "
10020 "identifier", argv[1]);
10023 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10024 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10025 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10027 errx(1,"%s", cam_errbuf);
10029 #endif /* MINIMALISTIC */
10032 * Reset optind to 2, and reset getopt, so these routines can parse
10033 * the arguments again.
10039 #ifndef MINIMALISTIC
10040 case CAM_CMD_DEVLIST:
10041 error = getdevlist(cam_dev);
10044 error = atahpa(cam_dev, retry_count, timeout,
10045 argc, argv, combinedopt);
10047 #endif /* MINIMALISTIC */
10048 case CAM_CMD_DEVTREE:
10049 error = getdevtree(argc, argv, combinedopt);
10051 #ifndef MINIMALISTIC
10053 error = testunitready(cam_dev, task_attr, retry_count,
10056 case CAM_CMD_INQUIRY:
10057 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10058 task_attr, retry_count, timeout);
10060 case CAM_CMD_IDENTIFY:
10061 error = ataidentify(cam_dev, retry_count, timeout);
10063 case CAM_CMD_STARTSTOP:
10064 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10065 arglist & CAM_ARG_EJECT, task_attr,
10066 retry_count, timeout);
10068 #endif /* MINIMALISTIC */
10069 case CAM_CMD_RESCAN:
10070 error = dorescan_or_reset(argc, argv, 1);
10072 case CAM_CMD_RESET:
10073 error = dorescan_or_reset(argc, argv, 0);
10075 #ifndef MINIMALISTIC
10076 case CAM_CMD_READ_DEFECTS:
10077 error = readdefects(cam_dev, argc, argv, combinedopt,
10078 task_attr, retry_count, timeout);
10080 case CAM_CMD_MODE_PAGE:
10081 modepage(cam_dev, argc, argv, combinedopt,
10082 task_attr, retry_count, timeout);
10084 case CAM_CMD_SCSI_CMD:
10085 error = scsicmd(cam_dev, argc, argv, combinedopt,
10086 task_attr, retry_count, timeout);
10088 case CAM_CMD_MMCSD_CMD:
10089 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10090 retry_count, timeout);
10092 case CAM_CMD_SMP_CMD:
10093 error = smpcmd(cam_dev, argc, argv, combinedopt,
10094 retry_count, timeout);
10096 case CAM_CMD_SMP_RG:
10097 error = smpreportgeneral(cam_dev, argc, argv,
10098 combinedopt, retry_count,
10101 case CAM_CMD_SMP_PC:
10102 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10103 retry_count, timeout);
10105 case CAM_CMD_SMP_PHYLIST:
10106 error = smpphylist(cam_dev, argc, argv, combinedopt,
10107 retry_count, timeout);
10109 case CAM_CMD_SMP_MANINFO:
10110 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10111 retry_count, timeout);
10113 case CAM_CMD_DEBUG:
10114 error = camdebug(argc, argv, combinedopt);
10117 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10120 error = ratecontrol(cam_dev, task_attr, retry_count,
10121 timeout, argc, argv, combinedopt);
10123 case CAM_CMD_FORMAT:
10124 error = scsiformat(cam_dev, argc, argv,
10125 combinedopt, task_attr, retry_count,
10128 case CAM_CMD_REPORTLUNS:
10129 error = scsireportluns(cam_dev, argc, argv,
10130 combinedopt, task_attr,
10131 retry_count, timeout);
10133 case CAM_CMD_READCAP:
10134 error = scsireadcapacity(cam_dev, argc, argv,
10135 combinedopt, task_attr,
10136 retry_count, timeout);
10139 case CAM_CMD_STANDBY:
10140 case CAM_CMD_SLEEP:
10141 error = atapm(cam_dev, argc, argv,
10142 combinedopt, retry_count, timeout);
10146 error = ataaxm(cam_dev, argc, argv,
10147 combinedopt, retry_count, timeout);
10149 case CAM_CMD_SECURITY:
10150 error = atasecurity(cam_dev, retry_count, timeout,
10151 argc, argv, combinedopt);
10153 case CAM_CMD_DOWNLOAD_FW:
10154 error = fwdownload(cam_dev, argc, argv, combinedopt,
10155 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10158 case CAM_CMD_SANITIZE:
10159 error = scsisanitize(cam_dev, argc, argv,
10160 combinedopt, task_attr,
10161 retry_count, timeout);
10163 case CAM_CMD_PERSIST:
10164 error = scsipersist(cam_dev, argc, argv, combinedopt,
10165 task_attr, retry_count, timeout,
10166 arglist & CAM_ARG_VERBOSE,
10167 arglist & CAM_ARG_ERR_RECOVER);
10169 case CAM_CMD_ATTRIB:
10170 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10171 task_attr, retry_count, timeout,
10172 arglist & CAM_ARG_VERBOSE,
10173 arglist & CAM_ARG_ERR_RECOVER);
10175 case CAM_CMD_OPCODES:
10176 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10177 task_attr, retry_count, timeout,
10178 arglist & CAM_ARG_VERBOSE);
10180 case CAM_CMD_REPROBE:
10181 error = scsireprobe(cam_dev);
10184 error = zone(cam_dev, argc, argv, combinedopt,
10185 task_attr, retry_count, timeout,
10186 arglist & CAM_ARG_VERBOSE);
10189 error = epc(cam_dev, argc, argv, combinedopt,
10190 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10192 case CAM_CMD_TIMESTAMP:
10193 error = timestamp(cam_dev, argc, argv, combinedopt,
10194 task_attr, retry_count, timeout,
10195 arglist & CAM_ARG_VERBOSE);
10197 #endif /* MINIMALISTIC */
10198 case CAM_CMD_USAGE:
10207 if (cam_dev != NULL)
10208 cam_close_device(cam_dev);