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"
67 #include "nvmecontrol_ext.h"
71 CAM_CMD_NONE = 0x00000000,
72 CAM_CMD_DEVLIST = 0x00000001,
73 CAM_CMD_TUR = 0x00000002,
74 CAM_CMD_INQUIRY = 0x00000003,
75 CAM_CMD_STARTSTOP = 0x00000004,
76 CAM_CMD_RESCAN = 0x00000005,
77 CAM_CMD_READ_DEFECTS = 0x00000006,
78 CAM_CMD_MODE_PAGE = 0x00000007,
79 CAM_CMD_SCSI_CMD = 0x00000008,
80 CAM_CMD_DEVTREE = 0x00000009,
81 CAM_CMD_USAGE = 0x0000000a,
82 CAM_CMD_DEBUG = 0x0000000b,
83 CAM_CMD_RESET = 0x0000000c,
84 CAM_CMD_FORMAT = 0x0000000d,
85 CAM_CMD_TAG = 0x0000000e,
86 CAM_CMD_RATE = 0x0000000f,
87 CAM_CMD_DETACH = 0x00000010,
88 CAM_CMD_REPORTLUNS = 0x00000011,
89 CAM_CMD_READCAP = 0x00000012,
90 CAM_CMD_IDENTIFY = 0x00000013,
91 CAM_CMD_IDLE = 0x00000014,
92 CAM_CMD_STANDBY = 0x00000015,
93 CAM_CMD_SLEEP = 0x00000016,
94 CAM_CMD_SMP_CMD = 0x00000017,
95 CAM_CMD_SMP_RG = 0x00000018,
96 CAM_CMD_SMP_PC = 0x00000019,
97 CAM_CMD_SMP_PHYLIST = 0x0000001a,
98 CAM_CMD_SMP_MANINFO = 0x0000001b,
99 CAM_CMD_DOWNLOAD_FW = 0x0000001c,
100 CAM_CMD_SECURITY = 0x0000001d,
101 CAM_CMD_HPA = 0x0000001e,
102 CAM_CMD_SANITIZE = 0x0000001f,
103 CAM_CMD_PERSIST = 0x00000020,
104 CAM_CMD_APM = 0x00000021,
105 CAM_CMD_AAM = 0x00000022,
106 CAM_CMD_ATTRIB = 0x00000023,
107 CAM_CMD_OPCODES = 0x00000024,
108 CAM_CMD_REPROBE = 0x00000025,
109 CAM_CMD_ZONE = 0x00000026,
110 CAM_CMD_EPC = 0x00000027,
111 CAM_CMD_TIMESTAMP = 0x00000028,
112 CAM_CMD_MMCSD_CMD = 0x00000029,
113 CAM_CMD_POWER_MODE = 0x0000002a,
117 CAM_ARG_NONE = 0x00000000,
118 CAM_ARG_VERBOSE = 0x00000001,
119 CAM_ARG_DEVICE = 0x00000002,
120 CAM_ARG_BUS = 0x00000004,
121 CAM_ARG_TARGET = 0x00000008,
122 CAM_ARG_LUN = 0x00000010,
123 CAM_ARG_EJECT = 0x00000020,
124 CAM_ARG_UNIT = 0x00000040,
125 CAM_ARG_FORMAT_BLOCK = 0x00000080,
126 CAM_ARG_FORMAT_BFI = 0x00000100,
127 CAM_ARG_FORMAT_PHYS = 0x00000200,
128 CAM_ARG_PLIST = 0x00000400,
129 CAM_ARG_GLIST = 0x00000800,
130 CAM_ARG_GET_SERIAL = 0x00001000,
131 CAM_ARG_GET_STDINQ = 0x00002000,
132 CAM_ARG_GET_XFERRATE = 0x00004000,
133 CAM_ARG_INQ_MASK = 0x00007000,
134 CAM_ARG_TIMEOUT = 0x00020000,
135 CAM_ARG_CMD_IN = 0x00040000,
136 CAM_ARG_CMD_OUT = 0x00080000,
137 CAM_ARG_ERR_RECOVER = 0x00200000,
138 CAM_ARG_RETRIES = 0x00400000,
139 CAM_ARG_START_UNIT = 0x00800000,
140 CAM_ARG_DEBUG_INFO = 0x01000000,
141 CAM_ARG_DEBUG_TRACE = 0x02000000,
142 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
143 CAM_ARG_DEBUG_CDB = 0x08000000,
144 CAM_ARG_DEBUG_XPT = 0x10000000,
145 CAM_ARG_DEBUG_PERIPH = 0x20000000,
146 CAM_ARG_DEBUG_PROBE = 0x40000000,
149 struct camcontrol_opts {
157 struct ata_res_pass16 {
158 u_int16_t reserved[5];
161 u_int8_t sector_count_exp;
162 u_int8_t sector_count;
163 u_int8_t lba_low_exp;
165 u_int8_t lba_mid_exp;
167 u_int8_t lba_high_exp;
173 struct ata_set_max_pwd
176 u_int8_t password[32];
177 u_int16_t reserved2[239];
180 static struct scsi_nv task_attrs[] = {
181 { "simple", MSG_SIMPLE_Q_TAG },
182 { "head", MSG_HEAD_OF_Q_TAG },
183 { "ordered", MSG_ORDERED_Q_TAG },
184 { "iwr", MSG_IGN_WIDE_RESIDUE },
185 { "aca", MSG_ACA_TASK }
188 static const char scsicmd_opts[] = "a:c:dfi:o:r";
189 static const char readdefect_opts[] = "f:GPqsS:X";
190 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
191 static const char smprg_opts[] = "l";
192 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
193 static const char smpphylist_opts[] = "lq";
197 static struct camcontrol_opts option_table[] = {
199 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
200 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
201 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
202 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
203 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
204 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
205 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
206 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
207 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHlNqs"},
208 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
209 #endif /* MINIMALISTIC */
210 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
211 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
213 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
214 {"mmcsdcmd", CAM_CMD_MMCSD_CMD, CAM_ARG_NONE, "c:a:f:Wb:l:41S:I"},
215 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
216 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
217 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
218 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
219 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
220 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
221 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
222 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
223 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
224 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
225 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
226 #endif /* MINIMALISTIC */
227 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
229 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
230 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
231 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
232 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
233 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
234 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
235 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
236 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
237 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
238 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
239 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
240 {"powermode", CAM_CMD_POWER_MODE, CAM_ARG_NONE, ""},
241 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
242 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
243 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
244 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
245 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
246 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
247 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
248 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
249 {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
250 {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
251 {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
252 #endif /* MINIMALISTIC */
253 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
254 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
255 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
260 struct device_match_result dev_match;
262 struct periph_match_result *periph_matches;
263 struct scsi_vpd_device_id *device_id;
265 STAILQ_ENTRY(cam_devitem) links;
269 STAILQ_HEAD(, cam_devitem) dev_queue;
273 static cam_cmdmask cmdlist;
274 static cam_argmask arglist;
276 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
277 uint32_t *cmdnum, cam_argmask *argnum,
278 const char **subopt);
280 static int getdevlist(struct cam_device *device);
281 #endif /* MINIMALISTIC */
282 static int getdevtree(int argc, char **argv, char *combinedopt);
283 static int print_dev_scsi(struct device_match_result *dev_result, char *tmpstr);
284 static int print_dev_ata(struct device_match_result *dev_result, char *tmpstr);
285 static int print_dev_semb(struct device_match_result *dev_result, char *tmpstr);
286 static int print_dev_mmcsd(struct device_match_result *dev_result,
289 static int print_dev_nvme(struct device_match_result *dev_result, char *tmpstr);
292 static int testunitready(struct cam_device *device, int task_attr,
293 int retry_count, int timeout, int quiet);
294 static int scsistart(struct cam_device *device, int startstop, int loadeject,
295 int task_attr, int retry_count, int timeout);
296 static int scsiinquiry(struct cam_device *device, int task_attr,
297 int retry_count, int timeout);
298 static int scsiserial(struct cam_device *device, int task_attr,
299 int retry_count, int timeout);
300 #endif /* MINIMALISTIC */
301 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
302 lun_id_t *lun, cam_argmask *arglst);
303 static int dorescan_or_reset(int argc, char **argv, int rescan);
304 static int rescan_or_reset_bus(path_id_t bus, int rescan);
305 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
306 lun_id_t lun, int scan);
308 static int readdefects(struct cam_device *device, int argc, char **argv,
309 char *combinedopt, int task_attr, int retry_count,
311 static void modepage(struct cam_device *device, int argc, char **argv,
312 char *combinedopt, int task_attr, int retry_count,
314 static int scsicmd(struct cam_device *device, int argc, char **argv,
315 char *combinedopt, int task_attr, int retry_count,
317 static int smpcmd(struct cam_device *device, int argc, char **argv,
318 char *combinedopt, int retry_count, int timeout);
319 static int mmcsdcmd(struct cam_device *device, int argc, char **argv,
320 char *combinedopt, int retry_count, int timeout);
321 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
322 char *combinedopt, int retry_count, int timeout);
323 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
324 char *combinedopt, int retry_count, int timeout);
325 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
326 char *combinedopt, int retry_count, int timeout);
327 static int getdevid(struct cam_devitem *item);
328 static int buildbusdevlist(struct cam_devlist *devlist);
329 static void freebusdevlist(struct cam_devlist *devlist);
330 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
332 static int smpphylist(struct cam_device *device, int argc, char **argv,
333 char *combinedopt, int retry_count, int timeout);
334 static int tagcontrol(struct cam_device *device, int argc, char **argv,
336 static void cts_print(struct cam_device *device,
337 struct ccb_trans_settings *cts);
338 static void cpi_print(struct ccb_pathinq *cpi);
339 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
340 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
341 static int get_print_cts(struct cam_device *device, int user_settings,
342 int quiet, struct ccb_trans_settings *cts);
343 static int ratecontrol(struct cam_device *device, int task_attr,
344 int retry_count, int timeout, int argc, char **argv,
346 static int scsiformat(struct cam_device *device, int argc, char **argv,
347 char *combinedopt, int task_attr, int retry_count,
349 static int scsisanitize(struct cam_device *device, int argc, char **argv,
350 char *combinedopt, int task_attr, int retry_count,
352 static int scsireportluns(struct cam_device *device, int argc, char **argv,
353 char *combinedopt, int task_attr, int retry_count,
355 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
356 char *combinedopt, int task_attr, int retry_count,
358 static int atapm(struct cam_device *device, int argc, char **argv,
359 char *combinedopt, int retry_count, int timeout);
360 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
361 int argc, char **argv, char *combinedopt);
362 static int atahpa(struct cam_device *device, int retry_count, int timeout,
363 int argc, char **argv, char *combinedopt);
364 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
365 int sa_set, int req_sa, uint8_t *buf,
367 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
369 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
370 char *combinedopt, int task_attr, int retry_count,
371 int timeout, int verbose);
372 static int scsireprobe(struct cam_device *device);
374 #endif /* MINIMALISTIC */
376 #define min(a,b) (((a)<(b))?(a):(b))
379 #define max(a,b) (((a)>(b))?(a):(b))
383 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
384 cam_argmask *argnum, const char **subopt)
386 struct camcontrol_opts *opts;
389 for (opts = table; (opts != NULL) && (opts->optname != NULL);
391 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
392 *cmdnum = opts->cmdnum;
393 *argnum = opts->argnum;
394 *subopt = opts->subopt;
395 if (++num_matches > 1)
396 return (CC_OR_AMBIGUOUS);
401 return (CC_OR_FOUND);
403 return (CC_OR_NOT_FOUND);
408 getdevlist(struct cam_device *device)
414 ccb = cam_getccb(device);
416 ccb->ccb_h.func_code = XPT_GDEVLIST;
417 ccb->ccb_h.flags = CAM_DIR_NONE;
418 ccb->ccb_h.retry_count = 1;
420 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
421 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
422 if (cam_send_ccb(device, ccb) < 0) {
423 perror("error getting device list");
430 switch (ccb->cgdl.status) {
431 case CAM_GDEVLIST_MORE_DEVS:
432 strcpy(status, "MORE");
434 case CAM_GDEVLIST_LAST_DEVICE:
435 strcpy(status, "LAST");
437 case CAM_GDEVLIST_LIST_CHANGED:
438 strcpy(status, "CHANGED");
440 case CAM_GDEVLIST_ERROR:
441 strcpy(status, "ERROR");
446 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
447 ccb->cgdl.periph_name,
448 ccb->cgdl.unit_number,
449 ccb->cgdl.generation,
454 * If the list has changed, we need to start over from the
457 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
465 #endif /* MINIMALISTIC */
468 getdevtree(int argc, char **argv, char *combinedopt)
479 while ((c = getopt(argc, argv, combinedopt)) != -1) {
482 if ((arglist & CAM_ARG_VERBOSE) == 0)
490 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
491 warn("couldn't open %s", XPT_DEVICE);
495 bzero(&ccb, sizeof(union ccb));
497 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
498 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
499 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
501 ccb.ccb_h.func_code = XPT_DEV_MATCH;
502 bufsize = sizeof(struct dev_match_result) * 100;
503 ccb.cdm.match_buf_len = bufsize;
504 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
505 if (ccb.cdm.matches == NULL) {
506 warnx("can't malloc memory for matches");
510 ccb.cdm.num_matches = 0;
513 * We fetch all nodes, since we display most of them in the default
514 * case, and all in the verbose case.
516 ccb.cdm.num_patterns = 0;
517 ccb.cdm.pattern_buf_len = 0;
520 * We do the ioctl multiple times if necessary, in case there are
521 * more than 100 nodes in the EDT.
524 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
525 warn("error sending CAMIOCOMMAND ioctl");
530 if ((ccb.ccb_h.status != CAM_REQ_CMP)
531 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
532 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
533 warnx("got CAM error %#x, CDM error %d\n",
534 ccb.ccb_h.status, ccb.cdm.status);
539 for (i = 0; i < ccb.cdm.num_matches; i++) {
540 switch (ccb.cdm.matches[i].type) {
541 case DEV_MATCH_BUS: {
542 struct bus_match_result *bus_result;
545 * Only print the bus information if the
546 * user turns on the verbose flag.
548 if ((busonly == 0) &&
549 (arglist & CAM_ARG_VERBOSE) == 0)
553 &ccb.cdm.matches[i].result.bus_result;
556 fprintf(stdout, ")\n");
560 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
562 bus_result->dev_name,
563 bus_result->unit_number,
565 (busonly ? "" : ":"));
568 case DEV_MATCH_DEVICE: {
569 struct device_match_result *dev_result;
576 &ccb.cdm.matches[i].result.device_result;
578 if ((dev_result->flags
579 & DEV_RESULT_UNCONFIGURED)
580 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
586 if (dev_result->protocol == PROTO_SCSI) {
587 if (print_dev_scsi(dev_result,
592 } else if (dev_result->protocol == PROTO_ATA ||
593 dev_result->protocol == PROTO_SATAPM) {
594 if (print_dev_ata(dev_result,
599 } else if (dev_result->protocol == PROTO_MMCSD){
600 if (print_dev_mmcsd(dev_result,
605 } else if (dev_result->protocol == PROTO_SEMB) {
606 if (print_dev_semb(dev_result,
612 } else if (dev_result->protocol == PROTO_NVME) {
613 if (print_dev_nvme(dev_result,
620 sprintf(tmpstr, "<>");
623 fprintf(stdout, ")\n");
627 fprintf(stdout, "%-33s at scbus%d "
628 "target %d lun %jx (",
631 dev_result->target_id,
632 (uintmax_t)dev_result->target_lun);
638 case DEV_MATCH_PERIPH: {
639 struct periph_match_result *periph_result;
642 &ccb.cdm.matches[i].result.periph_result;
644 if (busonly || skip_device != 0)
648 fprintf(stdout, ",");
650 fprintf(stdout, "%s%d",
651 periph_result->periph_name,
652 periph_result->unit_number);
658 fprintf(stdout, "unknown match type\n");
663 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
664 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
667 fprintf(stdout, ")\n");
675 print_dev_scsi(struct device_match_result *dev_result, char *tmpstr)
677 char vendor[16], product[48], revision[16];
679 cam_strvis(vendor, dev_result->inq_data.vendor,
680 sizeof(dev_result->inq_data.vendor), sizeof(vendor));
681 cam_strvis(product, dev_result->inq_data.product,
682 sizeof(dev_result->inq_data.product), sizeof(product));
683 cam_strvis(revision, dev_result->inq_data.revision,
684 sizeof(dev_result->inq_data.revision), sizeof(revision));
685 sprintf(tmpstr, "<%s %s %s>", vendor, product, revision);
691 print_dev_ata(struct device_match_result *dev_result, char *tmpstr)
693 char product[48], revision[16];
695 cam_strvis(product, dev_result->ident_data.model,
696 sizeof(dev_result->ident_data.model), sizeof(product));
697 cam_strvis(revision, dev_result->ident_data.revision,
698 sizeof(dev_result->ident_data.revision), sizeof(revision));
699 sprintf(tmpstr, "<%s %s>", product, revision);
705 print_dev_semb(struct device_match_result *dev_result, char *tmpstr)
707 struct sep_identify_data *sid;
708 char vendor[16], product[48], revision[16], fw[5];
710 sid = (struct sep_identify_data *)&dev_result->ident_data;
711 cam_strvis(vendor, sid->vendor_id,
712 sizeof(sid->vendor_id), sizeof(vendor));
713 cam_strvis(product, sid->product_id,
714 sizeof(sid->product_id), sizeof(product));
715 cam_strvis(revision, sid->product_rev,
716 sizeof(sid->product_rev), sizeof(revision));
717 cam_strvis(fw, sid->firmware_rev,
718 sizeof(sid->firmware_rev), sizeof(fw));
719 sprintf(tmpstr, "<%s %s %s %s>", vendor, product, revision, fw);
725 print_dev_mmcsd(struct device_match_result *dev_result, char *tmpstr)
728 struct ccb_dev_advinfo *advi;
729 struct cam_device *dev;
730 struct mmc_params mmc_ident_data;
732 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
733 dev_result->target_lun, O_RDWR, NULL);
735 warnx("%s", cam_errbuf);
739 ccb = cam_getccb(dev);
741 warnx("couldn't allocate CCB");
742 cam_close_device(dev);
747 advi->ccb_h.flags = CAM_DIR_IN;
748 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
749 advi->flags = CDAI_FLAG_NONE;
750 advi->buftype = CDAI_TYPE_MMC_PARAMS;
751 advi->bufsiz = sizeof(struct mmc_params);
752 advi->buf = (uint8_t *)&mmc_ident_data;
754 if (cam_send_ccb(dev, ccb) < 0) {
755 warn("error sending CAMIOCOMMAND ioctl");
757 cam_close_device(dev);
761 if (strlen(mmc_ident_data.model) > 0) {
762 sprintf(tmpstr, "<%s>", mmc_ident_data.model);
764 sprintf(tmpstr, "<%s card>",
765 mmc_ident_data.card_features &
766 CARD_FEATURE_SDIO ? "SDIO" : "unknown");
770 cam_close_device(dev);
776 nvme_get_cdata(struct cam_device *dev, struct nvme_controller_data *cdata)
779 struct ccb_dev_advinfo *advi;
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);
813 print_dev_nvme(struct device_match_result *dev_result, char *tmpstr)
815 struct cam_device *dev;
816 struct nvme_controller_data cdata;
817 char vendor[64], product[64];
819 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
820 dev_result->target_lun, O_RDWR, NULL);
822 warnx("%s", cam_errbuf);
826 if (nvme_get_cdata(dev, &cdata))
829 cam_strvis(vendor, cdata.mn, sizeof(cdata.mn), sizeof(vendor));
830 cam_strvis(product, cdata.fr, sizeof(cdata.fr), sizeof(product));
831 sprintf(tmpstr, "<%s %s>", vendor, product);
833 cam_close_device(dev);
840 testunitready(struct cam_device *device, int task_attr, int retry_count,
841 int timeout, int quiet)
846 ccb = cam_getccb(device);
848 scsi_test_unit_ready(&ccb->csio,
849 /* retries */ retry_count,
851 /* tag_action */ task_attr,
852 /* sense_len */ SSD_FULL_SIZE,
853 /* timeout */ timeout ? timeout : 5000);
855 /* Disable freezing the device queue */
856 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
858 if (arglist & CAM_ARG_ERR_RECOVER)
859 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
861 if (cam_send_ccb(device, ccb) < 0) {
863 perror("error sending test unit ready");
865 if (arglist & CAM_ARG_VERBOSE) {
866 cam_error_print(device, ccb, CAM_ESF_ALL,
867 CAM_EPF_ALL, stderr);
874 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
876 fprintf(stdout, "Unit is ready\n");
879 fprintf(stdout, "Unit is not ready\n");
882 if (arglist & CAM_ARG_VERBOSE) {
883 cam_error_print(device, ccb, CAM_ESF_ALL,
884 CAM_EPF_ALL, stderr);
894 scsistart(struct cam_device *device, int startstop, int loadeject,
895 int task_attr, int retry_count, int timeout)
900 ccb = cam_getccb(device);
903 * If we're stopping, send an ordered tag so the drive in question
904 * will finish any previously queued writes before stopping. If
905 * the device isn't capable of tagged queueing, or if tagged
906 * queueing is turned off, the tag action is a no-op. We override
907 * the default simple tag, although this also has the effect of
908 * overriding the user's wishes if he wanted to specify a simple
912 && (task_attr == MSG_SIMPLE_Q_TAG))
913 task_attr = MSG_ORDERED_Q_TAG;
915 scsi_start_stop(&ccb->csio,
916 /* retries */ retry_count,
918 /* tag_action */ task_attr,
919 /* start/stop */ startstop,
920 /* load_eject */ loadeject,
922 /* sense_len */ SSD_FULL_SIZE,
923 /* timeout */ timeout ? timeout : 120000);
925 /* Disable freezing the device queue */
926 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
928 if (arglist & CAM_ARG_ERR_RECOVER)
929 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
931 if (cam_send_ccb(device, ccb) < 0) {
932 perror("error sending start unit");
934 if (arglist & CAM_ARG_VERBOSE) {
935 cam_error_print(device, ccb, CAM_ESF_ALL,
936 CAM_EPF_ALL, stderr);
943 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
945 fprintf(stdout, "Unit started successfully");
947 fprintf(stdout,", Media loaded\n");
949 fprintf(stdout,"\n");
951 fprintf(stdout, "Unit stopped successfully");
953 fprintf(stdout, ", Media ejected\n");
955 fprintf(stdout, "\n");
961 "Error received from start unit command\n");
964 "Error received from stop unit command\n");
966 if (arglist & CAM_ARG_VERBOSE) {
967 cam_error_print(device, ccb, CAM_ESF_ALL,
968 CAM_EPF_ALL, stderr);
978 scsidoinquiry(struct cam_device *device, int argc, char **argv,
979 char *combinedopt, int task_attr, int retry_count, int timeout)
984 while ((c = getopt(argc, argv, combinedopt)) != -1) {
987 arglist |= CAM_ARG_GET_STDINQ;
990 arglist |= CAM_ARG_GET_XFERRATE;
993 arglist |= CAM_ARG_GET_SERIAL;
1001 * If the user didn't specify any inquiry options, he wants all of
1004 if ((arglist & CAM_ARG_INQ_MASK) == 0)
1005 arglist |= CAM_ARG_INQ_MASK;
1007 if (arglist & CAM_ARG_GET_STDINQ)
1008 error = scsiinquiry(device, task_attr, retry_count, timeout);
1013 if (arglist & CAM_ARG_GET_SERIAL)
1014 scsiserial(device, task_attr, retry_count, timeout);
1016 if (arglist & CAM_ARG_GET_XFERRATE)
1017 error = camxferrate(device);
1023 scsiinquiry(struct cam_device *device, int task_attr, int retry_count,
1027 struct scsi_inquiry_data *inq_buf;
1030 ccb = cam_getccb(device);
1033 warnx("couldn't allocate CCB");
1037 /* cam_getccb cleans up the header, caller has to zero the payload */
1038 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1040 inq_buf = (struct scsi_inquiry_data *)malloc(
1041 sizeof(struct scsi_inquiry_data));
1043 if (inq_buf == NULL) {
1045 warnx("can't malloc memory for inquiry\n");
1048 bzero(inq_buf, sizeof(*inq_buf));
1051 * Note that although the size of the inquiry buffer is the full
1052 * 256 bytes specified in the SCSI spec, we only tell the device
1053 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
1054 * two reasons for this:
1056 * - The SCSI spec says that when a length field is only 1 byte,
1057 * a value of 0 will be interpreted as 256. Therefore
1058 * scsi_inquiry() will convert an inq_len (which is passed in as
1059 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
1060 * to 0. Evidently, very few devices meet the spec in that
1061 * regard. Some devices, like many Seagate disks, take the 0 as
1062 * 0, and don't return any data. One Pioneer DVD-R drive
1063 * returns more data than the command asked for.
1065 * So, since there are numerous devices that just don't work
1066 * right with the full inquiry size, we don't send the full size.
1068 * - The second reason not to use the full inquiry data length is
1069 * that we don't need it here. The only reason we issue a
1070 * standard inquiry is to get the vendor name, device name,
1071 * and revision so scsi_print_inquiry() can print them.
1073 * If, at some point in the future, more inquiry data is needed for
1074 * some reason, this code should use a procedure similar to the
1075 * probe code. i.e., issue a short inquiry, and determine from
1076 * the additional length passed back from the device how much
1077 * inquiry data the device supports. Once the amount the device
1078 * supports is determined, issue an inquiry for that amount and no
1083 scsi_inquiry(&ccb->csio,
1084 /* retries */ retry_count,
1086 /* tag_action */ task_attr,
1087 /* inq_buf */ (u_int8_t *)inq_buf,
1088 /* inq_len */ SHORT_INQUIRY_LENGTH,
1091 /* sense_len */ SSD_FULL_SIZE,
1092 /* timeout */ timeout ? timeout : 5000);
1094 /* Disable freezing the device queue */
1095 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1097 if (arglist & CAM_ARG_ERR_RECOVER)
1098 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1100 if (cam_send_ccb(device, ccb) < 0) {
1101 perror("error sending SCSI inquiry");
1103 if (arglist & CAM_ARG_VERBOSE) {
1104 cam_error_print(device, ccb, CAM_ESF_ALL,
1105 CAM_EPF_ALL, stderr);
1112 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1115 if (arglist & CAM_ARG_VERBOSE) {
1116 cam_error_print(device, ccb, CAM_ESF_ALL,
1117 CAM_EPF_ALL, stderr);
1128 fprintf(stdout, "%s%d: ", device->device_name,
1129 device->dev_unit_num);
1130 scsi_print_inquiry(inq_buf);
1138 scsiserial(struct cam_device *device, int task_attr, int retry_count,
1142 struct scsi_vpd_unit_serial_number *serial_buf;
1143 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
1146 ccb = cam_getccb(device);
1149 warnx("couldn't allocate CCB");
1153 /* cam_getccb cleans up the header, caller has to zero the payload */
1154 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1156 serial_buf = (struct scsi_vpd_unit_serial_number *)
1157 malloc(sizeof(*serial_buf));
1159 if (serial_buf == NULL) {
1161 warnx("can't malloc memory for serial number");
1165 scsi_inquiry(&ccb->csio,
1166 /*retries*/ retry_count,
1168 /* tag_action */ task_attr,
1169 /* inq_buf */ (u_int8_t *)serial_buf,
1170 /* inq_len */ sizeof(*serial_buf),
1172 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
1173 /* sense_len */ SSD_FULL_SIZE,
1174 /* timeout */ timeout ? timeout : 5000);
1176 /* Disable freezing the device queue */
1177 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1179 if (arglist & CAM_ARG_ERR_RECOVER)
1180 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1182 if (cam_send_ccb(device, ccb) < 0) {
1183 warn("error getting serial number");
1185 if (arglist & CAM_ARG_VERBOSE) {
1186 cam_error_print(device, ccb, CAM_ESF_ALL,
1187 CAM_EPF_ALL, stderr);
1195 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1198 if (arglist & CAM_ARG_VERBOSE) {
1199 cam_error_print(device, ccb, CAM_ESF_ALL,
1200 CAM_EPF_ALL, stderr);
1211 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1212 serial_num[serial_buf->length] = '\0';
1214 if ((arglist & CAM_ARG_GET_STDINQ)
1215 || (arglist & CAM_ARG_GET_XFERRATE))
1216 fprintf(stdout, "%s%d: Serial Number ",
1217 device->device_name, device->dev_unit_num);
1219 fprintf(stdout, "%.60s\n", serial_num);
1227 camxferrate(struct cam_device *device)
1229 struct ccb_pathinq cpi;
1231 u_int32_t speed = 0;
1236 if ((retval = get_cpi(device, &cpi)) != 0)
1239 ccb = cam_getccb(device);
1242 warnx("couldn't allocate CCB");
1246 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
1248 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1249 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1251 if (((retval = cam_send_ccb(device, ccb)) < 0)
1252 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1253 const char error_string[] = "error getting transfer settings";
1258 warnx(error_string);
1260 if (arglist & CAM_ARG_VERBOSE)
1261 cam_error_print(device, ccb, CAM_ESF_ALL,
1262 CAM_EPF_ALL, stderr);
1266 goto xferrate_bailout;
1270 speed = cpi.base_transfer_speed;
1272 if (ccb->cts.transport == XPORT_SPI) {
1273 struct ccb_trans_settings_spi *spi =
1274 &ccb->cts.xport_specific.spi;
1276 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1277 freq = scsi_calc_syncsrate(spi->sync_period);
1280 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1281 speed *= (0x01 << spi->bus_width);
1283 } else if (ccb->cts.transport == XPORT_FC) {
1284 struct ccb_trans_settings_fc *fc =
1285 &ccb->cts.xport_specific.fc;
1287 if (fc->valid & CTS_FC_VALID_SPEED)
1288 speed = fc->bitrate;
1289 } else if (ccb->cts.transport == XPORT_SAS) {
1290 struct ccb_trans_settings_sas *sas =
1291 &ccb->cts.xport_specific.sas;
1293 if (sas->valid & CTS_SAS_VALID_SPEED)
1294 speed = sas->bitrate;
1295 } else if (ccb->cts.transport == XPORT_ATA) {
1296 struct ccb_trans_settings_pata *pata =
1297 &ccb->cts.xport_specific.ata;
1299 if (pata->valid & CTS_ATA_VALID_MODE)
1300 speed = ata_mode2speed(pata->mode);
1301 } else if (ccb->cts.transport == XPORT_SATA) {
1302 struct ccb_trans_settings_sata *sata =
1303 &ccb->cts.xport_specific.sata;
1305 if (sata->valid & CTS_SATA_VALID_REVISION)
1306 speed = ata_revision2speed(sata->revision);
1311 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1312 device->device_name, device->dev_unit_num,
1315 fprintf(stdout, "%s%d: %dKB/s transfers",
1316 device->device_name, device->dev_unit_num,
1320 if (ccb->cts.transport == XPORT_SPI) {
1321 struct ccb_trans_settings_spi *spi =
1322 &ccb->cts.xport_specific.spi;
1324 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1325 && (spi->sync_offset != 0))
1326 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1327 freq % 1000, spi->sync_offset);
1329 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1330 && (spi->bus_width > 0)) {
1331 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1332 && (spi->sync_offset != 0)) {
1333 fprintf(stdout, ", ");
1335 fprintf(stdout, " (");
1337 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1338 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1339 && (spi->sync_offset != 0)) {
1340 fprintf(stdout, ")");
1342 } else if (ccb->cts.transport == XPORT_ATA) {
1343 struct ccb_trans_settings_pata *pata =
1344 &ccb->cts.xport_specific.ata;
1347 if (pata->valid & CTS_ATA_VALID_MODE)
1348 printf("%s, ", ata_mode2string(pata->mode));
1349 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1350 printf("ATAPI %dbytes, ", pata->atapi);
1351 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1352 printf("PIO %dbytes", pata->bytecount);
1354 } else if (ccb->cts.transport == XPORT_SATA) {
1355 struct ccb_trans_settings_sata *sata =
1356 &ccb->cts.xport_specific.sata;
1359 if (sata->valid & CTS_SATA_VALID_REVISION)
1360 printf("SATA %d.x, ", sata->revision);
1363 if (sata->valid & CTS_SATA_VALID_MODE)
1364 printf("%s, ", ata_mode2string(sata->mode));
1365 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1366 printf("ATAPI %dbytes, ", sata->atapi);
1367 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1368 printf("PIO %dbytes", sata->bytecount);
1372 if (ccb->cts.protocol == PROTO_SCSI) {
1373 struct ccb_trans_settings_scsi *scsi =
1374 &ccb->cts.proto_specific.scsi;
1375 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1376 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1377 fprintf(stdout, ", Command Queueing Enabled");
1382 fprintf(stdout, "\n");
1392 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1394 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1395 ((u_int32_t)parm->lba_size_2 << 16);
1397 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1398 ((u_int64_t)parm->lba_size48_2 << 16) |
1399 ((u_int64_t)parm->lba_size48_3 << 32) |
1400 ((u_int64_t)parm->lba_size48_4 << 48);
1404 "Support Enabled Value\n");
1407 printf("Host Protected Area (HPA) ");
1408 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1409 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1410 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1413 printf("HPA - Security ");
1414 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1424 atasata(struct ata_params *parm)
1428 if (parm->satacapabilities != 0xffff &&
1429 parm->satacapabilities != 0x0000)
1436 atacapprint(struct ata_params *parm)
1438 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1439 ((u_int32_t)parm->lba_size_2 << 16);
1441 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1442 ((u_int64_t)parm->lba_size48_2 << 16) |
1443 ((u_int64_t)parm->lba_size48_3 << 32) |
1444 ((u_int64_t)parm->lba_size48_4 << 48);
1447 printf("protocol ");
1448 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1449 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1450 if (parm->satacapabilities & ATA_SATA_GEN3)
1451 printf(" SATA 3.x\n");
1452 else if (parm->satacapabilities & ATA_SATA_GEN2)
1453 printf(" SATA 2.x\n");
1454 else if (parm->satacapabilities & ATA_SATA_GEN1)
1455 printf(" SATA 1.x\n");
1461 printf("device model %.40s\n", parm->model);
1462 printf("firmware revision %.8s\n", parm->revision);
1463 printf("serial number %.20s\n", parm->serial);
1464 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1465 printf("WWN %04x%04x%04x%04x\n",
1466 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1468 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1469 printf("media serial number %.30s\n",
1470 parm->media_serial);
1473 printf("cylinders %d\n", parm->cylinders);
1474 printf("heads %d\n", parm->heads);
1475 printf("sectors/track %d\n", parm->sectors);
1476 printf("sector size logical %u, physical %lu, offset %lu\n",
1477 ata_logical_sector_size(parm),
1478 (unsigned long)ata_physical_sector_size(parm),
1479 (unsigned long)ata_logical_sector_offset(parm));
1481 if (parm->config == ATA_PROTO_CFA ||
1482 (parm->support.command2 & ATA_SUPPORT_CFA))
1483 printf("CFA supported\n");
1485 printf("LBA%ssupported ",
1486 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1488 printf("%d sectors\n", lbasize);
1492 printf("LBA48%ssupported ",
1493 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1495 printf("%ju sectors\n", (uintmax_t)lbasize48);
1499 printf("PIO supported PIO");
1500 switch (ata_max_pmode(parm)) {
1516 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1517 printf(" w/o IORDY");
1520 printf("DMA%ssupported ",
1521 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1522 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1523 if (parm->mwdmamodes & 0xff) {
1525 if (parm->mwdmamodes & 0x04)
1527 else if (parm->mwdmamodes & 0x02)
1529 else if (parm->mwdmamodes & 0x01)
1533 if ((parm->atavalid & ATA_FLAG_88) &&
1534 (parm->udmamodes & 0xff)) {
1536 if (parm->udmamodes & 0x40)
1538 else if (parm->udmamodes & 0x20)
1540 else if (parm->udmamodes & 0x10)
1542 else if (parm->udmamodes & 0x08)
1544 else if (parm->udmamodes & 0x04)
1546 else if (parm->udmamodes & 0x02)
1548 else if (parm->udmamodes & 0x01)
1555 if (parm->media_rotation_rate == 1) {
1556 printf("media RPM non-rotating\n");
1557 } else if (parm->media_rotation_rate >= 0x0401 &&
1558 parm->media_rotation_rate <= 0xFFFE) {
1559 printf("media RPM %d\n",
1560 parm->media_rotation_rate);
1563 printf("Zoned-Device Commands ");
1564 switch (parm->support3 & ATA_SUPPORT_ZONE_MASK) {
1565 case ATA_SUPPORT_ZONE_DEV_MANAGED:
1566 printf("device managed\n");
1568 case ATA_SUPPORT_ZONE_HOST_AWARE:
1569 printf("host aware\n");
1576 "Support Enabled Value Vendor\n");
1577 printf("read ahead %s %s\n",
1578 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1579 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1580 printf("write cache %s %s\n",
1581 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1582 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1583 printf("flush cache %s %s\n",
1584 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1585 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1586 printf("overlap %s\n",
1587 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1588 printf("Tagged Command Queuing (TCQ) %s %s",
1589 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1590 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1591 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1592 printf(" %d tags\n",
1593 ATA_QUEUE_LEN(parm->queue) + 1);
1596 printf("Native Command Queuing (NCQ) ");
1597 if (parm->satacapabilities != 0xffff &&
1598 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1599 printf("yes %d tags\n",
1600 ATA_QUEUE_LEN(parm->queue) + 1);
1604 printf("NCQ Queue Management %s\n", atasata(parm) &&
1605 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1607 printf("NCQ Streaming %s\n", atasata(parm) &&
1608 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1610 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1611 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1614 printf("SMART %s %s\n",
1615 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1616 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1617 printf("microcode download %s %s\n",
1618 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1619 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1620 printf("security %s %s\n",
1621 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1622 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1623 printf("power management %s %s\n",
1624 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1625 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1626 printf("advanced power management %s %s",
1627 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1628 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1629 if (parm->support.command2 & ATA_SUPPORT_APM) {
1630 printf(" %d/0x%02X\n",
1631 parm->apm_value & 0xff, parm->apm_value & 0xff);
1634 printf("automatic acoustic management %s %s",
1635 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1636 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1637 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1638 printf(" %d/0x%02X %d/0x%02X\n",
1639 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1640 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1641 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1642 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1645 printf("media status notification %s %s\n",
1646 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1647 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1648 printf("power-up in Standby %s %s\n",
1649 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1650 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1651 printf("write-read-verify %s %s",
1652 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1653 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1654 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1655 printf(" %d/0x%x\n",
1656 parm->wrv_mode, parm->wrv_mode);
1659 printf("unload %s %s\n",
1660 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1661 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1662 printf("general purpose logging %s %s\n",
1663 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1664 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1665 printf("free-fall %s %s\n",
1666 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1667 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1668 printf("Data Set Management (DSM/TRIM) ");
1669 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1671 printf("DSM - max 512byte blocks ");
1672 if (parm->max_dsm_blocks == 0x00)
1673 printf("yes not specified\n");
1676 parm->max_dsm_blocks);
1678 printf("DSM - deterministic read ");
1679 if (parm->support3 & ATA_SUPPORT_DRAT) {
1680 if (parm->support3 & ATA_SUPPORT_RZAT)
1681 printf("yes zeroed\n");
1683 printf("yes any value\n");
1693 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1695 struct ata_pass_16 *ata_pass_16;
1696 struct ata_cmd ata_cmd;
1698 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1699 ata_cmd.command = ata_pass_16->command;
1700 ata_cmd.control = ata_pass_16->control;
1701 ata_cmd.features = ata_pass_16->features;
1703 if (arglist & CAM_ARG_VERBOSE) {
1704 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1705 ata_op_string(&ata_cmd),
1706 ccb->csio.ccb_h.timeout);
1709 /* Disable freezing the device queue */
1710 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1712 if (arglist & CAM_ARG_ERR_RECOVER)
1713 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1715 if (cam_send_ccb(device, ccb) < 0) {
1716 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1717 warn("error sending ATA %s via pass_16",
1718 ata_op_string(&ata_cmd));
1721 if (arglist & CAM_ARG_VERBOSE) {
1722 cam_error_print(device, ccb, CAM_ESF_ALL,
1723 CAM_EPF_ALL, stderr);
1729 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1730 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1731 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1732 warnx("ATA %s via pass_16 failed",
1733 ata_op_string(&ata_cmd));
1735 if (arglist & CAM_ARG_VERBOSE) {
1736 cam_error_print(device, ccb, CAM_ESF_ALL,
1737 CAM_EPF_ALL, stderr);
1748 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1750 if (arglist & CAM_ARG_VERBOSE) {
1751 warnx("sending ATA %s with timeout of %u msecs",
1752 ata_op_string(&(ccb->ataio.cmd)),
1753 ccb->ataio.ccb_h.timeout);
1756 /* Disable freezing the device queue */
1757 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1759 if (arglist & CAM_ARG_ERR_RECOVER)
1760 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1762 if (cam_send_ccb(device, ccb) < 0) {
1763 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1764 warn("error sending ATA %s",
1765 ata_op_string(&(ccb->ataio.cmd)));
1768 if (arglist & CAM_ARG_VERBOSE) {
1769 cam_error_print(device, ccb, CAM_ESF_ALL,
1770 CAM_EPF_ALL, stderr);
1776 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1777 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1778 warnx("ATA %s failed: %d",
1779 ata_op_string(&(ccb->ataio.cmd)), quiet);
1782 if (arglist & CAM_ARG_VERBOSE) {
1783 cam_error_print(device, ccb, CAM_ESF_ALL,
1784 CAM_EPF_ALL, stderr);
1794 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1795 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1796 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1797 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1798 u_int16_t dxfer_len, int timeout, int quiet)
1800 if (data_ptr != NULL) {
1801 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1802 AP_FLAG_TLEN_SECT_CNT;
1803 if (flags & CAM_DIR_OUT)
1804 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1806 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1808 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1811 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1813 scsi_ata_pass_16(&ccb->csio,
1827 /*sense_len*/SSD_FULL_SIZE,
1830 return scsi_cam_pass_16_send(device, ccb, quiet);
1834 ata_try_pass_16(struct cam_device *device)
1836 struct ccb_pathinq cpi;
1838 if (get_cpi(device, &cpi) != 0) {
1839 warnx("couldn't get CPI");
1843 if (cpi.protocol == PROTO_SCSI) {
1844 /* possibly compatible with pass_16 */
1848 /* likely not compatible with pass_16 */
1853 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1854 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1855 u_int8_t command, u_int8_t features, u_int32_t lba,
1856 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1857 int timeout, int quiet)
1861 switch (ata_try_pass_16(device)) {
1865 /* Try using SCSI Passthrough */
1866 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1867 0, tag_action, command, features, lba,
1868 sector_count, data_ptr, dxfer_len,
1872 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1873 cam_fill_ataio(&ccb->ataio,
1882 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1883 return ata_cam_send(device, ccb, quiet);
1887 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1888 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1889 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1890 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1891 u_int16_t dxfer_len, int timeout, int force48bit)
1895 retval = ata_try_pass_16(device);
1902 /* Try using SCSI Passthrough */
1903 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1904 ata_flags, tag_action, command, features,
1905 lba, sector_count, data_ptr, dxfer_len,
1908 if (ata_flags & AP_FLAG_CHK_COND) {
1909 /* Decode ata_res from sense data */
1910 struct ata_res_pass16 *res_pass16;
1911 struct ata_res *res;
1915 /* sense_data is 4 byte aligned */
1916 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1917 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1918 ptr[i] = le16toh(ptr[i]);
1920 /* sense_data is 4 byte aligned */
1921 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1922 &ccb->csio.sense_data;
1923 res = &ccb->ataio.res;
1924 res->flags = res_pass16->flags;
1925 res->status = res_pass16->status;
1926 res->error = res_pass16->error;
1927 res->lba_low = res_pass16->lba_low;
1928 res->lba_mid = res_pass16->lba_mid;
1929 res->lba_high = res_pass16->lba_high;
1930 res->device = res_pass16->device;
1931 res->lba_low_exp = res_pass16->lba_low_exp;
1932 res->lba_mid_exp = res_pass16->lba_mid_exp;
1933 res->lba_high_exp = res_pass16->lba_high_exp;
1934 res->sector_count = res_pass16->sector_count;
1935 res->sector_count_exp = res_pass16->sector_count_exp;
1941 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1942 cam_fill_ataio(&ccb->ataio,
1951 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1952 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1954 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1956 if (ata_flags & AP_FLAG_CHK_COND)
1957 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1959 return ata_cam_send(device, ccb, 0);
1963 dump_data(uint16_t *ptr, uint32_t len)
1967 for (i = 0; i < len / 2; i++) {
1969 printf(" %3d: ", i);
1970 printf("%04hx ", ptr[i]);
1979 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1980 int is48bit, u_int64_t *hpasize)
1982 struct ata_res *res;
1984 res = &ccb->ataio.res;
1985 if (res->status & ATA_STATUS_ERROR) {
1986 if (arglist & CAM_ARG_VERBOSE) {
1987 cam_error_print(device, ccb, CAM_ESF_ALL,
1988 CAM_EPF_ALL, stderr);
1989 printf("error = 0x%02x, sector_count = 0x%04x, "
1990 "device = 0x%02x, status = 0x%02x\n",
1991 res->error, res->sector_count,
1992 res->device, res->status);
1995 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1996 warnx("Max address has already been set since "
1997 "last power-on or hardware reset");
2003 if (arglist & CAM_ARG_VERBOSE) {
2004 fprintf(stdout, "%s%d: Raw native max data:\n",
2005 device->device_name, device->dev_unit_num);
2006 /* res is 4 byte aligned */
2007 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
2009 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
2010 "status = 0x%02x\n", res->error, res->sector_count,
2011 res->device, res->status);
2014 if (hpasize != NULL) {
2016 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
2017 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
2018 ((res->lba_high << 16) | (res->lba_mid << 8) |
2021 *hpasize = (((res->device & 0x0f) << 24) |
2022 (res->lba_high << 16) | (res->lba_mid << 8) |
2031 ata_read_native_max(struct cam_device *device, int retry_count,
2032 u_int32_t timeout, union ccb *ccb,
2033 struct ata_params *parm, u_int64_t *hpasize)
2039 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
2040 protocol = AP_PROTO_NON_DATA;
2043 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
2044 protocol |= AP_EXTEND;
2046 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
2049 error = ata_do_cmd(device,
2052 /*flags*/CAM_DIR_NONE,
2053 /*protocol*/protocol,
2054 /*ata_flags*/AP_FLAG_CHK_COND,
2055 /*tag_action*/MSG_SIMPLE_Q_TAG,
2062 timeout ? timeout : 5000,
2068 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
2072 atahpa_set_max(struct cam_device *device, int retry_count,
2073 u_int32_t timeout, union ccb *ccb,
2074 int is48bit, u_int64_t maxsize, int persist)
2080 protocol = AP_PROTO_NON_DATA;
2083 cmd = ATA_SET_MAX_ADDRESS48;
2084 protocol |= AP_EXTEND;
2086 cmd = ATA_SET_MAX_ADDRESS;
2089 /* lba's are zero indexed so the max lba is requested max - 1 */
2093 error = ata_do_cmd(device,
2096 /*flags*/CAM_DIR_NONE,
2097 /*protocol*/protocol,
2098 /*ata_flags*/AP_FLAG_CHK_COND,
2099 /*tag_action*/MSG_SIMPLE_Q_TAG,
2101 /*features*/ATA_HPA_FEAT_MAX_ADDR,
2103 /*sector_count*/persist,
2106 timeout ? timeout : 1000,
2112 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2116 atahpa_password(struct cam_device *device, int retry_count,
2117 u_int32_t timeout, union ccb *ccb,
2118 int is48bit, struct ata_set_max_pwd *pwd)
2124 protocol = AP_PROTO_PIO_OUT;
2125 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2127 error = ata_do_cmd(device,
2130 /*flags*/CAM_DIR_OUT,
2131 /*protocol*/protocol,
2132 /*ata_flags*/AP_FLAG_CHK_COND,
2133 /*tag_action*/MSG_SIMPLE_Q_TAG,
2135 /*features*/ATA_HPA_FEAT_SET_PWD,
2138 /*data_ptr*/(u_int8_t*)pwd,
2139 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2140 timeout ? timeout : 1000,
2146 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2150 atahpa_lock(struct cam_device *device, int retry_count,
2151 u_int32_t timeout, union ccb *ccb, int is48bit)
2157 protocol = AP_PROTO_NON_DATA;
2158 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2160 error = ata_do_cmd(device,
2163 /*flags*/CAM_DIR_NONE,
2164 /*protocol*/protocol,
2165 /*ata_flags*/AP_FLAG_CHK_COND,
2166 /*tag_action*/MSG_SIMPLE_Q_TAG,
2168 /*features*/ATA_HPA_FEAT_LOCK,
2173 timeout ? timeout : 1000,
2179 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2183 atahpa_unlock(struct cam_device *device, int retry_count,
2184 u_int32_t timeout, union ccb *ccb,
2185 int is48bit, struct ata_set_max_pwd *pwd)
2191 protocol = AP_PROTO_PIO_OUT;
2192 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2194 error = ata_do_cmd(device,
2197 /*flags*/CAM_DIR_OUT,
2198 /*protocol*/protocol,
2199 /*ata_flags*/AP_FLAG_CHK_COND,
2200 /*tag_action*/MSG_SIMPLE_Q_TAG,
2202 /*features*/ATA_HPA_FEAT_UNLOCK,
2205 /*data_ptr*/(u_int8_t*)pwd,
2206 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2207 timeout ? timeout : 1000,
2213 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2217 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2218 u_int32_t timeout, union ccb *ccb, int is48bit)
2224 protocol = AP_PROTO_NON_DATA;
2225 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2227 error = ata_do_cmd(device,
2230 /*flags*/CAM_DIR_NONE,
2231 /*protocol*/protocol,
2232 /*ata_flags*/AP_FLAG_CHK_COND,
2233 /*tag_action*/MSG_SIMPLE_Q_TAG,
2235 /*features*/ATA_HPA_FEAT_FREEZE,
2240 timeout ? timeout : 1000,
2246 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2251 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2252 union ccb *ccb, struct ata_params** ident_bufp)
2254 struct ata_params *ident_buf;
2255 struct ccb_pathinq cpi;
2256 struct ccb_getdev cgd;
2259 u_int8_t command, retry_command;
2261 if (get_cpi(device, &cpi) != 0) {
2262 warnx("couldn't get CPI");
2266 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2267 if (cpi.protocol == PROTO_ATA) {
2268 if (get_cgd(device, &cgd) != 0) {
2269 warnx("couldn't get CGD");
2273 command = (cgd.protocol == PROTO_ATA) ?
2274 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2277 /* We don't know which for sure so try both */
2278 command = ATA_ATA_IDENTIFY;
2279 retry_command = ATA_ATAPI_IDENTIFY;
2282 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2284 warnx("can't calloc memory for identify\n");
2288 error = ata_do_28bit_cmd(device,
2290 /*retries*/retry_count,
2291 /*flags*/CAM_DIR_IN,
2292 /*protocol*/AP_PROTO_PIO_IN,
2293 /*tag_action*/MSG_SIMPLE_Q_TAG,
2298 /*data_ptr*/(u_int8_t *)ptr,
2299 /*dxfer_len*/sizeof(struct ata_params),
2300 /*timeout*/timeout ? timeout : 30 * 1000,
2304 if (retry_command == 0) {
2308 error = ata_do_28bit_cmd(device,
2310 /*retries*/retry_count,
2311 /*flags*/CAM_DIR_IN,
2312 /*protocol*/AP_PROTO_PIO_IN,
2313 /*tag_action*/MSG_SIMPLE_Q_TAG,
2314 /*command*/retry_command,
2318 /*data_ptr*/(u_int8_t *)ptr,
2319 /*dxfer_len*/sizeof(struct ata_params),
2320 /*timeout*/timeout ? timeout : 30 * 1000,
2329 ident_buf = (struct ata_params *)ptr;
2330 ata_param_fixup(ident_buf);
2333 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2338 if (arglist & CAM_ARG_VERBOSE) {
2339 fprintf(stdout, "%s%d: Raw identify data:\n",
2340 device->device_name, device->dev_unit_num);
2341 dump_data(ptr, sizeof(struct ata_params));
2344 /* check for invalid (all zero) response */
2346 warnx("Invalid identify response detected");
2351 *ident_bufp = ident_buf;
2358 ataidentify(struct cam_device *device, int retry_count, int timeout)
2361 struct ata_params *ident_buf;
2364 if ((ccb = cam_getccb(device)) == NULL) {
2365 warnx("couldn't allocate CCB");
2369 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2374 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2375 if (ata_read_native_max(device, retry_count, timeout, ccb,
2376 ident_buf, &hpasize) != 0) {
2384 printf("%s%d: ", device->device_name, device->dev_unit_num);
2385 ata_print_ident(ident_buf);
2386 camxferrate(device);
2387 atacapprint(ident_buf);
2388 atahpa_print(ident_buf, hpasize, 0);
2398 nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused)
2400 struct nvme_controller_data cdata;
2402 if (nvme_get_cdata(device, &cdata))
2404 nvme_print_controller(&cdata);
2411 identify(struct cam_device *device, int retry_count, int timeout)
2414 struct ccb_pathinq cpi;
2416 if (get_cpi(device, &cpi) != 0) {
2417 warnx("couldn't get CPI");
2421 if (cpi.protocol == PROTO_NVME) {
2422 return (nvmeidentify(device, retry_count, timeout));
2425 return (ataidentify(device, retry_count, timeout));
2427 #endif /* MINIMALISTIC */
2430 #ifndef MINIMALISTIC
2432 ATA_SECURITY_ACTION_PRINT,
2433 ATA_SECURITY_ACTION_FREEZE,
2434 ATA_SECURITY_ACTION_UNLOCK,
2435 ATA_SECURITY_ACTION_DISABLE,
2436 ATA_SECURITY_ACTION_ERASE,
2437 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2438 ATA_SECURITY_ACTION_SET_PASSWORD
2442 atasecurity_print_time(u_int16_t tw)
2446 printf("unspecified");
2448 printf("> 508 min");
2450 printf("%i min", 2 * tw);
2454 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2458 return 2 * 3600 * 1000; /* default: two hours */
2459 else if (timeout > 255)
2460 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2462 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2467 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2471 bzero(&cmd, sizeof(cmd));
2472 cmd.command = command;
2473 printf("Issuing %s", ata_op_string(&cmd));
2476 char pass[sizeof(pwd->password)+1];
2478 /* pwd->password may not be null terminated */
2479 pass[sizeof(pwd->password)] = '\0';
2480 strncpy(pass, pwd->password, sizeof(pwd->password));
2481 printf(" password='%s', user='%s'",
2483 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2486 if (command == ATA_SECURITY_SET_PASSWORD) {
2487 printf(", mode='%s'",
2488 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2489 "maximum" : "high");
2497 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2498 int retry_count, u_int32_t timeout, int quiet)
2502 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2504 return ata_do_28bit_cmd(device,
2507 /*flags*/CAM_DIR_NONE,
2508 /*protocol*/AP_PROTO_NON_DATA,
2509 /*tag_action*/MSG_SIMPLE_Q_TAG,
2510 /*command*/ATA_SECURITY_FREEZE_LOCK,
2521 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2522 int retry_count, u_int32_t timeout,
2523 struct ata_security_password *pwd, int quiet)
2527 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2529 return ata_do_28bit_cmd(device,
2532 /*flags*/CAM_DIR_OUT,
2533 /*protocol*/AP_PROTO_PIO_OUT,
2534 /*tag_action*/MSG_SIMPLE_Q_TAG,
2535 /*command*/ATA_SECURITY_UNLOCK,
2539 /*data_ptr*/(u_int8_t *)pwd,
2540 /*dxfer_len*/sizeof(*pwd),
2546 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2547 int retry_count, u_int32_t timeout,
2548 struct ata_security_password *pwd, int quiet)
2552 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2553 return ata_do_28bit_cmd(device,
2556 /*flags*/CAM_DIR_OUT,
2557 /*protocol*/AP_PROTO_PIO_OUT,
2558 /*tag_action*/MSG_SIMPLE_Q_TAG,
2559 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2563 /*data_ptr*/(u_int8_t *)pwd,
2564 /*dxfer_len*/sizeof(*pwd),
2571 atasecurity_erase_confirm(struct cam_device *device,
2572 struct ata_params* ident_buf)
2575 printf("\nYou are about to ERASE ALL DATA from the following"
2576 " device:\n%s%d,%s%d: ", device->device_name,
2577 device->dev_unit_num, device->given_dev_name,
2578 device->given_unit_number);
2579 ata_print_ident(ident_buf);
2583 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2585 if (fgets(str, sizeof(str), stdin) != NULL) {
2586 if (strncasecmp(str, "yes", 3) == 0) {
2588 } else if (strncasecmp(str, "no", 2) == 0) {
2591 printf("Please answer \"yes\" or "
2602 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2603 int retry_count, u_int32_t timeout,
2604 u_int32_t erase_timeout,
2605 struct ata_security_password *pwd, int quiet)
2610 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2612 error = ata_do_28bit_cmd(device,
2615 /*flags*/CAM_DIR_NONE,
2616 /*protocol*/AP_PROTO_NON_DATA,
2617 /*tag_action*/MSG_SIMPLE_Q_TAG,
2618 /*command*/ATA_SECURITY_ERASE_PREPARE,
2631 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2633 error = ata_do_28bit_cmd(device,
2636 /*flags*/CAM_DIR_OUT,
2637 /*protocol*/AP_PROTO_PIO_OUT,
2638 /*tag_action*/MSG_SIMPLE_Q_TAG,
2639 /*command*/ATA_SECURITY_ERASE_UNIT,
2643 /*data_ptr*/(u_int8_t *)pwd,
2644 /*dxfer_len*/sizeof(*pwd),
2645 /*timeout*/erase_timeout,
2648 if (error == 0 && quiet == 0)
2649 printf("\nErase Complete\n");
2655 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2656 int retry_count, u_int32_t timeout,
2657 struct ata_security_password *pwd, int quiet)
2661 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2663 return ata_do_28bit_cmd(device,
2666 /*flags*/CAM_DIR_OUT,
2667 /*protocol*/AP_PROTO_PIO_OUT,
2668 /*tag_action*/MSG_SIMPLE_Q_TAG,
2669 /*command*/ATA_SECURITY_SET_PASSWORD,
2673 /*data_ptr*/(u_int8_t *)pwd,
2674 /*dxfer_len*/sizeof(*pwd),
2680 atasecurity_print(struct ata_params *parm)
2683 printf("\nSecurity Option Value\n");
2684 if (arglist & CAM_ARG_VERBOSE) {
2685 printf("status %04x\n",
2686 parm->security_status);
2688 printf("supported %s\n",
2689 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2690 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2692 printf("enabled %s\n",
2693 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2694 printf("drive locked %s\n",
2695 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2696 printf("security config frozen %s\n",
2697 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2698 printf("count expired %s\n",
2699 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2700 printf("security level %s\n",
2701 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2702 printf("enhanced erase supported %s\n",
2703 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2704 printf("erase time ");
2705 atasecurity_print_time(parm->erase_time);
2707 printf("enhanced erase time ");
2708 atasecurity_print_time(parm->enhanced_erase_time);
2710 printf("master password rev %04x%s\n",
2711 parm->master_passwd_revision,
2712 parm->master_passwd_revision == 0x0000 ||
2713 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2717 * Validates and copies the password in optarg to the passed buffer.
2718 * If the password in optarg is the same length as the buffer then
2719 * the data will still be copied but no null termination will occur.
2722 ata_getpwd(u_int8_t *passwd, int max, char opt)
2726 len = strlen(optarg);
2728 warnx("-%c password is too long", opt);
2730 } else if (len == 0) {
2731 warnx("-%c password is missing", opt);
2733 } else if (optarg[0] == '-'){
2734 warnx("-%c password starts with '-' (generic arg?)", opt);
2736 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2737 warnx("-%c password conflicts with existing password from -%c",
2742 /* Callers pass in a buffer which does NOT need to be terminated */
2743 strncpy(passwd, optarg, max);
2750 ATA_HPA_ACTION_PRINT,
2751 ATA_HPA_ACTION_SET_MAX,
2752 ATA_HPA_ACTION_SET_PWD,
2753 ATA_HPA_ACTION_LOCK,
2754 ATA_HPA_ACTION_UNLOCK,
2755 ATA_HPA_ACTION_FREEZE_LOCK
2759 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2760 u_int64_t maxsize, int persist)
2762 printf("\nYou are about to configure HPA to limit the user accessible\n"
2763 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2764 persist ? "persistently" : "temporarily",
2765 device->device_name, device->dev_unit_num,
2766 device->given_dev_name, device->given_unit_number);
2767 ata_print_ident(ident_buf);
2771 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2773 if (NULL != fgets(str, sizeof(str), stdin)) {
2774 if (0 == strncasecmp(str, "yes", 3)) {
2776 } else if (0 == strncasecmp(str, "no", 2)) {
2779 printf("Please answer \"yes\" or "
2790 atahpa(struct cam_device *device, int retry_count, int timeout,
2791 int argc, char **argv, char *combinedopt)
2794 struct ata_params *ident_buf;
2795 struct ccb_getdev cgd;
2796 struct ata_set_max_pwd pwd;
2797 int error, confirm, quiet, c, action, actions, persist;
2798 int security, is48bit, pwdsize;
2799 u_int64_t hpasize, maxsize;
2808 memset(&pwd, 0, sizeof(pwd));
2810 /* default action is to print hpa information */
2811 action = ATA_HPA_ACTION_PRINT;
2812 pwdsize = sizeof(pwd.password);
2814 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2817 action = ATA_HPA_ACTION_SET_MAX;
2818 maxsize = strtoumax(optarg, NULL, 0);
2823 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2825 action = ATA_HPA_ACTION_SET_PWD;
2831 action = ATA_HPA_ACTION_LOCK;
2837 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2839 action = ATA_HPA_ACTION_UNLOCK;
2845 action = ATA_HPA_ACTION_FREEZE_LOCK;
2865 warnx("too many hpa actions specified");
2869 if (get_cgd(device, &cgd) != 0) {
2870 warnx("couldn't get CGD");
2874 ccb = cam_getccb(device);
2876 warnx("couldn't allocate CCB");
2880 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2887 printf("%s%d: ", device->device_name, device->dev_unit_num);
2888 ata_print_ident(ident_buf);
2889 camxferrate(device);
2892 if (action == ATA_HPA_ACTION_PRINT) {
2893 error = ata_read_native_max(device, retry_count, timeout, ccb,
2894 ident_buf, &hpasize);
2896 atahpa_print(ident_buf, hpasize, 1);
2903 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2904 warnx("HPA is not supported by this device");
2910 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2911 warnx("HPA Security is not supported by this device");
2917 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2920 * The ATA spec requires:
2921 * 1. Read native max addr is called directly before set max addr
2922 * 2. Read native max addr is NOT called before any other set max call
2925 case ATA_HPA_ACTION_SET_MAX:
2927 atahpa_set_confirm(device, ident_buf, maxsize,
2934 error = ata_read_native_max(device, retry_count, timeout,
2935 ccb, ident_buf, &hpasize);
2937 error = atahpa_set_max(device, retry_count, timeout,
2938 ccb, is48bit, maxsize, persist);
2940 /* redo identify to get new lba values */
2941 error = ata_do_identify(device, retry_count,
2944 atahpa_print(ident_buf, hpasize, 1);
2949 case ATA_HPA_ACTION_SET_PWD:
2950 error = atahpa_password(device, retry_count, timeout,
2951 ccb, is48bit, &pwd);
2953 printf("HPA password has been set\n");
2956 case ATA_HPA_ACTION_LOCK:
2957 error = atahpa_lock(device, retry_count, timeout,
2960 printf("HPA has been locked\n");
2963 case ATA_HPA_ACTION_UNLOCK:
2964 error = atahpa_unlock(device, retry_count, timeout,
2965 ccb, is48bit, &pwd);
2967 printf("HPA has been unlocked\n");
2970 case ATA_HPA_ACTION_FREEZE_LOCK:
2971 error = atahpa_freeze_lock(device, retry_count, timeout,
2974 printf("HPA has been frozen\n");
2978 errx(1, "Option currently not supported");
2988 atasecurity(struct cam_device *device, int retry_count, int timeout,
2989 int argc, char **argv, char *combinedopt)
2992 struct ata_params *ident_buf;
2993 int error, confirm, quiet, c, action, actions, setpwd;
2994 int security_enabled, erase_timeout, pwdsize;
2995 struct ata_security_password pwd;
3003 memset(&pwd, 0, sizeof(pwd));
3005 /* default action is to print security information */
3006 action = ATA_SECURITY_ACTION_PRINT;
3008 /* user is master by default as its safer that way */
3009 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3010 pwdsize = sizeof(pwd.password);
3012 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3015 action = ATA_SECURITY_ACTION_FREEZE;
3020 if (strcasecmp(optarg, "user") == 0) {
3021 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
3022 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
3023 } else if (strcasecmp(optarg, "master") == 0) {
3024 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3025 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
3027 warnx("-U argument '%s' is invalid (must be "
3028 "'user' or 'master')", optarg);
3034 if (strcasecmp(optarg, "high") == 0) {
3035 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3036 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3037 } else if (strcasecmp(optarg, "maximum") == 0) {
3038 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3039 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3041 warnx("-l argument '%s' is unknown (must be "
3042 "'high' or 'maximum')", optarg);
3048 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3050 action = ATA_SECURITY_ACTION_UNLOCK;
3055 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3057 action = ATA_SECURITY_ACTION_DISABLE;
3062 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3064 action = ATA_SECURITY_ACTION_ERASE;
3069 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3071 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3072 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3077 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3080 if (action == ATA_SECURITY_ACTION_PRINT)
3081 action = ATA_SECURITY_ACTION_SET_PASSWORD;
3083 * Don't increment action as this can be combined
3084 * with other actions.
3097 erase_timeout = atoi(optarg) * 1000;
3103 warnx("too many security actions specified");
3107 if ((ccb = cam_getccb(device)) == NULL) {
3108 warnx("couldn't allocate CCB");
3112 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3119 printf("%s%d: ", device->device_name, device->dev_unit_num);
3120 ata_print_ident(ident_buf);
3121 camxferrate(device);
3124 if (action == ATA_SECURITY_ACTION_PRINT) {
3125 atasecurity_print(ident_buf);
3131 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3132 warnx("Security not supported");
3138 /* default timeout 15 seconds the same as linux hdparm */
3139 timeout = timeout ? timeout : 15 * 1000;
3141 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3143 /* first set the password if requested */
3145 /* confirm we can erase before setting the password if erasing */
3147 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3148 action == ATA_SECURITY_ACTION_ERASE) &&
3149 atasecurity_erase_confirm(device, ident_buf) == 0) {
3155 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3156 pwd.revision = ident_buf->master_passwd_revision;
3157 if (pwd.revision != 0 && pwd.revision != 0xfff &&
3158 --pwd.revision == 0) {
3159 pwd.revision = 0xfffe;
3162 error = atasecurity_set_password(device, ccb, retry_count,
3163 timeout, &pwd, quiet);
3169 security_enabled = 1;
3173 case ATA_SECURITY_ACTION_FREEZE:
3174 error = atasecurity_freeze(device, ccb, retry_count,
3178 case ATA_SECURITY_ACTION_UNLOCK:
3179 if (security_enabled) {
3180 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3181 error = atasecurity_unlock(device, ccb,
3182 retry_count, timeout, &pwd, quiet);
3184 warnx("Can't unlock, drive is not locked");
3188 warnx("Can't unlock, security is disabled");
3193 case ATA_SECURITY_ACTION_DISABLE:
3194 if (security_enabled) {
3195 /* First unlock the drive if its locked */
3196 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3197 error = atasecurity_unlock(device, ccb,
3205 error = atasecurity_disable(device,
3213 warnx("Can't disable security (already disabled)");
3218 case ATA_SECURITY_ACTION_ERASE:
3219 if (security_enabled) {
3220 if (erase_timeout == 0) {
3221 erase_timeout = atasecurity_erase_timeout_msecs(
3222 ident_buf->erase_time);
3225 error = atasecurity_erase(device, ccb, retry_count,
3226 timeout, erase_timeout, &pwd, quiet);
3228 warnx("Can't secure erase (security is disabled)");
3233 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3234 if (security_enabled) {
3235 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3236 if (erase_timeout == 0) {
3238 atasecurity_erase_timeout_msecs(
3239 ident_buf->enhanced_erase_time);
3242 error = atasecurity_erase(device, ccb,
3243 retry_count, timeout,
3244 erase_timeout, &pwd,
3247 warnx("Enhanced erase is not supported");
3251 warnx("Can't secure erase (enhanced), "
3252 "(security is disabled)");
3263 #endif /* MINIMALISTIC */
3266 * Parse out a bus, or a bus, target and lun in the following
3272 * Returns the number of parsed components, or 0.
3275 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3276 cam_argmask *arglst)
3281 while (isspace(*tstr) && (*tstr != '\0'))
3284 tmpstr = (char *)strtok(tstr, ":");
3285 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3286 *bus = strtol(tmpstr, NULL, 0);
3287 *arglst |= CAM_ARG_BUS;
3289 tmpstr = (char *)strtok(NULL, ":");
3290 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3291 *target = strtol(tmpstr, NULL, 0);
3292 *arglst |= CAM_ARG_TARGET;
3294 tmpstr = (char *)strtok(NULL, ":");
3295 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3296 *lun = strtol(tmpstr, NULL, 0);
3297 *arglst |= CAM_ARG_LUN;
3307 dorescan_or_reset(int argc, char **argv, int rescan)
3309 static const char must[] =
3310 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3312 path_id_t bus = CAM_BUS_WILDCARD;
3313 target_id_t target = CAM_TARGET_WILDCARD;
3314 lun_id_t lun = CAM_LUN_WILDCARD;
3318 warnx(must, rescan? "rescan" : "reset");
3322 tstr = argv[optind];
3323 while (isspace(*tstr) && (*tstr != '\0'))
3325 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3326 arglist |= CAM_ARG_BUS;
3327 else if (isdigit(*tstr)) {
3328 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3329 if (rv != 1 && rv != 3) {
3330 warnx(must, rescan? "rescan" : "reset");
3340 * Note that resetting or rescanning a device used to
3341 * require a bus or bus:target:lun. This is because the
3342 * device in question may not exist and you're trying to
3343 * get the controller to rescan to find it. It may also be
3344 * because the device is hung / unresponsive, and opening
3345 * an unresponsive device is not desireable.
3347 * It can be more convenient to reference a device by
3348 * peripheral name and unit number, though, and it is
3349 * possible to get the bus:target:lun for devices that
3350 * currently exist in the EDT. So this can work for
3351 * devices that we want to reset, or devices that exist
3352 * that we want to rescan, but not devices that do not
3355 * So, we are careful here to look up the bus/target/lun
3356 * for the device the user wants to operate on, specified
3357 * by peripheral instance (e.g. da0, pass32) without
3358 * actually opening that device. The process is similar to
3359 * what cam_lookup_pass() does, except that we don't
3360 * actually open the passthrough driver instance in the end.
3363 if (cam_get_device(tstr, name, sizeof(name), &unit) == -1) {
3364 warnx("%s", cam_errbuf);
3369 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3370 warn("Unable to open %s", XPT_DEVICE);
3375 bzero(&ccb, sizeof(ccb));
3378 * The function code isn't strictly necessary for the
3379 * GETPASSTHRU ioctl.
3381 ccb.ccb_h.func_code = XPT_GDEVLIST;
3384 * These two are necessary for the GETPASSTHRU ioctl to
3387 strlcpy(ccb.cgdl.periph_name, name,
3388 sizeof(ccb.cgdl.periph_name));
3389 ccb.cgdl.unit_number = unit;
3392 * Attempt to get the passthrough device. This ioctl will
3393 * fail if the device name is null, if the device doesn't
3394 * exist, or if the passthrough driver isn't in the kernel.
3396 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3397 warn("Unable to find bus:target:lun for device %s%d",
3403 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3404 const struct cam_status_entry *entry;
3406 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3407 warnx("Unable to find bus:target_lun for device %s%d, "
3408 "CAM status: %s (%#x)", name, unit,
3409 entry ? entry->status_text : "Unknown",
3417 * The kernel fills in the bus/target/lun. We don't
3418 * need the passthrough device name and unit number since
3419 * we aren't going to open it.
3421 bus = ccb.ccb_h.path_id;
3422 target = ccb.ccb_h.target_id;
3423 lun = ccb.ccb_h.target_lun;
3425 arglist |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3430 if ((arglist & CAM_ARG_BUS)
3431 && (arglist & CAM_ARG_TARGET)
3432 && (arglist & CAM_ARG_LUN))
3433 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3435 error = rescan_or_reset_bus(bus, rescan);
3443 rescan_or_reset_bus(path_id_t bus, int rescan)
3445 union ccb *ccb = NULL, *matchccb = NULL;
3446 int fd = -1, retval;
3451 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3452 warnx("error opening transport layer device %s", XPT_DEVICE);
3453 warn("%s", XPT_DEVICE);
3457 ccb = malloc(sizeof(*ccb));
3459 warn("failed to allocate CCB");
3463 bzero(ccb, sizeof(*ccb));
3465 if (bus != CAM_BUS_WILDCARD) {
3466 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3467 ccb->ccb_h.path_id = bus;
3468 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3469 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3470 ccb->crcn.flags = CAM_FLAG_NONE;
3472 /* run this at a low priority */
3473 ccb->ccb_h.pinfo.priority = 5;
3475 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3476 warn("CAMIOCOMMAND ioctl failed");
3481 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3482 fprintf(stdout, "%s of bus %d was successful\n",
3483 rescan ? "Re-scan" : "Reset", bus);
3485 fprintf(stdout, "%s of bus %d returned error %#x\n",
3486 rescan ? "Re-scan" : "Reset", bus,
3487 ccb->ccb_h.status & CAM_STATUS_MASK);
3496 * The right way to handle this is to modify the xpt so that it can
3497 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3498 * that isn't implemented, so instead we enumerate the buses and
3499 * send the rescan or reset to those buses in the case where the
3500 * given bus is -1 (wildcard). We don't send a rescan or reset
3501 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3502 * no-op, sending a rescan to the xpt bus would result in a status of
3505 matchccb = malloc(sizeof(*matchccb));
3506 if (matchccb == NULL) {
3507 warn("failed to allocate CCB");
3511 bzero(matchccb, sizeof(*matchccb));
3512 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3513 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3514 bufsize = sizeof(struct dev_match_result) * 20;
3515 matchccb->cdm.match_buf_len = bufsize;
3516 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3517 if (matchccb->cdm.matches == NULL) {
3518 warnx("can't malloc memory for matches");
3522 matchccb->cdm.num_matches = 0;
3524 matchccb->cdm.num_patterns = 1;
3525 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3527 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3528 matchccb->cdm.pattern_buf_len);
3529 if (matchccb->cdm.patterns == NULL) {
3530 warnx("can't malloc memory for patterns");
3534 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3535 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3540 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3541 warn("CAMIOCOMMAND ioctl failed");
3546 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3547 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3548 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3549 warnx("got CAM error %#x, CDM error %d\n",
3550 matchccb->ccb_h.status, matchccb->cdm.status);
3555 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3556 struct bus_match_result *bus_result;
3558 /* This shouldn't happen. */
3559 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3562 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3565 * We don't want to rescan or reset the xpt bus.
3568 if (bus_result->path_id == CAM_XPT_PATH_ID)
3571 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3573 ccb->ccb_h.path_id = bus_result->path_id;
3574 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3575 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3576 ccb->crcn.flags = CAM_FLAG_NONE;
3578 /* run this at a low priority */
3579 ccb->ccb_h.pinfo.priority = 5;
3581 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3582 warn("CAMIOCOMMAND ioctl failed");
3587 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3588 fprintf(stdout, "%s of bus %d was successful\n",
3589 rescan? "Re-scan" : "Reset",
3590 bus_result->path_id);
3593 * Don't bail out just yet, maybe the other
3594 * rescan or reset commands will complete
3597 fprintf(stderr, "%s of bus %d returned error "
3598 "%#x\n", rescan? "Re-scan" : "Reset",
3599 bus_result->path_id,
3600 ccb->ccb_h.status & CAM_STATUS_MASK);
3604 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3605 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3612 if (matchccb != NULL) {
3613 free(matchccb->cdm.patterns);
3614 free(matchccb->cdm.matches);
3623 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3626 struct cam_device *device;
3631 if (bus == CAM_BUS_WILDCARD) {
3632 warnx("invalid bus number %d", bus);
3636 if (target == CAM_TARGET_WILDCARD) {
3637 warnx("invalid target number %d", target);
3641 if (lun == CAM_LUN_WILDCARD) {
3642 warnx("invalid lun number %jx", (uintmax_t)lun);
3648 bzero(&ccb, sizeof(union ccb));
3651 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3652 warnx("error opening transport layer device %s\n",
3654 warn("%s", XPT_DEVICE);
3658 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3659 if (device == NULL) {
3660 warnx("%s", cam_errbuf);
3665 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3666 ccb.ccb_h.path_id = bus;
3667 ccb.ccb_h.target_id = target;
3668 ccb.ccb_h.target_lun = lun;
3669 ccb.ccb_h.timeout = 5000;
3670 ccb.crcn.flags = CAM_FLAG_NONE;
3672 /* run this at a low priority */
3673 ccb.ccb_h.pinfo.priority = 5;
3676 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3677 warn("CAMIOCOMMAND ioctl failed");
3682 if (cam_send_ccb(device, &ccb) < 0) {
3683 warn("error sending XPT_RESET_DEV CCB");
3684 cam_close_device(device);
3692 cam_close_device(device);
3695 * An error code of CAM_BDR_SENT is normal for a BDR request.
3697 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3699 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3700 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3701 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3704 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3705 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3706 ccb.ccb_h.status & CAM_STATUS_MASK);
3711 #ifndef MINIMALISTIC
3713 static struct scsi_nv defect_list_type_map[] = {
3714 { "block", SRDD10_BLOCK_FORMAT },
3715 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3716 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3717 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3718 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3719 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3723 readdefects(struct cam_device *device, int argc, char **argv,
3724 char *combinedopt, int task_attr, int retry_count, int timeout)
3726 union ccb *ccb = NULL;
3727 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3728 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3729 size_t hdr_size = 0, entry_size = 0;
3732 u_int8_t *defect_list = NULL;
3733 u_int8_t list_format = 0;
3734 int list_type_set = 0;
3735 u_int32_t dlist_length = 0;
3736 u_int32_t returned_length = 0, valid_len = 0;
3737 u_int32_t num_returned = 0, num_valid = 0;
3738 u_int32_t max_possible_size = 0, hdr_max = 0;
3739 u_int32_t starting_offset = 0;
3740 u_int8_t returned_format, returned_type;
3742 int summary = 0, quiet = 0;
3744 int lists_specified = 0;
3745 int get_length = 1, first_pass = 1;
3748 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3752 scsi_nv_status status;
3755 status = scsi_get_nv(defect_list_type_map,
3756 sizeof(defect_list_type_map) /
3757 sizeof(defect_list_type_map[0]), optarg,
3758 &entry_num, SCSI_NV_FLAG_IG_CASE);
3760 if (status == SCSI_NV_FOUND) {
3761 list_format = defect_list_type_map[
3765 warnx("%s: %s %s option %s", __func__,
3766 (status == SCSI_NV_AMBIGUOUS) ?
3767 "ambiguous" : "invalid", "defect list type",
3770 goto defect_bailout;
3775 arglist |= CAM_ARG_GLIST;
3778 arglist |= CAM_ARG_PLIST;
3789 starting_offset = strtoul(optarg, &endptr, 0);
3790 if (*endptr != '\0') {
3792 warnx("invalid starting offset %s", optarg);
3793 goto defect_bailout;
3805 if (list_type_set == 0) {
3807 warnx("no defect list format specified");
3808 goto defect_bailout;
3811 if (arglist & CAM_ARG_PLIST) {
3812 list_format |= SRDD10_PLIST;
3816 if (arglist & CAM_ARG_GLIST) {
3817 list_format |= SRDD10_GLIST;
3822 * This implies a summary, and was the previous behavior.
3824 if (lists_specified == 0)
3827 ccb = cam_getccb(device);
3832 * We start off asking for just the header to determine how much
3833 * defect data is available. Some Hitachi drives return an error
3834 * if you ask for more data than the drive has. Once we know the
3835 * length, we retry the command with the returned length.
3837 if (use_12byte == 0)
3838 dlist_length = sizeof(*hdr10);
3840 dlist_length = sizeof(*hdr12);
3843 if (defect_list != NULL) {
3847 defect_list = malloc(dlist_length);
3848 if (defect_list == NULL) {
3849 warnx("can't malloc memory for defect list");
3851 goto defect_bailout;
3855 bzero(defect_list, dlist_length);
3858 * cam_getccb() zeros the CCB header only. So we need to zero the
3859 * payload portion of the ccb.
3861 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3863 scsi_read_defects(&ccb->csio,
3864 /*retries*/ retry_count,
3866 /*tag_action*/ task_attr,
3867 /*list_format*/ list_format,
3868 /*addr_desc_index*/ starting_offset,
3869 /*data_ptr*/ defect_list,
3870 /*dxfer_len*/ dlist_length,
3871 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3872 /*sense_len*/ SSD_FULL_SIZE,
3873 /*timeout*/ timeout ? timeout : 5000);
3875 /* Disable freezing the device queue */
3876 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3878 if (cam_send_ccb(device, ccb) < 0) {
3879 perror("error reading defect list");
3881 if (arglist & CAM_ARG_VERBOSE) {
3882 cam_error_print(device, ccb, CAM_ESF_ALL,
3883 CAM_EPF_ALL, stderr);
3887 goto defect_bailout;
3890 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3892 if (use_12byte == 0) {
3893 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3894 hdr_size = sizeof(*hdr10);
3895 hdr_max = SRDDH10_MAX_LENGTH;
3897 if (valid_len >= hdr_size) {
3898 returned_length = scsi_2btoul(hdr10->length);
3899 returned_format = hdr10->format;
3901 returned_length = 0;
3902 returned_format = 0;
3905 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3906 hdr_size = sizeof(*hdr12);
3907 hdr_max = SRDDH12_MAX_LENGTH;
3909 if (valid_len >= hdr_size) {
3910 returned_length = scsi_4btoul(hdr12->length);
3911 returned_format = hdr12->format;
3913 returned_length = 0;
3914 returned_format = 0;
3918 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3919 switch (returned_type) {
3920 case SRDD10_BLOCK_FORMAT:
3921 entry_size = sizeof(struct scsi_defect_desc_block);
3923 case SRDD10_LONG_BLOCK_FORMAT:
3924 entry_size = sizeof(struct scsi_defect_desc_long_block);
3926 case SRDD10_EXT_PHYS_FORMAT:
3927 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3928 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3930 case SRDD10_EXT_BFI_FORMAT:
3931 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3932 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3935 warnx("Unknown defect format 0x%x\n", returned_type);
3937 goto defect_bailout;
3941 max_possible_size = (hdr_max / entry_size) * entry_size;
3942 num_returned = returned_length / entry_size;
3943 num_valid = min(returned_length, valid_len - hdr_size);
3944 num_valid /= entry_size;
3946 if (get_length != 0) {
3949 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3950 CAM_SCSI_STATUS_ERROR) {
3951 struct scsi_sense_data *sense;
3952 int error_code, sense_key, asc, ascq;
3954 sense = &ccb->csio.sense_data;
3955 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3956 ccb->csio.sense_resid, &error_code, &sense_key,
3957 &asc, &ascq, /*show_errors*/ 1);
3960 * If the drive is reporting that it just doesn't
3961 * support the defect list format, go ahead and use
3962 * the length it reported. Otherwise, the length
3963 * may not be valid, so use the maximum.
3965 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3966 && (asc == 0x1c) && (ascq == 0x00)
3967 && (returned_length > 0)) {
3968 if ((use_12byte == 0)
3969 && (returned_length >= max_possible_size)) {
3974 dlist_length = returned_length + hdr_size;
3975 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3976 && (asc == 0x1f) && (ascq == 0x00)
3977 && (returned_length > 0)) {
3978 /* Partial defect list transfer */
3980 * Hitachi drives return this error
3981 * along with a partial defect list if they
3982 * have more defects than the 10 byte
3983 * command can support. Retry with the 12
3986 if (use_12byte == 0) {
3991 dlist_length = returned_length + hdr_size;
3992 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
3993 && (asc == 0x24) && (ascq == 0x00)) {
3994 /* Invalid field in CDB */
3996 * SBC-3 says that if the drive has more
3997 * defects than can be reported with the
3998 * 10 byte command, it should return this
3999 * error and no data. Retry with the 12
4002 if (use_12byte == 0) {
4007 dlist_length = returned_length + hdr_size;
4010 * If we got a SCSI error and no valid length,
4011 * just use the 10 byte maximum. The 12
4012 * byte maximum is too large.
4014 if (returned_length == 0)
4015 dlist_length = SRDD10_MAX_LENGTH;
4017 if ((use_12byte == 0)
4018 && (returned_length >=
4019 max_possible_size)) {
4024 dlist_length = returned_length +
4028 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4031 warnx("Error reading defect header");
4032 if (arglist & CAM_ARG_VERBOSE)
4033 cam_error_print(device, ccb, CAM_ESF_ALL,
4034 CAM_EPF_ALL, stderr);
4035 goto defect_bailout;
4037 if ((use_12byte == 0)
4038 && (returned_length >= max_possible_size)) {
4043 dlist_length = returned_length + hdr_size;
4046 fprintf(stdout, "%u", num_returned);
4048 fprintf(stdout, " defect%s",
4049 (num_returned != 1) ? "s" : "");
4051 fprintf(stdout, "\n");
4053 goto defect_bailout;
4057 * We always limit the list length to the 10-byte maximum
4058 * length (0xffff). The reason is that some controllers
4059 * can't handle larger I/Os, and we can transfer the entire
4060 * 10 byte list in one shot. For drives that support the 12
4061 * byte read defects command, we'll step through the list
4062 * by specifying a starting offset. For drives that don't
4063 * support the 12 byte command's starting offset, we'll
4064 * just display the first 64K.
4066 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4072 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4073 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4074 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4075 struct scsi_sense_data *sense;
4076 int error_code, sense_key, asc, ascq;
4078 sense = &ccb->csio.sense_data;
4079 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4080 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4081 &ascq, /*show_errors*/ 1);
4084 * According to the SCSI spec, if the disk doesn't support
4085 * the requested format, it will generally return a sense
4086 * key of RECOVERED ERROR, and an additional sense code
4087 * of "DEFECT LIST NOT FOUND". HGST drives also return
4088 * Primary/Grown defect list not found errors. So just
4089 * check for an ASC of 0x1c.
4091 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4093 const char *format_str;
4095 format_str = scsi_nv_to_str(defect_list_type_map,
4096 sizeof(defect_list_type_map) /
4097 sizeof(defect_list_type_map[0]),
4098 list_format & SRDD10_DLIST_FORMAT_MASK);
4099 warnx("requested defect format %s not available",
4100 format_str ? format_str : "unknown");
4102 format_str = scsi_nv_to_str(defect_list_type_map,
4103 sizeof(defect_list_type_map) /
4104 sizeof(defect_list_type_map[0]), returned_type);
4105 if (format_str != NULL) {
4106 warnx("Device returned %s format",
4110 warnx("Device returned unknown defect"
4111 " data format %#x", returned_type);
4112 goto defect_bailout;
4116 warnx("Error returned from read defect data command");
4117 if (arglist & CAM_ARG_VERBOSE)
4118 cam_error_print(device, ccb, CAM_ESF_ALL,
4119 CAM_EPF_ALL, stderr);
4120 goto defect_bailout;
4122 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4124 warnx("Error returned from read defect data command");
4125 if (arglist & CAM_ARG_VERBOSE)
4126 cam_error_print(device, ccb, CAM_ESF_ALL,
4127 CAM_EPF_ALL, stderr);
4128 goto defect_bailout;
4131 if (first_pass != 0) {
4132 fprintf(stderr, "Got %d defect", num_returned);
4134 if ((lists_specified == 0) || (num_returned == 0)) {
4135 fprintf(stderr, "s.\n");
4136 goto defect_bailout;
4137 } else if (num_returned == 1)
4138 fprintf(stderr, ":\n");
4140 fprintf(stderr, "s:\n");
4146 * XXX KDM I should probably clean up the printout format for the
4149 switch (returned_type) {
4150 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4151 case SRDD10_EXT_PHYS_FORMAT:
4153 struct scsi_defect_desc_phys_sector *dlist;
4155 dlist = (struct scsi_defect_desc_phys_sector *)
4156 (defect_list + hdr_size);
4158 for (i = 0; i < num_valid; i++) {
4161 sector = scsi_4btoul(dlist[i].sector);
4162 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4163 mads = (sector & SDD_EXT_PHYS_MADS) ?
4165 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4167 if (hex_format == 0)
4168 fprintf(stdout, "%d:%d:%d%s",
4169 scsi_3btoul(dlist[i].cylinder),
4171 scsi_4btoul(dlist[i].sector),
4172 mads ? " - " : "\n");
4174 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4175 scsi_3btoul(dlist[i].cylinder),
4177 scsi_4btoul(dlist[i].sector),
4178 mads ? " - " : "\n");
4181 if (num_valid < num_returned) {
4182 starting_offset += num_valid;
4187 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4188 case SRDD10_EXT_BFI_FORMAT:
4190 struct scsi_defect_desc_bytes_from_index *dlist;
4192 dlist = (struct scsi_defect_desc_bytes_from_index *)
4193 (defect_list + hdr_size);
4195 for (i = 0; i < num_valid; i++) {
4198 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4199 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4200 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4201 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4203 if (hex_format == 0)
4204 fprintf(stdout, "%d:%d:%d%s",
4205 scsi_3btoul(dlist[i].cylinder),
4207 scsi_4btoul(dlist[i].bytes_from_index),
4208 mads ? " - " : "\n");
4210 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4211 scsi_3btoul(dlist[i].cylinder),
4213 scsi_4btoul(dlist[i].bytes_from_index),
4214 mads ? " - " : "\n");
4218 if (num_valid < num_returned) {
4219 starting_offset += num_valid;
4224 case SRDDH10_BLOCK_FORMAT:
4226 struct scsi_defect_desc_block *dlist;
4228 dlist = (struct scsi_defect_desc_block *)
4229 (defect_list + hdr_size);
4231 for (i = 0; i < num_valid; i++) {
4232 if (hex_format == 0)
4233 fprintf(stdout, "%u\n",
4234 scsi_4btoul(dlist[i].address));
4236 fprintf(stdout, "0x%x\n",
4237 scsi_4btoul(dlist[i].address));
4240 if (num_valid < num_returned) {
4241 starting_offset += num_valid;
4247 case SRDD10_LONG_BLOCK_FORMAT:
4249 struct scsi_defect_desc_long_block *dlist;
4251 dlist = (struct scsi_defect_desc_long_block *)
4252 (defect_list + hdr_size);
4254 for (i = 0; i < num_valid; i++) {
4255 if (hex_format == 0)
4256 fprintf(stdout, "%ju\n",
4257 (uintmax_t)scsi_8btou64(
4260 fprintf(stdout, "0x%jx\n",
4261 (uintmax_t)scsi_8btou64(
4265 if (num_valid < num_returned) {
4266 starting_offset += num_valid;
4272 fprintf(stderr, "Unknown defect format 0x%x\n",
4279 if (defect_list != NULL)
4287 #endif /* MINIMALISTIC */
4291 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4295 ccb = cam_getccb(device);
4301 #ifndef MINIMALISTIC
4303 mode_sense(struct cam_device *device, int dbd, int pc, int page, int subpage,
4304 int task_attr, int retry_count, int timeout, u_int8_t *data,
4310 ccb = cam_getccb(device);
4313 errx(1, "mode_sense: couldn't allocate CCB");
4315 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4317 scsi_mode_sense_subpage(&ccb->csio,
4318 /* retries */ retry_count,
4320 /* tag_action */ task_attr,
4324 /* subpage */ subpage,
4325 /* param_buf */ data,
4326 /* param_len */ datalen,
4327 /* minimum_cmd_size */ 0,
4328 /* sense_len */ SSD_FULL_SIZE,
4329 /* timeout */ timeout ? timeout : 5000);
4331 if (arglist & CAM_ARG_ERR_RECOVER)
4332 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4334 /* Disable freezing the device queue */
4335 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4337 if (((retval = cam_send_ccb(device, ccb)) < 0)
4338 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4339 if (arglist & CAM_ARG_VERBOSE) {
4340 cam_error_print(device, ccb, CAM_ESF_ALL,
4341 CAM_EPF_ALL, stderr);
4344 cam_close_device(device);
4346 err(1, "error sending mode sense command");
4348 errx(1, "error sending mode sense command");
4355 mode_select(struct cam_device *device, int save_pages, int task_attr,
4356 int retry_count, int timeout, u_int8_t *data, int datalen)
4361 ccb = cam_getccb(device);
4364 errx(1, "mode_select: couldn't allocate CCB");
4366 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4368 scsi_mode_select(&ccb->csio,
4369 /* retries */ retry_count,
4371 /* tag_action */ task_attr,
4372 /* scsi_page_fmt */ 1,
4373 /* save_pages */ save_pages,
4374 /* param_buf */ data,
4375 /* param_len */ datalen,
4376 /* sense_len */ SSD_FULL_SIZE,
4377 /* timeout */ timeout ? timeout : 5000);
4379 if (arglist & CAM_ARG_ERR_RECOVER)
4380 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4382 /* Disable freezing the device queue */
4383 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4385 if (((retval = cam_send_ccb(device, ccb)) < 0)
4386 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4387 if (arglist & CAM_ARG_VERBOSE) {
4388 cam_error_print(device, ccb, CAM_ESF_ALL,
4389 CAM_EPF_ALL, stderr);
4392 cam_close_device(device);
4395 err(1, "error sending mode select command");
4397 errx(1, "error sending mode select command");
4405 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4406 int task_attr, int retry_count, int timeout)
4409 int c, page = -1, subpage = -1, pc = 0;
4410 int binary = 0, dbd = 0, edit = 0, list = 0;
4412 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4427 str_subpage = optarg;
4428 strsep(&str_subpage, ",");
4429 page = strtol(optarg, NULL, 0);
4431 subpage = strtol(str_subpage, NULL, 0);
4435 errx(1, "invalid mode page %d", page);
4437 errx(1, "invalid mode subpage %d", subpage);
4440 pc = strtol(optarg, NULL, 0);
4441 if ((pc < 0) || (pc > 3))
4442 errx(1, "invalid page control field %d", pc);
4449 if (page == -1 && list == 0)
4450 errx(1, "you must specify a mode page!");
4453 mode_list(device, dbd, pc, list > 1, task_attr, retry_count,
4456 mode_edit(device, dbd, pc, page, subpage, edit, binary,
4457 task_attr, retry_count, timeout);
4462 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4463 int task_attr, int retry_count, int timeout)
4466 u_int32_t flags = CAM_DIR_NONE;
4467 u_int8_t *data_ptr = NULL;
4469 u_int8_t atacmd[12];
4470 struct get_hook hook;
4471 int c, data_bytes = 0, valid_bytes;
4477 char *datastr = NULL, *tstr, *resstr = NULL;
4479 int fd_data = 0, fd_res = 0;
4482 ccb = cam_getccb(device);
4485 warnx("scsicmd: error allocating ccb");
4489 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4491 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4495 while (isspace(*tstr) && (*tstr != '\0'))
4497 hook.argc = argc - optind;
4498 hook.argv = argv + optind;
4500 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4503 * Increment optind by the number of arguments the
4504 * encoding routine processed. After each call to
4505 * getopt(3), optind points to the argument that
4506 * getopt should process _next_. In this case,
4507 * that means it points to the first command string
4508 * argument, if there is one. Once we increment
4509 * this, it should point to either the next command
4510 * line argument, or it should be past the end of
4517 while (isspace(*tstr) && (*tstr != '\0'))
4519 hook.argc = argc - optind;
4520 hook.argv = argv + optind;
4522 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4525 * Increment optind by the number of arguments the
4526 * encoding routine processed. After each call to
4527 * getopt(3), optind points to the argument that
4528 * getopt should process _next_. In this case,
4529 * that means it points to the first command string
4530 * argument, if there is one. Once we increment
4531 * this, it should point to either the next command
4532 * line argument, or it should be past the end of
4544 if (arglist & CAM_ARG_CMD_OUT) {
4545 warnx("command must either be "
4546 "read or write, not both");
4548 goto scsicmd_bailout;
4550 arglist |= CAM_ARG_CMD_IN;
4552 data_bytes = strtol(optarg, NULL, 0);
4553 if (data_bytes <= 0) {
4554 warnx("invalid number of input bytes %d",
4557 goto scsicmd_bailout;
4559 hook.argc = argc - optind;
4560 hook.argv = argv + optind;
4563 datastr = cget(&hook, NULL);
4565 * If the user supplied "-" instead of a format, he
4566 * wants the data to be written to stdout.
4568 if ((datastr != NULL)
4569 && (datastr[0] == '-'))
4572 data_ptr = (u_int8_t *)malloc(data_bytes);
4573 if (data_ptr == NULL) {
4574 warnx("can't malloc memory for data_ptr");
4576 goto scsicmd_bailout;
4580 if (arglist & CAM_ARG_CMD_IN) {
4581 warnx("command must either be "
4582 "read or write, not both");
4584 goto scsicmd_bailout;
4586 arglist |= CAM_ARG_CMD_OUT;
4587 flags = CAM_DIR_OUT;
4588 data_bytes = strtol(optarg, NULL, 0);
4589 if (data_bytes <= 0) {
4590 warnx("invalid number of output bytes %d",
4593 goto scsicmd_bailout;
4595 hook.argc = argc - optind;
4596 hook.argv = argv + optind;
4598 datastr = cget(&hook, NULL);
4599 data_ptr = (u_int8_t *)malloc(data_bytes);
4600 if (data_ptr == NULL) {
4601 warnx("can't malloc memory for data_ptr");
4603 goto scsicmd_bailout;
4605 bzero(data_ptr, data_bytes);
4607 * If the user supplied "-" instead of a format, he
4608 * wants the data to be read from stdin.
4610 if ((datastr != NULL)
4611 && (datastr[0] == '-'))
4614 buff_encode_visit(data_ptr, data_bytes, datastr,
4620 hook.argc = argc - optind;
4621 hook.argv = argv + optind;
4623 resstr = cget(&hook, NULL);
4624 if ((resstr != NULL) && (resstr[0] == '-'))
4634 * If fd_data is set, and we're writing to the device, we need to
4635 * read the data the user wants written from stdin.
4637 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4639 int amt_to_read = data_bytes;
4640 u_int8_t *buf_ptr = data_ptr;
4642 for (amt_read = 0; amt_to_read > 0;
4643 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4644 if (amt_read == -1) {
4645 warn("error reading data from stdin");
4647 goto scsicmd_bailout;
4649 amt_to_read -= amt_read;
4650 buf_ptr += amt_read;
4654 if (arglist & CAM_ARG_ERR_RECOVER)
4655 flags |= CAM_PASS_ERR_RECOVER;
4657 /* Disable freezing the device queue */
4658 flags |= CAM_DEV_QFRZDIS;
4662 * This is taken from the SCSI-3 draft spec.
4663 * (T10/1157D revision 0.3)
4664 * The top 3 bits of an opcode are the group code.
4665 * The next 5 bits are the command code.
4666 * Group 0: six byte commands
4667 * Group 1: ten byte commands
4668 * Group 2: ten byte commands
4670 * Group 4: sixteen byte commands
4671 * Group 5: twelve byte commands
4672 * Group 6: vendor specific
4673 * Group 7: vendor specific
4675 switch((cdb[0] >> 5) & 0x7) {
4686 /* computed by buff_encode_visit */
4697 * We should probably use csio_build_visit or something like that
4698 * here, but it's easier to encode arguments as you go. The
4699 * alternative would be skipping the CDB argument and then encoding
4700 * it here, since we've got the data buffer argument by now.
4702 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4704 cam_fill_csio(&ccb->csio,
4705 /*retries*/ retry_count,
4708 /*tag_action*/ task_attr,
4709 /*data_ptr*/ data_ptr,
4710 /*dxfer_len*/ data_bytes,
4711 /*sense_len*/ SSD_FULL_SIZE,
4712 /*cdb_len*/ cdb_len,
4713 /*timeout*/ timeout ? timeout : 5000);
4716 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4718 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4720 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4722 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4724 cam_fill_ataio(&ccb->ataio,
4725 /*retries*/ retry_count,
4729 /*data_ptr*/ data_ptr,
4730 /*dxfer_len*/ data_bytes,
4731 /*timeout*/ timeout ? timeout : 5000);
4734 if (((retval = cam_send_ccb(device, ccb)) < 0)
4735 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4736 const char warnstr[] = "error sending command";
4743 if (arglist & CAM_ARG_VERBOSE) {
4744 cam_error_print(device, ccb, CAM_ESF_ALL,
4745 CAM_EPF_ALL, stderr);
4749 goto scsicmd_bailout;
4752 if (atacmd_len && need_res) {
4754 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4756 fprintf(stdout, "\n");
4759 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4760 ccb->ataio.res.status,
4761 ccb->ataio.res.error,
4762 ccb->ataio.res.lba_low,
4763 ccb->ataio.res.lba_mid,
4764 ccb->ataio.res.lba_high,
4765 ccb->ataio.res.device,
4766 ccb->ataio.res.lba_low_exp,
4767 ccb->ataio.res.lba_mid_exp,
4768 ccb->ataio.res.lba_high_exp,
4769 ccb->ataio.res.sector_count,
4770 ccb->ataio.res.sector_count_exp);
4776 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4778 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4779 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4780 && (arglist & CAM_ARG_CMD_IN)
4781 && (valid_bytes > 0)) {
4783 buff_decode_visit(data_ptr, valid_bytes, datastr,
4785 fprintf(stdout, "\n");
4787 ssize_t amt_written;
4788 int amt_to_write = valid_bytes;
4789 u_int8_t *buf_ptr = data_ptr;
4791 for (amt_written = 0; (amt_to_write > 0) &&
4792 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4793 amt_to_write -= amt_written;
4794 buf_ptr += amt_written;
4796 if (amt_written == -1) {
4797 warn("error writing data to stdout");
4799 goto scsicmd_bailout;
4800 } else if ((amt_written == 0)
4801 && (amt_to_write > 0)) {
4802 warnx("only wrote %u bytes out of %u",
4803 valid_bytes - amt_to_write, valid_bytes);
4810 if ((data_bytes > 0) && (data_ptr != NULL))
4819 camdebug(int argc, char **argv, char *combinedopt)
4822 path_id_t bus = CAM_BUS_WILDCARD;
4823 target_id_t target = CAM_TARGET_WILDCARD;
4824 lun_id_t lun = CAM_LUN_WILDCARD;
4825 char *tstr, *tmpstr = NULL;
4829 bzero(&ccb, sizeof(union ccb));
4831 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4834 arglist |= CAM_ARG_DEBUG_INFO;
4835 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4838 arglist |= CAM_ARG_DEBUG_PERIPH;
4839 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4842 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4843 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4846 arglist |= CAM_ARG_DEBUG_TRACE;
4847 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4850 arglist |= CAM_ARG_DEBUG_XPT;
4851 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4854 arglist |= CAM_ARG_DEBUG_CDB;
4855 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4858 arglist |= CAM_ARG_DEBUG_PROBE;
4859 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4866 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4867 warnx("error opening transport layer device %s", XPT_DEVICE);
4868 warn("%s", XPT_DEVICE);
4875 warnx("you must specify \"off\", \"all\" or a bus,");
4876 warnx("bus:target, or bus:target:lun");
4883 while (isspace(*tstr) && (*tstr != '\0'))
4886 if (strncmp(tstr, "off", 3) == 0) {
4887 ccb.cdbg.flags = CAM_DEBUG_NONE;
4888 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4889 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4890 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4891 } else if (strncmp(tstr, "all", 3) != 0) {
4892 tmpstr = (char *)strtok(tstr, ":");
4893 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4894 bus = strtol(tmpstr, NULL, 0);
4895 arglist |= CAM_ARG_BUS;
4896 tmpstr = (char *)strtok(NULL, ":");
4897 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4898 target = strtol(tmpstr, NULL, 0);
4899 arglist |= CAM_ARG_TARGET;
4900 tmpstr = (char *)strtok(NULL, ":");
4901 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4902 lun = strtol(tmpstr, NULL, 0);
4903 arglist |= CAM_ARG_LUN;
4908 warnx("you must specify \"all\", \"off\", or a bus,");
4909 warnx("bus:target, or bus:target:lun to debug");
4915 ccb.ccb_h.func_code = XPT_DEBUG;
4916 ccb.ccb_h.path_id = bus;
4917 ccb.ccb_h.target_id = target;
4918 ccb.ccb_h.target_lun = lun;
4920 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4921 warn("CAMIOCOMMAND ioctl failed");
4926 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4927 CAM_FUNC_NOTAVAIL) {
4928 warnx("CAM debugging not available");
4929 warnx("you need to put options CAMDEBUG in"
4930 " your kernel config file!");
4932 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4934 warnx("XPT_DEBUG CCB failed with status %#x",
4938 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4940 "Debugging turned off\n");
4943 "Debugging enabled for "
4945 bus, target, (uintmax_t)lun);
4956 tagcontrol(struct cam_device *device, int argc, char **argv,
4966 ccb = cam_getccb(device);
4969 warnx("tagcontrol: error allocating ccb");
4973 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4976 numtags = strtol(optarg, NULL, 0);
4978 warnx("tag count %d is < 0", numtags);
4980 goto tagcontrol_bailout;
4991 cam_path_string(device, pathstr, sizeof(pathstr));
4994 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
4995 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4996 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4997 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4998 ccb->crs.openings = numtags;
5001 if (cam_send_ccb(device, ccb) < 0) {
5002 perror("error sending XPT_REL_SIMQ CCB");
5004 goto tagcontrol_bailout;
5007 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5008 warnx("XPT_REL_SIMQ CCB failed");
5009 cam_error_print(device, ccb, CAM_ESF_ALL,
5010 CAM_EPF_ALL, stderr);
5012 goto tagcontrol_bailout;
5017 fprintf(stdout, "%stagged openings now %d\n",
5018 pathstr, ccb->crs.openings);
5021 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5023 ccb->ccb_h.func_code = XPT_GDEV_STATS;
5025 if (cam_send_ccb(device, ccb) < 0) {
5026 perror("error sending XPT_GDEV_STATS CCB");
5028 goto tagcontrol_bailout;
5031 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5032 warnx("XPT_GDEV_STATS CCB failed");
5033 cam_error_print(device, ccb, CAM_ESF_ALL,
5034 CAM_EPF_ALL, stderr);
5036 goto tagcontrol_bailout;
5039 if (arglist & CAM_ARG_VERBOSE) {
5040 fprintf(stdout, "%s", pathstr);
5041 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5042 fprintf(stdout, "%s", pathstr);
5043 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5044 fprintf(stdout, "%s", pathstr);
5045 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5046 fprintf(stdout, "%s", pathstr);
5047 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5048 fprintf(stdout, "%s", pathstr);
5049 fprintf(stdout, "held %d\n", ccb->cgds.held);
5050 fprintf(stdout, "%s", pathstr);
5051 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5052 fprintf(stdout, "%s", pathstr);
5053 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5056 fprintf(stdout, "%s", pathstr);
5057 fprintf(stdout, "device openings: ");
5059 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5060 ccb->cgds.dev_active);
5070 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5074 cam_path_string(device, pathstr, sizeof(pathstr));
5076 if (cts->transport == XPORT_SPI) {
5077 struct ccb_trans_settings_spi *spi =
5078 &cts->xport_specific.spi;
5080 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5082 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5085 if (spi->sync_offset != 0) {
5088 freq = scsi_calc_syncsrate(spi->sync_period);
5089 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5090 pathstr, freq / 1000, freq % 1000);
5094 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5095 fprintf(stdout, "%soffset: %d\n", pathstr,
5099 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5100 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5101 (0x01 << spi->bus_width) * 8);
5104 if (spi->valid & CTS_SPI_VALID_DISC) {
5105 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5106 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5107 "enabled" : "disabled");
5110 if (cts->transport == XPORT_FC) {
5111 struct ccb_trans_settings_fc *fc =
5112 &cts->xport_specific.fc;
5114 if (fc->valid & CTS_FC_VALID_WWNN)
5115 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5116 (long long) fc->wwnn);
5117 if (fc->valid & CTS_FC_VALID_WWPN)
5118 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5119 (long long) fc->wwpn);
5120 if (fc->valid & CTS_FC_VALID_PORT)
5121 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5122 if (fc->valid & CTS_FC_VALID_SPEED)
5123 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5124 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5126 if (cts->transport == XPORT_SAS) {
5127 struct ccb_trans_settings_sas *sas =
5128 &cts->xport_specific.sas;
5130 if (sas->valid & CTS_SAS_VALID_SPEED)
5131 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5132 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5134 if (cts->transport == XPORT_ATA) {
5135 struct ccb_trans_settings_pata *pata =
5136 &cts->xport_specific.ata;
5138 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5139 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5140 ata_mode2string(pata->mode));
5142 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5143 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5146 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5147 fprintf(stdout, "%sPIO transaction length: %d\n",
5148 pathstr, pata->bytecount);
5151 if (cts->transport == XPORT_SATA) {
5152 struct ccb_trans_settings_sata *sata =
5153 &cts->xport_specific.sata;
5155 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5156 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5159 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5160 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5161 ata_mode2string(sata->mode));
5163 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5164 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5167 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5168 fprintf(stdout, "%sPIO transaction length: %d\n",
5169 pathstr, sata->bytecount);
5171 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5172 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5175 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5176 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5179 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5180 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5184 if (cts->protocol == PROTO_ATA) {
5185 struct ccb_trans_settings_ata *ata=
5186 &cts->proto_specific.ata;
5188 if (ata->valid & CTS_ATA_VALID_TQ) {
5189 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5190 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5191 "enabled" : "disabled");
5194 if (cts->protocol == PROTO_SCSI) {
5195 struct ccb_trans_settings_scsi *scsi=
5196 &cts->proto_specific.scsi;
5198 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5199 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5200 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5201 "enabled" : "disabled");
5205 if (cts->protocol == PROTO_NVME) {
5206 struct ccb_trans_settings_nvme *nvmex =
5207 &cts->xport_specific.nvme;
5209 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5210 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5211 NVME_MAJOR(nvmex->spec),
5212 NVME_MINOR(nvmex->spec));
5214 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5215 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5216 nvmex->lanes, nvmex->max_lanes);
5217 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5218 nvmex->speed, nvmex->max_speed);
5225 * Get a path inquiry CCB for the specified device.
5228 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5233 ccb = cam_getccb(device);
5235 warnx("get_cpi: couldn't allocate CCB");
5238 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5239 ccb->ccb_h.func_code = XPT_PATH_INQ;
5240 if (cam_send_ccb(device, ccb) < 0) {
5241 warn("get_cpi: error sending Path Inquiry CCB");
5242 if (arglist & CAM_ARG_VERBOSE)
5243 cam_error_print(device, ccb, CAM_ESF_ALL,
5244 CAM_EPF_ALL, stderr);
5246 goto get_cpi_bailout;
5248 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5249 if (arglist & CAM_ARG_VERBOSE)
5250 cam_error_print(device, ccb, CAM_ESF_ALL,
5251 CAM_EPF_ALL, stderr);
5253 goto get_cpi_bailout;
5255 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5263 * Get a get device CCB for the specified device.
5266 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5271 ccb = cam_getccb(device);
5273 warnx("get_cgd: couldn't allocate CCB");
5276 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5277 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5278 if (cam_send_ccb(device, ccb) < 0) {
5279 warn("get_cgd: error sending Path Inquiry CCB");
5280 if (arglist & CAM_ARG_VERBOSE)
5281 cam_error_print(device, ccb, CAM_ESF_ALL,
5282 CAM_EPF_ALL, stderr);
5284 goto get_cgd_bailout;
5286 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5287 if (arglist & CAM_ARG_VERBOSE)
5288 cam_error_print(device, ccb, CAM_ESF_ALL,
5289 CAM_EPF_ALL, stderr);
5291 goto get_cgd_bailout;
5293 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5301 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5305 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5306 int timeout, int verbosemode)
5308 union ccb *ccb = NULL;
5309 struct scsi_vpd_supported_page_list sup_pages;
5313 ccb = cam_getccb(dev);
5315 warn("Unable to allocate CCB");
5320 /* cam_getccb cleans up the header, caller has to zero the payload */
5321 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5323 bzero(&sup_pages, sizeof(sup_pages));
5325 scsi_inquiry(&ccb->csio,
5326 /*retries*/ retry_count,
5328 /* tag_action */ MSG_SIMPLE_Q_TAG,
5329 /* inq_buf */ (u_int8_t *)&sup_pages,
5330 /* inq_len */ sizeof(sup_pages),
5332 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5333 /* sense_len */ SSD_FULL_SIZE,
5334 /* timeout */ timeout ? timeout : 5000);
5336 /* Disable freezing the device queue */
5337 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5339 if (retry_count != 0)
5340 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5342 if (cam_send_ccb(dev, ccb) < 0) {
5349 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5350 if (verbosemode != 0)
5351 cam_error_print(dev, ccb, CAM_ESF_ALL,
5352 CAM_EPF_ALL, stderr);
5357 for (i = 0; i < sup_pages.length; i++) {
5358 if (sup_pages.list[i] == page_id) {
5371 * devtype is filled in with the type of device.
5372 * Returns 0 for success, non-zero for failure.
5375 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5376 int verbosemode, camcontrol_devtype *devtype)
5378 struct ccb_getdev cgd;
5381 retval = get_cgd(dev, &cgd);
5385 switch (cgd.protocol) {
5391 *devtype = CC_DT_ATA;
5393 break; /*NOTREACHED*/
5395 *devtype = CC_DT_UNKNOWN;
5397 break; /*NOTREACHED*/
5401 * Check for the ATA Information VPD page (0x89). If this is an
5402 * ATA device behind a SCSI to ATA translation layer, this VPD page
5403 * should be present.
5405 * If that VPD page isn't present, or we get an error back from the
5406 * INQUIRY command, we'll just treat it as a normal SCSI device.
5408 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5409 timeout, verbosemode);
5411 *devtype = CC_DT_ATA_BEHIND_SCSI;
5413 *devtype = CC_DT_SCSI;
5422 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5423 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5424 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5425 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5426 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5427 int is48bit, camcontrol_devtype devtype)
5431 if (devtype == CC_DT_ATA) {
5432 cam_fill_ataio(&ccb->ataio,
5433 /*retries*/ retry_count,
5436 /*tag_action*/ tag_action,
5437 /*data_ptr*/ data_ptr,
5438 /*dxfer_len*/ dxfer_len,
5439 /*timeout*/ timeout);
5440 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5441 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5444 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5447 if (auxiliary != 0) {
5448 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5449 ccb->ataio.aux = auxiliary;
5452 if (ata_flags & AP_FLAG_CHK_COND)
5453 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5455 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5456 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5457 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5458 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5460 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5461 protocol |= AP_EXTEND;
5463 retval = scsi_ata_pass(&ccb->csio,
5464 /*retries*/ retry_count,
5467 /*tag_action*/ tag_action,
5468 /*protocol*/ protocol,
5469 /*ata_flags*/ ata_flags,
5470 /*features*/ features,
5471 /*sector_count*/ sector_count,
5473 /*command*/ command,
5476 /*auxiliary*/ auxiliary,
5478 /*data_ptr*/ data_ptr,
5479 /*dxfer_len*/ dxfer_len,
5480 /*cdb_storage*/ cdb_storage,
5481 /*cdb_storage_len*/ cdb_storage_len,
5482 /*minimum_cmd_size*/ 0,
5483 /*sense_len*/ sense_len,
5484 /*timeout*/ timeout);
5491 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5492 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5496 switch (ccb->ccb_h.func_code) {
5499 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5502 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5503 * or 16 byte, and need to see what
5505 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5506 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5508 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5509 if ((opcode != ATA_PASS_12)
5510 && (opcode != ATA_PASS_16)) {
5512 warnx("%s: unsupported opcode %02x", __func__, opcode);
5516 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5518 /* Note: the _ccb() variant returns 0 for an error */
5525 switch (error_code) {
5526 case SSD_DESC_CURRENT_ERROR:
5527 case SSD_DESC_DEFERRED_ERROR: {
5528 struct scsi_sense_data_desc *sense;
5529 struct scsi_sense_ata_ret_desc *desc;
5532 sense = (struct scsi_sense_data_desc *)
5533 &ccb->csio.sense_data;
5535 desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len -
5536 ccb->csio.sense_resid, SSD_DESC_ATA);
5537 if (desc_ptr == NULL) {
5538 cam_error_print(dev, ccb, CAM_ESF_ALL,
5539 CAM_EPF_ALL, stderr);
5543 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5545 *error = desc->error;
5546 *count = (desc->count_15_8 << 8) |
5548 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5549 ((uint64_t)desc->lba_39_32 << 32) |
5550 ((uint64_t)desc->lba_31_24 << 24) |
5551 (desc->lba_23_16 << 16) |
5552 (desc->lba_15_8 << 8) |
5554 *device = desc->device;
5555 *status = desc->status;
5558 * If the extend bit isn't set, the result is for a
5559 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5560 * command without the extend bit set. This means
5561 * that the device is supposed to return 28-bit
5562 * status. The count field is only 8 bits, and the
5563 * LBA field is only 8 bits.
5565 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5571 case SSD_CURRENT_ERROR:
5572 case SSD_DEFERRED_ERROR: {
5574 struct scsi_sense_data_fixed *sense;
5577 * XXX KDM need to support fixed sense data.
5579 warnx("%s: Fixed sense data not supported yet",
5583 break; /*NOTREACHED*/
5594 struct ata_res *res;
5597 * In this case, we have an ATA command, and we need to
5598 * fill in the requested values from the result register
5601 res = &ccb->ataio.res;
5602 *error = res->error;
5603 *status = res->status;
5604 *device = res->device;
5605 *count = res->sector_count;
5606 *lba = (res->lba_high << 16) |
5607 (res->lba_mid << 8) |
5609 if (res->flags & CAM_ATAIO_48BIT) {
5610 *count |= (res->sector_count_exp << 8);
5611 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5612 ((uint64_t)res->lba_mid_exp << 32) |
5613 ((uint64_t)res->lba_high_exp << 40);
5615 *lba |= (res->device & 0xf) << 24;
5628 cpi_print(struct ccb_pathinq *cpi)
5630 char adapter_str[1024];
5633 snprintf(adapter_str, sizeof(adapter_str),
5634 "%s%d:", cpi->dev_name, cpi->unit_number);
5636 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5639 for (i = 1; i < UINT8_MAX; i = i << 1) {
5642 if ((i & cpi->hba_inquiry) == 0)
5645 fprintf(stdout, "%s supports ", adapter_str);
5649 str = "MDP message";
5652 str = "32 bit wide SCSI";
5655 str = "16 bit wide SCSI";
5658 str = "SDTR message";
5661 str = "linked CDBs";
5664 str = "tag queue messages";
5667 str = "soft reset alternative";
5670 str = "SATA Port Multiplier";
5673 str = "unknown PI bit set";
5676 fprintf(stdout, "%s\n", str);
5679 for (i = 1; i < UINT32_MAX; i = i << 1) {
5682 if ((i & cpi->hba_misc) == 0)
5685 fprintf(stdout, "%s ", adapter_str);
5689 str = "can understand ata_ext requests";
5692 str = "64bit extended LUNs supported";
5695 str = "bus scans from high ID to low ID";
5698 str = "removable devices not included in scan";
5700 case PIM_NOINITIATOR:
5701 str = "initiator role not supported";
5703 case PIM_NOBUSRESET:
5704 str = "user has disabled initial BUS RESET or"
5705 " controller is in target/mixed mode";
5708 str = "do not send 6-byte commands";
5711 str = "scan bus sequentially";
5714 str = "unmapped I/O supported";
5717 str = "does its own scanning";
5720 str = "unknown PIM bit set";
5723 fprintf(stdout, "%s\n", str);
5726 for (i = 1; i < UINT16_MAX; i = i << 1) {
5729 if ((i & cpi->target_sprt) == 0)
5732 fprintf(stdout, "%s supports ", adapter_str);
5735 str = "target mode processor mode";
5738 str = "target mode phase cog. mode";
5740 case PIT_DISCONNECT:
5741 str = "disconnects in target mode";
5744 str = "terminate I/O message in target mode";
5747 str = "group 6 commands in target mode";
5750 str = "group 7 commands in target mode";
5753 str = "unknown PIT bit set";
5757 fprintf(stdout, "%s\n", str);
5759 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5761 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5763 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5765 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5766 adapter_str, cpi->hpath_id);
5767 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5769 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5770 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5771 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5772 adapter_str, cpi->hba_vendor);
5773 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5774 adapter_str, cpi->hba_device);
5775 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5776 adapter_str, cpi->hba_subvendor);
5777 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5778 adapter_str, cpi->hba_subdevice);
5779 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5780 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5781 if (cpi->base_transfer_speed > 1000)
5782 fprintf(stdout, "%d.%03dMB/sec\n",
5783 cpi->base_transfer_speed / 1000,
5784 cpi->base_transfer_speed % 1000);
5786 fprintf(stdout, "%dKB/sec\n",
5787 (cpi->base_transfer_speed % 1000) * 1000);
5788 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5789 adapter_str, cpi->maxio);
5793 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5794 struct ccb_trans_settings *cts)
5800 ccb = cam_getccb(device);
5803 warnx("get_print_cts: error allocating ccb");
5807 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5809 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5811 if (user_settings == 0)
5812 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5814 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5816 if (cam_send_ccb(device, ccb) < 0) {
5817 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5818 if (arglist & CAM_ARG_VERBOSE)
5819 cam_error_print(device, ccb, CAM_ESF_ALL,
5820 CAM_EPF_ALL, stderr);
5822 goto get_print_cts_bailout;
5825 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5826 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5827 if (arglist & CAM_ARG_VERBOSE)
5828 cam_error_print(device, ccb, CAM_ESF_ALL,
5829 CAM_EPF_ALL, stderr);
5831 goto get_print_cts_bailout;
5835 cts_print(device, &ccb->cts);
5838 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5840 get_print_cts_bailout:
5848 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
5849 int timeout, int argc, char **argv, char *combinedopt)
5853 int user_settings = 0;
5855 int disc_enable = -1, tag_enable = -1;
5858 double syncrate = -1;
5861 int change_settings = 0, send_tur = 0;
5862 struct ccb_pathinq cpi;
5864 ccb = cam_getccb(device);
5866 warnx("ratecontrol: error allocating ccb");
5869 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5878 if (strncasecmp(optarg, "enable", 6) == 0)
5880 else if (strncasecmp(optarg, "disable", 7) == 0)
5883 warnx("-D argument \"%s\" is unknown", optarg);
5885 goto ratecontrol_bailout;
5887 change_settings = 1;
5890 mode = ata_string2mode(optarg);
5892 warnx("unknown mode '%s'", optarg);
5894 goto ratecontrol_bailout;
5896 change_settings = 1;
5899 offset = strtol(optarg, NULL, 0);
5901 warnx("offset value %d is < 0", offset);
5903 goto ratecontrol_bailout;
5905 change_settings = 1;
5911 syncrate = atof(optarg);
5913 warnx("sync rate %f is < 0", syncrate);
5915 goto ratecontrol_bailout;
5917 change_settings = 1;
5920 if (strncasecmp(optarg, "enable", 6) == 0)
5922 else if (strncasecmp(optarg, "disable", 7) == 0)
5925 warnx("-T argument \"%s\" is unknown", optarg);
5927 goto ratecontrol_bailout;
5929 change_settings = 1;
5935 bus_width = strtol(optarg, NULL, 0);
5936 if (bus_width < 0) {
5937 warnx("bus width %d is < 0", bus_width);
5939 goto ratecontrol_bailout;
5941 change_settings = 1;
5947 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5949 * Grab path inquiry information, so we can determine whether
5950 * or not the initiator is capable of the things that the user
5953 ccb->ccb_h.func_code = XPT_PATH_INQ;
5954 if (cam_send_ccb(device, ccb) < 0) {
5955 perror("error sending XPT_PATH_INQ CCB");
5956 if (arglist & CAM_ARG_VERBOSE) {
5957 cam_error_print(device, ccb, CAM_ESF_ALL,
5958 CAM_EPF_ALL, stderr);
5961 goto ratecontrol_bailout;
5963 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5964 warnx("XPT_PATH_INQ CCB failed");
5965 if (arglist & CAM_ARG_VERBOSE) {
5966 cam_error_print(device, ccb, CAM_ESF_ALL,
5967 CAM_EPF_ALL, stderr);
5970 goto ratecontrol_bailout;
5972 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5973 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5975 fprintf(stdout, "%s parameters:\n",
5976 user_settings ? "User" : "Current");
5978 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5980 goto ratecontrol_bailout;
5982 if (arglist & CAM_ARG_VERBOSE)
5985 if (change_settings) {
5986 int didsettings = 0;
5987 struct ccb_trans_settings_spi *spi = NULL;
5988 struct ccb_trans_settings_pata *pata = NULL;
5989 struct ccb_trans_settings_sata *sata = NULL;
5990 struct ccb_trans_settings_ata *ata = NULL;
5991 struct ccb_trans_settings_scsi *scsi = NULL;
5993 if (ccb->cts.transport == XPORT_SPI)
5994 spi = &ccb->cts.xport_specific.spi;
5995 if (ccb->cts.transport == XPORT_ATA)
5996 pata = &ccb->cts.xport_specific.ata;
5997 if (ccb->cts.transport == XPORT_SATA)
5998 sata = &ccb->cts.xport_specific.sata;
5999 if (ccb->cts.protocol == PROTO_ATA)
6000 ata = &ccb->cts.proto_specific.ata;
6001 if (ccb->cts.protocol == PROTO_SCSI)
6002 scsi = &ccb->cts.proto_specific.scsi;
6003 ccb->cts.xport_specific.valid = 0;
6004 ccb->cts.proto_specific.valid = 0;
6005 if (spi && disc_enable != -1) {
6006 spi->valid |= CTS_SPI_VALID_DISC;
6007 if (disc_enable == 0)
6008 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6010 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6013 if (tag_enable != -1) {
6014 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6015 warnx("HBA does not support tagged queueing, "
6016 "so you cannot modify tag settings");
6018 goto ratecontrol_bailout;
6021 ata->valid |= CTS_SCSI_VALID_TQ;
6022 if (tag_enable == 0)
6023 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6025 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6028 scsi->valid |= CTS_SCSI_VALID_TQ;
6029 if (tag_enable == 0)
6030 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6032 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6036 if (spi && offset != -1) {
6037 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6038 warnx("HBA is not capable of changing offset");
6040 goto ratecontrol_bailout;
6042 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6043 spi->sync_offset = offset;
6046 if (spi && syncrate != -1) {
6047 int prelim_sync_period;
6049 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6050 warnx("HBA is not capable of changing "
6053 goto ratecontrol_bailout;
6055 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6057 * The sync rate the user gives us is in MHz.
6058 * We need to translate it into KHz for this
6063 * Next, we calculate a "preliminary" sync period
6064 * in tenths of a nanosecond.
6067 prelim_sync_period = 0;
6069 prelim_sync_period = 10000000 / syncrate;
6071 scsi_calc_syncparam(prelim_sync_period);
6074 if (sata && syncrate != -1) {
6075 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6076 warnx("HBA is not capable of changing "
6079 goto ratecontrol_bailout;
6081 if (!user_settings) {
6082 warnx("You can modify only user rate "
6083 "settings for SATA");
6085 goto ratecontrol_bailout;
6087 sata->revision = ata_speed2revision(syncrate * 100);
6088 if (sata->revision < 0) {
6089 warnx("Invalid rate %f", syncrate);
6091 goto ratecontrol_bailout;
6093 sata->valid |= CTS_SATA_VALID_REVISION;
6096 if ((pata || sata) && mode != -1) {
6097 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6098 warnx("HBA is not capable of changing "
6101 goto ratecontrol_bailout;
6103 if (!user_settings) {
6104 warnx("You can modify only user mode "
6105 "settings for ATA/SATA");
6107 goto ratecontrol_bailout;
6111 pata->valid |= CTS_ATA_VALID_MODE;
6114 sata->valid |= CTS_SATA_VALID_MODE;
6119 * The bus_width argument goes like this:
6123 * Therefore, if you shift the number of bits given on the
6124 * command line right by 4, you should get the correct
6127 if (spi && bus_width != -1) {
6129 * We might as well validate things here with a
6130 * decipherable error message, rather than what
6131 * will probably be an indecipherable error message
6132 * by the time it gets back to us.
6134 if ((bus_width == 16)
6135 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6136 warnx("HBA does not support 16 bit bus width");
6138 goto ratecontrol_bailout;
6139 } else if ((bus_width == 32)
6140 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6141 warnx("HBA does not support 32 bit bus width");
6143 goto ratecontrol_bailout;
6144 } else if ((bus_width != 8)
6145 && (bus_width != 16)
6146 && (bus_width != 32)) {
6147 warnx("Invalid bus width %d", bus_width);
6149 goto ratecontrol_bailout;
6151 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6152 spi->bus_width = bus_width >> 4;
6155 if (didsettings == 0) {
6156 goto ratecontrol_bailout;
6158 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6159 if (cam_send_ccb(device, ccb) < 0) {
6160 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
6161 if (arglist & CAM_ARG_VERBOSE) {
6162 cam_error_print(device, ccb, CAM_ESF_ALL,
6163 CAM_EPF_ALL, stderr);
6166 goto ratecontrol_bailout;
6168 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6169 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6170 if (arglist & CAM_ARG_VERBOSE) {
6171 cam_error_print(device, ccb, CAM_ESF_ALL,
6172 CAM_EPF_ALL, stderr);
6175 goto ratecontrol_bailout;
6179 retval = testunitready(device, task_attr, retry_count, timeout,
6180 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6182 * If the TUR didn't succeed, just bail.
6186 fprintf(stderr, "Test Unit Ready failed\n");
6187 goto ratecontrol_bailout;
6190 if ((change_settings || send_tur) && !quiet &&
6191 (ccb->cts.transport == XPORT_ATA ||
6192 ccb->cts.transport == XPORT_SATA || send_tur)) {
6193 fprintf(stdout, "New parameters:\n");
6194 retval = get_print_cts(device, user_settings, 0, NULL);
6197 ratecontrol_bailout:
6203 scsiformat(struct cam_device *device, int argc, char **argv,
6204 char *combinedopt, int task_attr, int retry_count, int timeout)
6208 int ycount = 0, quiet = 0;
6209 int error = 0, retval = 0;
6210 int use_timeout = 10800 * 1000;
6212 struct format_defect_list_header fh;
6213 u_int8_t *data_ptr = NULL;
6214 u_int32_t dxfer_len = 0;
6216 int num_warnings = 0;
6219 ccb = cam_getccb(device);
6222 warnx("scsiformat: error allocating ccb");
6226 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6228 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6249 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6250 "following device:\n");
6252 error = scsidoinquiry(device, argc, argv, combinedopt,
6253 task_attr, retry_count, timeout);
6256 warnx("scsiformat: error sending inquiry");
6257 goto scsiformat_bailout;
6262 if (!get_confirmation()) {
6264 goto scsiformat_bailout;
6269 use_timeout = timeout;
6272 fprintf(stdout, "Current format timeout is %d seconds\n",
6273 use_timeout / 1000);
6277 * If the user hasn't disabled questions and didn't specify a
6278 * timeout on the command line, ask them if they want the current
6282 && (timeout == 0)) {
6284 int new_timeout = 0;
6286 fprintf(stdout, "Enter new timeout in seconds or press\n"
6287 "return to keep the current timeout [%d] ",
6288 use_timeout / 1000);
6290 if (fgets(str, sizeof(str), stdin) != NULL) {
6292 new_timeout = atoi(str);
6295 if (new_timeout != 0) {
6296 use_timeout = new_timeout * 1000;
6297 fprintf(stdout, "Using new timeout value %d\n",
6298 use_timeout / 1000);
6303 * Keep this outside the if block below to silence any unused
6304 * variable warnings.
6306 bzero(&fh, sizeof(fh));
6309 * If we're in immediate mode, we've got to include the format
6312 if (immediate != 0) {
6313 fh.byte2 = FU_DLH_IMMED;
6314 data_ptr = (u_int8_t *)&fh;
6315 dxfer_len = sizeof(fh);
6316 byte2 = FU_FMT_DATA;
6317 } else if (quiet == 0) {
6318 fprintf(stdout, "Formatting...");
6322 scsi_format_unit(&ccb->csio,
6323 /* retries */ retry_count,
6325 /* tag_action */ task_attr,
6328 /* data_ptr */ data_ptr,
6329 /* dxfer_len */ dxfer_len,
6330 /* sense_len */ SSD_FULL_SIZE,
6331 /* timeout */ use_timeout);
6333 /* Disable freezing the device queue */
6334 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6336 if (arglist & CAM_ARG_ERR_RECOVER)
6337 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6339 if (((retval = cam_send_ccb(device, ccb)) < 0)
6340 || ((immediate == 0)
6341 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6342 const char errstr[] = "error sending format command";
6349 if (arglist & CAM_ARG_VERBOSE) {
6350 cam_error_print(device, ccb, CAM_ESF_ALL,
6351 CAM_EPF_ALL, stderr);
6354 goto scsiformat_bailout;
6358 * If we ran in non-immediate mode, we already checked for errors
6359 * above and printed out any necessary information. If we're in
6360 * immediate mode, we need to loop through and get status
6361 * information periodically.
6363 if (immediate == 0) {
6365 fprintf(stdout, "Format Complete\n");
6367 goto scsiformat_bailout;
6374 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6377 * There's really no need to do error recovery or
6378 * retries here, since we're just going to sit in a
6379 * loop and wait for the device to finish formatting.
6381 scsi_test_unit_ready(&ccb->csio,
6384 /* tag_action */ task_attr,
6385 /* sense_len */ SSD_FULL_SIZE,
6386 /* timeout */ 5000);
6388 /* Disable freezing the device queue */
6389 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6391 retval = cam_send_ccb(device, ccb);
6394 * If we get an error from the ioctl, bail out. SCSI
6395 * errors are expected.
6398 warn("error sending CAMIOCOMMAND ioctl");
6399 if (arglist & CAM_ARG_VERBOSE) {
6400 cam_error_print(device, ccb, CAM_ESF_ALL,
6401 CAM_EPF_ALL, stderr);
6404 goto scsiformat_bailout;
6407 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6409 if ((status != CAM_REQ_CMP)
6410 && (status == CAM_SCSI_STATUS_ERROR)
6411 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6412 struct scsi_sense_data *sense;
6413 int error_code, sense_key, asc, ascq;
6415 sense = &ccb->csio.sense_data;
6416 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6417 ccb->csio.sense_resid, &error_code, &sense_key,
6418 &asc, &ascq, /*show_errors*/ 1);
6421 * According to the SCSI-2 and SCSI-3 specs, a
6422 * drive that is in the middle of a format should
6423 * return NOT READY with an ASC of "logical unit
6424 * not ready, format in progress". The sense key
6425 * specific bytes will then be a progress indicator.
6427 if ((sense_key == SSD_KEY_NOT_READY)
6428 && (asc == 0x04) && (ascq == 0x04)) {
6431 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6432 ccb->csio.sense_resid, sks) == 0)
6435 u_int64_t percentage;
6437 val = scsi_2btoul(&sks[1]);
6438 percentage = 10000ull * val;
6441 "\rFormatting: %ju.%02u %% "
6443 (uintmax_t)(percentage /
6445 (unsigned)((percentage /
6449 } else if ((quiet == 0)
6450 && (++num_warnings <= 1)) {
6451 warnx("Unexpected SCSI Sense Key "
6452 "Specific value returned "
6454 scsi_sense_print(device, &ccb->csio,
6456 warnx("Unable to print status "
6457 "information, but format will "
6459 warnx("will exit when format is "
6464 warnx("Unexpected SCSI error during format");
6465 cam_error_print(device, ccb, CAM_ESF_ALL,
6466 CAM_EPF_ALL, stderr);
6468 goto scsiformat_bailout;
6471 } else if (status != CAM_REQ_CMP) {
6472 warnx("Unexpected CAM status %#x", status);
6473 if (arglist & CAM_ARG_VERBOSE)
6474 cam_error_print(device, ccb, CAM_ESF_ALL,
6475 CAM_EPF_ALL, stderr);
6477 goto scsiformat_bailout;
6480 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6483 fprintf(stdout, "\nFormat Complete\n");
6493 scsisanitize(struct cam_device *device, int argc, char **argv,
6494 char *combinedopt, int task_attr, int retry_count, int timeout)
6497 u_int8_t action = 0;
6499 int ycount = 0, quiet = 0;
6500 int error = 0, retval = 0;
6501 int use_timeout = 10800 * 1000;
6507 const char *pattern = NULL;
6508 u_int8_t *data_ptr = NULL;
6509 u_int32_t dxfer_len = 0;
6511 int num_warnings = 0;
6514 ccb = cam_getccb(device);
6517 warnx("scsisanitize: error allocating ccb");
6521 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6523 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6526 if (strcasecmp(optarg, "overwrite") == 0)
6527 action = SSZ_SERVICE_ACTION_OVERWRITE;
6528 else if (strcasecmp(optarg, "block") == 0)
6529 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6530 else if (strcasecmp(optarg, "crypto") == 0)
6531 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6532 else if (strcasecmp(optarg, "exitfailure") == 0)
6533 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6535 warnx("invalid service operation \"%s\"",
6538 goto scsisanitize_bailout;
6542 passes = strtol(optarg, NULL, 0);
6543 if (passes < 1 || passes > 31) {
6544 warnx("invalid passes value %d", passes);
6546 goto scsisanitize_bailout;
6577 warnx("an action is required");
6579 goto scsisanitize_bailout;
6580 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6581 struct scsi_sanitize_parameter_list *pl;
6585 if (pattern == NULL) {
6586 warnx("overwrite action requires -P argument");
6588 goto scsisanitize_bailout;
6590 fd = open(pattern, O_RDONLY);
6592 warn("cannot open pattern file %s", pattern);
6594 goto scsisanitize_bailout;
6596 if (fstat(fd, &sb) < 0) {
6597 warn("cannot stat pattern file %s", pattern);
6599 goto scsisanitize_bailout;
6602 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6603 warnx("pattern file size exceeds maximum value %d",
6604 SSZPL_MAX_PATTERN_LENGTH);
6606 goto scsisanitize_bailout;
6608 dxfer_len = sizeof(*pl) + sz;
6609 data_ptr = calloc(1, dxfer_len);
6610 if (data_ptr == NULL) {
6611 warnx("cannot allocate parameter list buffer");
6613 goto scsisanitize_bailout;
6616 amt = read(fd, data_ptr + sizeof(*pl), sz);
6618 warn("cannot read pattern file");
6620 goto scsisanitize_bailout;
6621 } else if (amt != sz) {
6622 warnx("short pattern file read");
6624 goto scsisanitize_bailout;
6627 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6633 pl->byte1 |= SSZPL_INVERT;
6634 scsi_ulto2b(sz, pl->length);
6640 else if (invert != 0)
6642 else if (pattern != NULL)
6647 warnx("%s argument only valid with overwrite "
6650 goto scsisanitize_bailout;
6655 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6656 "following device:\n");
6658 error = scsidoinquiry(device, argc, argv, combinedopt,
6659 task_attr, retry_count, timeout);
6662 warnx("scsisanitize: error sending inquiry");
6663 goto scsisanitize_bailout;
6668 if (!get_confirmation()) {
6670 goto scsisanitize_bailout;
6675 use_timeout = timeout;
6678 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6679 use_timeout / 1000);
6683 * If the user hasn't disabled questions and didn't specify a
6684 * timeout on the command line, ask them if they want the current
6688 && (timeout == 0)) {
6690 int new_timeout = 0;
6692 fprintf(stdout, "Enter new timeout in seconds or press\n"
6693 "return to keep the current timeout [%d] ",
6694 use_timeout / 1000);
6696 if (fgets(str, sizeof(str), stdin) != NULL) {
6698 new_timeout = atoi(str);
6701 if (new_timeout != 0) {
6702 use_timeout = new_timeout * 1000;
6703 fprintf(stdout, "Using new timeout value %d\n",
6704 use_timeout / 1000);
6710 byte2 |= SSZ_UNRESTRICTED_EXIT;
6714 scsi_sanitize(&ccb->csio,
6715 /* retries */ retry_count,
6717 /* tag_action */ task_attr,
6720 /* data_ptr */ data_ptr,
6721 /* dxfer_len */ dxfer_len,
6722 /* sense_len */ SSD_FULL_SIZE,
6723 /* timeout */ use_timeout);
6725 /* Disable freezing the device queue */
6726 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6728 if (arglist & CAM_ARG_ERR_RECOVER)
6729 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6731 if (cam_send_ccb(device, ccb) < 0) {
6732 warn("error sending sanitize command");
6734 goto scsisanitize_bailout;
6737 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6738 struct scsi_sense_data *sense;
6739 int error_code, sense_key, asc, ascq;
6741 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6742 CAM_SCSI_STATUS_ERROR) {
6743 sense = &ccb->csio.sense_data;
6744 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6745 ccb->csio.sense_resid, &error_code, &sense_key,
6746 &asc, &ascq, /*show_errors*/ 1);
6748 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6749 asc == 0x20 && ascq == 0x00)
6750 warnx("sanitize is not supported by "
6753 warnx("error sanitizing this device");
6755 warnx("error sanitizing this device");
6757 if (arglist & CAM_ARG_VERBOSE) {
6758 cam_error_print(device, ccb, CAM_ESF_ALL,
6759 CAM_EPF_ALL, stderr);
6762 goto scsisanitize_bailout;
6766 * If we ran in non-immediate mode, we already checked for errors
6767 * above and printed out any necessary information. If we're in
6768 * immediate mode, we need to loop through and get status
6769 * information periodically.
6771 if (immediate == 0) {
6773 fprintf(stdout, "Sanitize Complete\n");
6775 goto scsisanitize_bailout;
6782 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6785 * There's really no need to do error recovery or
6786 * retries here, since we're just going to sit in a
6787 * loop and wait for the device to finish sanitizing.
6789 scsi_test_unit_ready(&ccb->csio,
6792 /* tag_action */ task_attr,
6793 /* sense_len */ SSD_FULL_SIZE,
6794 /* timeout */ 5000);
6796 /* Disable freezing the device queue */
6797 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6799 retval = cam_send_ccb(device, ccb);
6802 * If we get an error from the ioctl, bail out. SCSI
6803 * errors are expected.
6806 warn("error sending CAMIOCOMMAND ioctl");
6807 if (arglist & CAM_ARG_VERBOSE) {
6808 cam_error_print(device, ccb, CAM_ESF_ALL,
6809 CAM_EPF_ALL, stderr);
6812 goto scsisanitize_bailout;
6815 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6817 if ((status != CAM_REQ_CMP)
6818 && (status == CAM_SCSI_STATUS_ERROR)
6819 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6820 struct scsi_sense_data *sense;
6821 int error_code, sense_key, asc, ascq;
6823 sense = &ccb->csio.sense_data;
6824 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6825 ccb->csio.sense_resid, &error_code, &sense_key,
6826 &asc, &ascq, /*show_errors*/ 1);
6829 * According to the SCSI-3 spec, a drive that is in the
6830 * middle of a sanitize should return NOT READY with an
6831 * ASC of "logical unit not ready, sanitize in
6832 * progress". The sense key specific bytes will then
6833 * be a progress indicator.
6835 if ((sense_key == SSD_KEY_NOT_READY)
6836 && (asc == 0x04) && (ascq == 0x1b)) {
6839 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6840 ccb->csio.sense_resid, sks) == 0)
6843 u_int64_t percentage;
6845 val = scsi_2btoul(&sks[1]);
6846 percentage = 10000 * val;
6849 "\rSanitizing: %ju.%02u %% "
6851 (uintmax_t)(percentage /
6853 (unsigned)((percentage /
6857 } else if ((quiet == 0)
6858 && (++num_warnings <= 1)) {
6859 warnx("Unexpected SCSI Sense Key "
6860 "Specific value returned "
6861 "during sanitize:");
6862 scsi_sense_print(device, &ccb->csio,
6864 warnx("Unable to print status "
6865 "information, but sanitze will "
6867 warnx("will exit when sanitize is "
6872 warnx("Unexpected SCSI error during sanitize");
6873 cam_error_print(device, ccb, CAM_ESF_ALL,
6874 CAM_EPF_ALL, stderr);
6876 goto scsisanitize_bailout;
6879 } else if (status != CAM_REQ_CMP) {
6880 warnx("Unexpected CAM status %#x", status);
6881 if (arglist & CAM_ARG_VERBOSE)
6882 cam_error_print(device, ccb, CAM_ESF_ALL,
6883 CAM_EPF_ALL, stderr);
6885 goto scsisanitize_bailout;
6887 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6890 fprintf(stdout, "\nSanitize Complete\n");
6892 scsisanitize_bailout:
6895 if (data_ptr != NULL)
6903 scsireportluns(struct cam_device *device, int argc, char **argv,
6904 char *combinedopt, int task_attr, int retry_count, int timeout)
6907 int c, countonly, lunsonly;
6908 struct scsi_report_luns_data *lundata;
6910 uint8_t report_type;
6911 uint32_t list_len, i, j;
6916 report_type = RPL_REPORT_DEFAULT;
6917 ccb = cam_getccb(device);
6920 warnx("%s: error allocating ccb", __func__);
6924 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6929 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6938 if (strcasecmp(optarg, "default") == 0)
6939 report_type = RPL_REPORT_DEFAULT;
6940 else if (strcasecmp(optarg, "wellknown") == 0)
6941 report_type = RPL_REPORT_WELLKNOWN;
6942 else if (strcasecmp(optarg, "all") == 0)
6943 report_type = RPL_REPORT_ALL;
6945 warnx("%s: invalid report type \"%s\"",
6956 if ((countonly != 0)
6957 && (lunsonly != 0)) {
6958 warnx("%s: you can only specify one of -c or -l", __func__);
6963 * According to SPC-4, the allocation length must be at least 16
6964 * bytes -- enough for the header and one LUN.
6966 alloc_len = sizeof(*lundata) + 8;
6970 lundata = malloc(alloc_len);
6972 if (lundata == NULL) {
6973 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6978 scsi_report_luns(&ccb->csio,
6979 /*retries*/ retry_count,
6981 /*tag_action*/ task_attr,
6982 /*select_report*/ report_type,
6983 /*rpl_buf*/ lundata,
6984 /*alloc_len*/ alloc_len,
6985 /*sense_len*/ SSD_FULL_SIZE,
6986 /*timeout*/ timeout ? timeout : 5000);
6988 /* Disable freezing the device queue */
6989 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6991 if (arglist & CAM_ARG_ERR_RECOVER)
6992 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6994 if (cam_send_ccb(device, ccb) < 0) {
6995 warn("error sending REPORT LUNS command");
6997 if (arglist & CAM_ARG_VERBOSE)
6998 cam_error_print(device, ccb, CAM_ESF_ALL,
6999 CAM_EPF_ALL, stderr);
7005 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7006 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7012 list_len = scsi_4btoul(lundata->length);
7015 * If we need to list the LUNs, and our allocation
7016 * length was too short, reallocate and retry.
7018 if ((countonly == 0)
7019 && (list_len > (alloc_len - sizeof(*lundata)))) {
7020 alloc_len = list_len + sizeof(*lundata);
7026 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7027 ((list_len / 8) > 1) ? "s" : "");
7032 for (i = 0; i < (list_len / 8); i++) {
7036 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7038 fprintf(stdout, ",");
7039 switch (lundata->luns[i].lundata[j] &
7040 RPL_LUNDATA_ATYP_MASK) {
7041 case RPL_LUNDATA_ATYP_PERIPH:
7042 if ((lundata->luns[i].lundata[j] &
7043 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7044 fprintf(stdout, "%d:",
7045 lundata->luns[i].lundata[j] &
7046 RPL_LUNDATA_PERIPH_BUS_MASK);
7048 && ((lundata->luns[i].lundata[j+2] &
7049 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7052 fprintf(stdout, "%d",
7053 lundata->luns[i].lundata[j+1]);
7055 case RPL_LUNDATA_ATYP_FLAT: {
7057 tmplun[0] = lundata->luns[i].lundata[j] &
7058 RPL_LUNDATA_FLAT_LUN_MASK;
7059 tmplun[1] = lundata->luns[i].lundata[j+1];
7061 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7065 case RPL_LUNDATA_ATYP_LUN:
7066 fprintf(stdout, "%d:%d:%d",
7067 (lundata->luns[i].lundata[j+1] &
7068 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7069 lundata->luns[i].lundata[j] &
7070 RPL_LUNDATA_LUN_TARG_MASK,
7071 lundata->luns[i].lundata[j+1] &
7072 RPL_LUNDATA_LUN_LUN_MASK);
7074 case RPL_LUNDATA_ATYP_EXTLUN: {
7075 int field_len_code, eam_code;
7077 eam_code = lundata->luns[i].lundata[j] &
7078 RPL_LUNDATA_EXT_EAM_MASK;
7079 field_len_code = (lundata->luns[i].lundata[j] &
7080 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7082 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7083 && (field_len_code == 0x00)) {
7084 fprintf(stdout, "%d",
7085 lundata->luns[i].lundata[j+1]);
7086 } else if ((eam_code ==
7087 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7088 && (field_len_code == 0x03)) {
7092 * This format takes up all 8 bytes.
7093 * If we aren't starting at offset 0,
7097 fprintf(stdout, "Invalid "
7100 "specified format", j);
7104 bzero(tmp_lun, sizeof(tmp_lun));
7105 bcopy(&lundata->luns[i].lundata[j+1],
7106 &tmp_lun[1], sizeof(tmp_lun) - 1);
7107 fprintf(stdout, "%#jx",
7108 (intmax_t)scsi_8btou64(tmp_lun));
7111 fprintf(stderr, "Unknown Extended LUN"
7112 "Address method %#x, length "
7113 "code %#x", eam_code,
7120 fprintf(stderr, "Unknown LUN address method "
7121 "%#x\n", lundata->luns[i].lundata[0] &
7122 RPL_LUNDATA_ATYP_MASK);
7126 * For the flat addressing method, there are no
7127 * other levels after it.
7132 fprintf(stdout, "\n");
7145 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7146 char *combinedopt, int task_attr, int retry_count, int timeout)
7149 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7150 struct scsi_read_capacity_data rcap;
7151 struct scsi_read_capacity_data_long rcaplong;
7166 ccb = cam_getccb(device);
7169 warnx("%s: error allocating ccb", __func__);
7173 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7175 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7205 if ((blocksizeonly != 0)
7206 && (numblocks != 0)) {
7207 warnx("%s: you can only specify one of -b or -N", __func__);
7212 if ((blocksizeonly != 0)
7213 && (sizeonly != 0)) {
7214 warnx("%s: you can only specify one of -b or -s", __func__);
7221 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7227 && (blocksizeonly != 0)) {
7228 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7236 scsi_read_capacity(&ccb->csio,
7237 /*retries*/ retry_count,
7239 /*tag_action*/ task_attr,
7242 /*timeout*/ timeout ? timeout : 5000);
7244 /* Disable freezing the device queue */
7245 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7247 if (arglist & CAM_ARG_ERR_RECOVER)
7248 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7250 if (cam_send_ccb(device, ccb) < 0) {
7251 warn("error sending READ CAPACITY command");
7253 if (arglist & CAM_ARG_VERBOSE)
7254 cam_error_print(device, ccb, CAM_ESF_ALL,
7255 CAM_EPF_ALL, stderr);
7261 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7262 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7267 maxsector = scsi_4btoul(rcap.addr);
7268 block_len = scsi_4btoul(rcap.length);
7271 * A last block of 2^32-1 means that the true capacity is over 2TB,
7272 * and we need to issue the long READ CAPACITY to get the real
7273 * capacity. Otherwise, we're all set.
7275 if (maxsector != 0xffffffff)
7279 scsi_read_capacity_16(&ccb->csio,
7280 /*retries*/ retry_count,
7282 /*tag_action*/ task_attr,
7286 /*rcap_buf*/ (uint8_t *)&rcaplong,
7287 /*rcap_buf_len*/ sizeof(rcaplong),
7288 /*sense_len*/ SSD_FULL_SIZE,
7289 /*timeout*/ timeout ? timeout : 5000);
7291 /* Disable freezing the device queue */
7292 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7294 if (arglist & CAM_ARG_ERR_RECOVER)
7295 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7297 if (cam_send_ccb(device, ccb) < 0) {
7298 warn("error sending READ CAPACITY (16) command");
7300 if (arglist & CAM_ARG_VERBOSE)
7301 cam_error_print(device, ccb, CAM_ESF_ALL,
7302 CAM_EPF_ALL, stderr);
7308 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7309 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7314 maxsector = scsi_8btou64(rcaplong.addr);
7315 block_len = scsi_4btoul(rcaplong.length);
7318 if (blocksizeonly == 0) {
7320 * Humanize implies !quiet, and also implies numblocks.
7322 if (humanize != 0) {
7327 tmpbytes = (maxsector + 1) * block_len;
7328 ret = humanize_number(tmpstr, sizeof(tmpstr),
7329 tmpbytes, "", HN_AUTOSCALE,
7332 HN_DIVISOR_1000 : 0));
7334 warnx("%s: humanize_number failed!", __func__);
7338 fprintf(stdout, "Device Size: %s%s", tmpstr,
7339 (sizeonly == 0) ? ", " : "\n");
7340 } else if (numblocks != 0) {
7341 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7342 "Blocks: " : "", (uintmax_t)maxsector + 1,
7343 (sizeonly == 0) ? ", " : "\n");
7345 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7346 "Last Block: " : "", (uintmax_t)maxsector,
7347 (sizeonly == 0) ? ", " : "\n");
7351 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7352 "Block Length: " : "", block_len, (quiet == 0) ?
7361 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7362 int retry_count, int timeout)
7366 uint8_t *smp_request = NULL, *smp_response = NULL;
7367 int request_size = 0, response_size = 0;
7368 int fd_request = 0, fd_response = 0;
7369 char *datastr = NULL;
7370 struct get_hook hook;
7375 * Note that at the moment we don't support sending SMP CCBs to
7376 * devices that aren't probed by CAM.
7378 ccb = cam_getccb(device);
7380 warnx("%s: error allocating CCB", __func__);
7384 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7386 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7389 arglist |= CAM_ARG_CMD_IN;
7390 response_size = strtol(optarg, NULL, 0);
7391 if (response_size <= 0) {
7392 warnx("invalid number of response bytes %d",
7395 goto smpcmd_bailout;
7397 hook.argc = argc - optind;
7398 hook.argv = argv + optind;
7401 datastr = cget(&hook, NULL);
7403 * If the user supplied "-" instead of a format, he
7404 * wants the data to be written to stdout.
7406 if ((datastr != NULL)
7407 && (datastr[0] == '-'))
7410 smp_response = (u_int8_t *)malloc(response_size);
7411 if (smp_response == NULL) {
7412 warn("can't malloc memory for SMP response");
7414 goto smpcmd_bailout;
7418 arglist |= CAM_ARG_CMD_OUT;
7419 request_size = strtol(optarg, NULL, 0);
7420 if (request_size <= 0) {
7421 warnx("invalid number of request bytes %d",
7424 goto smpcmd_bailout;
7426 hook.argc = argc - optind;
7427 hook.argv = argv + optind;
7429 datastr = cget(&hook, NULL);
7430 smp_request = (u_int8_t *)malloc(request_size);
7431 if (smp_request == NULL) {
7432 warn("can't malloc memory for SMP request");
7434 goto smpcmd_bailout;
7436 bzero(smp_request, request_size);
7438 * If the user supplied "-" instead of a format, he
7439 * wants the data to be read from stdin.
7441 if ((datastr != NULL)
7442 && (datastr[0] == '-'))
7445 buff_encode_visit(smp_request, request_size,
7456 * If fd_data is set, and we're writing to the device, we need to
7457 * read the data the user wants written from stdin.
7459 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7461 int amt_to_read = request_size;
7462 u_int8_t *buf_ptr = smp_request;
7464 for (amt_read = 0; amt_to_read > 0;
7465 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7466 if (amt_read == -1) {
7467 warn("error reading data from stdin");
7469 goto smpcmd_bailout;
7471 amt_to_read -= amt_read;
7472 buf_ptr += amt_read;
7476 if (((arglist & CAM_ARG_CMD_IN) == 0)
7477 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7478 warnx("%s: need both the request (-r) and response (-R) "
7479 "arguments", __func__);
7481 goto smpcmd_bailout;
7484 flags |= CAM_DEV_QFRZDIS;
7486 cam_fill_smpio(&ccb->smpio,
7487 /*retries*/ retry_count,
7490 /*smp_request*/ smp_request,
7491 /*smp_request_len*/ request_size,
7492 /*smp_response*/ smp_response,
7493 /*smp_response_len*/ response_size,
7494 /*timeout*/ timeout ? timeout : 5000);
7496 ccb->smpio.flags = SMP_FLAG_NONE;
7498 if (((retval = cam_send_ccb(device, ccb)) < 0)
7499 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7500 const char warnstr[] = "error sending command";
7507 if (arglist & CAM_ARG_VERBOSE) {
7508 cam_error_print(device, ccb, CAM_ESF_ALL,
7509 CAM_EPF_ALL, stderr);
7513 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7514 && (response_size > 0)) {
7515 if (fd_response == 0) {
7516 buff_decode_visit(smp_response, response_size,
7517 datastr, arg_put, NULL);
7518 fprintf(stdout, "\n");
7520 ssize_t amt_written;
7521 int amt_to_write = response_size;
7522 u_int8_t *buf_ptr = smp_response;
7524 for (amt_written = 0; (amt_to_write > 0) &&
7525 (amt_written = write(STDOUT_FILENO, buf_ptr,
7526 amt_to_write)) > 0;){
7527 amt_to_write -= amt_written;
7528 buf_ptr += amt_written;
7530 if (amt_written == -1) {
7531 warn("error writing data to stdout");
7533 goto smpcmd_bailout;
7534 } else if ((amt_written == 0)
7535 && (amt_to_write > 0)) {
7536 warnx("only wrote %u bytes out of %u",
7537 response_size - amt_to_write,
7546 if (smp_request != NULL)
7549 if (smp_response != NULL)
7556 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7557 int retry_count, int timeout)
7561 int32_t mmc_opcode = 0, mmc_arg = 0;
7562 int32_t mmc_flags = -1;
7565 int is_bw_4 = 0, is_bw_1 = 0;
7566 int is_highspeed = 0, is_stdspeed = 0;
7567 int is_info_request = 0;
7569 uint8_t mmc_data_byte = 0;
7571 /* For IO_RW_EXTENDED command */
7572 uint8_t *mmc_data = NULL;
7573 struct mmc_data mmc_d;
7574 int mmc_data_len = 0;
7577 * Note that at the moment we don't support sending SMP CCBs to
7578 * devices that aren't probed by CAM.
7580 ccb = cam_getccb(device);
7582 warnx("%s: error allocating CCB", __func__);
7586 bzero(&(&ccb->ccb_h)[1],
7587 sizeof(union ccb) - sizeof(struct ccb_hdr));
7589 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7598 if (!strcmp(optarg, "high"))
7604 is_info_request = 1;
7607 mmc_opcode = strtol(optarg, NULL, 0);
7608 if (mmc_opcode < 0) {
7609 warnx("invalid MMC opcode %d",
7612 goto mmccmd_bailout;
7616 mmc_arg = strtol(optarg, NULL, 0);
7618 warnx("invalid MMC arg %d",
7621 goto mmccmd_bailout;
7625 mmc_flags = strtol(optarg, NULL, 0);
7626 if (mmc_flags < 0) {
7627 warnx("invalid MMC flags %d",
7630 goto mmccmd_bailout;
7634 mmc_data_len = strtol(optarg, NULL, 0);
7635 if (mmc_data_len <= 0) {
7636 warnx("invalid MMC data len %d",
7639 goto mmccmd_bailout;
7646 mmc_data_byte = strtol(optarg, NULL, 0);
7652 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7654 /* If flags are left default, supply the right flags */
7656 switch (mmc_opcode) {
7657 case MMC_GO_IDLE_STATE:
7658 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7660 case IO_SEND_OP_COND:
7661 mmc_flags = MMC_RSP_R4;
7663 case SD_SEND_RELATIVE_ADDR:
7664 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7666 case MMC_SELECT_CARD:
7667 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7668 mmc_arg = mmc_arg << 16;
7670 case SD_IO_RW_DIRECT:
7671 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7672 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7674 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7676 case SD_IO_RW_EXTENDED:
7677 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7678 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7679 int len_arg = mmc_data_len;
7680 if (mmc_data_len == 512)
7684 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7686 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7689 mmc_flags = MMC_RSP_R1;
7693 // Switch bus width instead of sending IO command
7694 if (is_bw_4 || is_bw_1) {
7695 struct ccb_trans_settings_mmc *cts;
7696 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7697 ccb->ccb_h.flags = 0;
7698 cts = &ccb->cts.proto_specific.mmc;
7699 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7700 cts->ios_valid = MMC_BW;
7701 if (((retval = cam_send_ccb(device, ccb)) < 0)
7702 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7703 warn("Error sending command");
7705 printf("Parameters set OK\n");
7711 // Switch bus speed instead of sending IO command
7712 if (is_stdspeed || is_highspeed) {
7713 struct ccb_trans_settings_mmc *cts;
7714 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7715 ccb->ccb_h.flags = 0;
7716 cts = &ccb->cts.proto_specific.mmc;
7717 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
7718 cts->ios_valid = MMC_BT;
7719 if (((retval = cam_send_ccb(device, ccb)) < 0)
7720 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7721 warn("Error sending command");
7723 printf("Speed set OK (HS: %d)\n", is_highspeed);
7729 // Get information about controller and its settings
7730 if (is_info_request) {
7731 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
7732 ccb->ccb_h.flags = 0;
7733 struct ccb_trans_settings_mmc *cts;
7734 cts = &ccb->cts.proto_specific.mmc;
7735 if (((retval = cam_send_ccb(device, ccb)) < 0)
7736 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7737 warn("Error sending command");
7740 printf("Host controller information\n");
7741 printf("Host OCR: 0x%x\n", cts->host_ocr);
7742 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
7743 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
7744 printf("Supported bus width: ");
7745 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
7747 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
7749 printf("\nCurrent settings:\n");
7750 printf("Bus width: ");
7751 switch (cts->ios.bus_width) {
7762 printf("Freq: %d.%03d MHz%s\n",
7763 cts->ios.clock / 1000000,
7764 (cts->ios.clock / 1000) % 1000,
7765 cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : "");
7769 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
7771 if (mmc_data_len > 0) {
7772 flags |= CAM_DIR_IN;
7773 mmc_data = malloc(mmc_data_len);
7774 memset(mmc_data, 0, mmc_data_len);
7775 memset(&mmc_d, 0, sizeof(mmc_d));
7776 mmc_d.len = mmc_data_len;
7777 mmc_d.data = mmc_data;
7778 mmc_d.flags = MMC_DATA_READ;
7779 } else flags |= CAM_DIR_NONE;
7781 cam_fill_mmcio(&ccb->mmcio,
7782 /*retries*/ retry_count,
7785 /*mmc_opcode*/ mmc_opcode,
7786 /*mmc_arg*/ mmc_arg,
7787 /*mmc_flags*/ mmc_flags,
7788 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
7789 /*timeout*/ timeout ? timeout : 5000);
7791 if (((retval = cam_send_ccb(device, ccb)) < 0)
7792 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7793 const char warnstr[] = "error sending command";
7800 if (arglist & CAM_ARG_VERBOSE) {
7801 cam_error_print(device, ccb, CAM_ESF_ALL,
7802 CAM_EPF_ALL, stderr);
7806 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
7807 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
7808 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
7809 ccb->mmcio.cmd.resp[1],
7810 ccb->mmcio.cmd.resp[2],
7811 ccb->mmcio.cmd.resp[3]);
7813 switch (mmc_opcode) {
7814 case SD_IO_RW_DIRECT:
7815 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
7816 SD_R5_DATA(ccb->mmcio.cmd.resp),
7817 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
7819 case SD_IO_RW_EXTENDED:
7820 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
7821 hexdump(mmc_data, mmc_data_len, NULL, 0);
7823 case SD_SEND_RELATIVE_ADDR:
7824 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
7827 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
7834 if (mmc_data_len > 0 && mmc_data != NULL)
7841 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7842 char *combinedopt, int retry_count, int timeout)
7845 struct smp_report_general_request *request = NULL;
7846 struct smp_report_general_response *response = NULL;
7847 struct sbuf *sb = NULL;
7849 int c, long_response = 0;
7853 * Note that at the moment we don't support sending SMP CCBs to
7854 * devices that aren't probed by CAM.
7856 ccb = cam_getccb(device);
7858 warnx("%s: error allocating CCB", __func__);
7862 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7864 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7873 request = malloc(sizeof(*request));
7874 if (request == NULL) {
7875 warn("%s: unable to allocate %zd bytes", __func__,
7881 response = malloc(sizeof(*response));
7882 if (response == NULL) {
7883 warn("%s: unable to allocate %zd bytes", __func__,
7890 smp_report_general(&ccb->smpio,
7894 /*request_len*/ sizeof(*request),
7895 (uint8_t *)response,
7896 /*response_len*/ sizeof(*response),
7897 /*long_response*/ long_response,
7900 if (((retval = cam_send_ccb(device, ccb)) < 0)
7901 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7902 const char warnstr[] = "error sending command";
7909 if (arglist & CAM_ARG_VERBOSE) {
7910 cam_error_print(device, ccb, CAM_ESF_ALL,
7911 CAM_EPF_ALL, stderr);
7918 * If the device supports the long response bit, try again and see
7919 * if we can get all of the data.
7921 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7922 && (long_response == 0)) {
7923 ccb->ccb_h.status = CAM_REQ_INPROG;
7924 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7930 * XXX KDM detect and decode SMP errors here.
7932 sb = sbuf_new_auto();
7934 warnx("%s: error allocating sbuf", __func__);
7938 smp_report_general_sbuf(response, sizeof(*response), sb);
7940 if (sbuf_finish(sb) != 0) {
7941 warnx("%s: sbuf_finish", __func__);
7945 printf("%s", sbuf_data(sb));
7951 if (request != NULL)
7954 if (response != NULL)
7963 static struct camcontrol_opts phy_ops[] = {
7964 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7965 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7966 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7967 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7968 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7969 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7970 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7971 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7972 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7977 smpphycontrol(struct cam_device *device, int argc, char **argv,
7978 char *combinedopt, int retry_count, int timeout)
7981 struct smp_phy_control_request *request = NULL;
7982 struct smp_phy_control_response *response = NULL;
7983 int long_response = 0;
7986 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7988 uint64_t attached_dev_name = 0;
7989 int dev_name_set = 0;
7990 uint32_t min_plr = 0, max_plr = 0;
7991 uint32_t pp_timeout_val = 0;
7992 int slumber_partial = 0;
7993 int set_pp_timeout_val = 0;
7997 * Note that at the moment we don't support sending SMP CCBs to
7998 * devices that aren't probed by CAM.
8000 ccb = cam_getccb(device);
8002 warnx("%s: error allocating CCB", __func__);
8006 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8008 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8016 if (strcasecmp(optarg, "enable") == 0)
8018 else if (strcasecmp(optarg, "disable") == 0)
8021 warnx("%s: Invalid argument %s", __func__,
8028 slumber_partial |= enable <<
8029 SMP_PC_SAS_SLUMBER_SHIFT;
8032 slumber_partial |= enable <<
8033 SMP_PC_SAS_PARTIAL_SHIFT;
8036 slumber_partial |= enable <<
8037 SMP_PC_SATA_SLUMBER_SHIFT;
8040 slumber_partial |= enable <<
8041 SMP_PC_SATA_PARTIAL_SHIFT;
8044 warnx("%s: programmer error", __func__);
8047 break; /*NOTREACHED*/
8052 attached_dev_name = (uintmax_t)strtoumax(optarg,
8061 * We don't do extensive checking here, so this
8062 * will continue to work when new speeds come out.
8064 min_plr = strtoul(optarg, NULL, 0);
8066 || (min_plr > 0xf)) {
8067 warnx("%s: invalid link rate %x",
8075 * We don't do extensive checking here, so this
8076 * will continue to work when new speeds come out.
8078 max_plr = strtoul(optarg, NULL, 0);
8080 || (max_plr > 0xf)) {
8081 warnx("%s: invalid link rate %x",
8088 camcontrol_optret optreturn;
8089 cam_argmask argnums;
8092 if (phy_op_set != 0) {
8093 warnx("%s: only one phy operation argument "
8094 "(-o) allowed", __func__);
8102 * Allow the user to specify the phy operation
8103 * numerically, as well as with a name. This will
8104 * future-proof it a bit, so options that are added
8105 * in future specs can be used.
8107 if (isdigit(optarg[0])) {
8108 phy_operation = strtoul(optarg, NULL, 0);
8109 if ((phy_operation == 0)
8110 || (phy_operation > 0xff)) {
8111 warnx("%s: invalid phy operation %#x",
8112 __func__, phy_operation);
8118 optreturn = getoption(phy_ops, optarg, &phy_operation,
8121 if (optreturn == CC_OR_AMBIGUOUS) {
8122 warnx("%s: ambiguous option %s", __func__,
8127 } else if (optreturn == CC_OR_NOT_FOUND) {
8128 warnx("%s: option %s not found", __func__,
8140 pp_timeout_val = strtoul(optarg, NULL, 0);
8141 if (pp_timeout_val > 15) {
8142 warnx("%s: invalid partial pathway timeout "
8143 "value %u, need a value less than 16",
8144 __func__, pp_timeout_val);
8148 set_pp_timeout_val = 1;
8156 warnx("%s: a PHY (-p phy) argument is required",__func__);
8161 if (((dev_name_set != 0)
8162 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8163 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8164 && (dev_name_set == 0))) {
8165 warnx("%s: -d name and -o setdevname arguments both "
8166 "required to set device name", __func__);
8171 request = malloc(sizeof(*request));
8172 if (request == NULL) {
8173 warn("%s: unable to allocate %zd bytes", __func__,
8179 response = malloc(sizeof(*response));
8180 if (response == NULL) {
8181 warn("%s: unable to allocate %zd bytes", __func__,
8187 smp_phy_control(&ccb->smpio,
8192 (uint8_t *)response,
8195 /*expected_exp_change_count*/ 0,
8198 (set_pp_timeout_val != 0) ? 1 : 0,
8206 if (((retval = cam_send_ccb(device, ccb)) < 0)
8207 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8208 const char warnstr[] = "error sending command";
8215 if (arglist & CAM_ARG_VERBOSE) {
8217 * Use CAM_EPF_NORMAL so we only get one line of
8218 * SMP command decoding.
8220 cam_error_print(device, ccb, CAM_ESF_ALL,
8221 CAM_EPF_NORMAL, stderr);
8227 /* XXX KDM print out something here for success? */
8232 if (request != NULL)
8235 if (response != NULL)
8242 smpmaninfo(struct cam_device *device, int argc, char **argv,
8243 char *combinedopt, int retry_count, int timeout)
8246 struct smp_report_manuf_info_request request;
8247 struct smp_report_manuf_info_response response;
8248 struct sbuf *sb = NULL;
8249 int long_response = 0;
8254 * Note that at the moment we don't support sending SMP CCBs to
8255 * devices that aren't probed by CAM.
8257 ccb = cam_getccb(device);
8259 warnx("%s: error allocating CCB", __func__);
8263 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8265 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8274 bzero(&request, sizeof(request));
8275 bzero(&response, sizeof(response));
8277 smp_report_manuf_info(&ccb->smpio,
8282 (uint8_t *)&response,
8287 if (((retval = cam_send_ccb(device, ccb)) < 0)
8288 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8289 const char warnstr[] = "error sending command";
8296 if (arglist & CAM_ARG_VERBOSE) {
8297 cam_error_print(device, ccb, CAM_ESF_ALL,
8298 CAM_EPF_ALL, stderr);
8304 sb = sbuf_new_auto();
8306 warnx("%s: error allocating sbuf", __func__);
8310 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8312 if (sbuf_finish(sb) != 0) {
8313 warnx("%s: sbuf_finish", __func__);
8317 printf("%s", sbuf_data(sb));
8331 getdevid(struct cam_devitem *item)
8334 union ccb *ccb = NULL;
8336 struct cam_device *dev;
8338 dev = cam_open_btl(item->dev_match.path_id,
8339 item->dev_match.target_id,
8340 item->dev_match.target_lun, O_RDWR, NULL);
8343 warnx("%s", cam_errbuf);
8348 item->device_id_len = 0;
8350 ccb = cam_getccb(dev);
8352 warnx("%s: error allocating CCB", __func__);
8357 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8360 * On the first try, we just probe for the size of the data, and
8361 * then allocate that much memory and try again.
8364 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8365 ccb->ccb_h.flags = CAM_DIR_IN;
8366 ccb->cdai.flags = CDAI_FLAG_NONE;
8367 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8368 ccb->cdai.bufsiz = item->device_id_len;
8369 if (item->device_id_len != 0)
8370 ccb->cdai.buf = (uint8_t *)item->device_id;
8372 if (cam_send_ccb(dev, ccb) < 0) {
8373 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8378 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8379 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8384 if (item->device_id_len == 0) {
8386 * This is our first time through. Allocate the buffer,
8387 * and then go back to get the data.
8389 if (ccb->cdai.provsiz == 0) {
8390 warnx("%s: invalid .provsiz field returned with "
8391 "XPT_GDEV_ADVINFO CCB", __func__);
8395 item->device_id_len = ccb->cdai.provsiz;
8396 item->device_id = malloc(item->device_id_len);
8397 if (item->device_id == NULL) {
8398 warn("%s: unable to allocate %d bytes", __func__,
8399 item->device_id_len);
8403 ccb->ccb_h.status = CAM_REQ_INPROG;
8409 cam_close_device(dev);
8418 * XXX KDM merge this code with getdevtree()?
8421 buildbusdevlist(struct cam_devlist *devlist)
8424 int bufsize, fd = -1;
8425 struct dev_match_pattern *patterns;
8426 struct cam_devitem *item = NULL;
8427 int skip_device = 0;
8430 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8431 warn("couldn't open %s", XPT_DEVICE);
8435 bzero(&ccb, sizeof(union ccb));
8437 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8438 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8439 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8441 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8442 bufsize = sizeof(struct dev_match_result) * 100;
8443 ccb.cdm.match_buf_len = bufsize;
8444 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8445 if (ccb.cdm.matches == NULL) {
8446 warnx("can't malloc memory for matches");
8450 ccb.cdm.num_matches = 0;
8451 ccb.cdm.num_patterns = 2;
8452 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8453 ccb.cdm.num_patterns;
8455 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8456 if (patterns == NULL) {
8457 warnx("can't malloc memory for patterns");
8462 ccb.cdm.patterns = patterns;
8463 bzero(patterns, ccb.cdm.pattern_buf_len);
8465 patterns[0].type = DEV_MATCH_DEVICE;
8466 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8467 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8468 patterns[1].type = DEV_MATCH_PERIPH;
8469 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8470 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8473 * We do the ioctl multiple times if necessary, in case there are
8474 * more than 100 nodes in the EDT.
8479 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8480 warn("error sending CAMIOCOMMAND ioctl");
8485 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8486 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8487 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8488 warnx("got CAM error %#x, CDM error %d\n",
8489 ccb.ccb_h.status, ccb.cdm.status);
8494 for (i = 0; i < ccb.cdm.num_matches; i++) {
8495 switch (ccb.cdm.matches[i].type) {
8496 case DEV_MATCH_DEVICE: {
8497 struct device_match_result *dev_result;
8500 &ccb.cdm.matches[i].result.device_result;
8502 if (dev_result->flags &
8503 DEV_RESULT_UNCONFIGURED) {
8509 item = malloc(sizeof(*item));
8511 warn("%s: unable to allocate %zd bytes",
8512 __func__, sizeof(*item));
8516 bzero(item, sizeof(*item));
8517 bcopy(dev_result, &item->dev_match,
8518 sizeof(*dev_result));
8519 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8522 if (getdevid(item) != 0) {
8528 case DEV_MATCH_PERIPH: {
8529 struct periph_match_result *periph_result;
8532 &ccb.cdm.matches[i].result.periph_result;
8534 if (skip_device != 0)
8536 item->num_periphs++;
8537 item->periph_matches = realloc(
8538 item->periph_matches,
8540 sizeof(struct periph_match_result));
8541 if (item->periph_matches == NULL) {
8542 warn("%s: error allocating periph "
8547 bcopy(periph_result, &item->periph_matches[
8548 item->num_periphs - 1],
8549 sizeof(*periph_result));
8553 fprintf(stderr, "%s: unexpected match "
8554 "type %d\n", __func__,
8555 ccb.cdm.matches[i].type);
8558 break; /*NOTREACHED*/
8561 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8562 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8570 free(ccb.cdm.matches);
8573 freebusdevlist(devlist);
8579 freebusdevlist(struct cam_devlist *devlist)
8581 struct cam_devitem *item, *item2;
8583 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8584 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8586 free(item->device_id);
8587 free(item->periph_matches);
8592 static struct cam_devitem *
8593 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8595 struct cam_devitem *item;
8597 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8598 struct scsi_vpd_id_descriptor *idd;
8601 * XXX KDM look for LUN IDs as well?
8603 idd = scsi_get_devid(item->device_id,
8604 item->device_id_len,
8605 scsi_devid_is_sas_target);
8609 if (scsi_8btou64(idd->identifier) == sasaddr)
8617 smpphylist(struct cam_device *device, int argc, char **argv,
8618 char *combinedopt, int retry_count, int timeout)
8620 struct smp_report_general_request *rgrequest = NULL;
8621 struct smp_report_general_response *rgresponse = NULL;
8622 struct smp_discover_request *disrequest = NULL;
8623 struct smp_discover_response *disresponse = NULL;
8624 struct cam_devlist devlist;
8626 int long_response = 0;
8633 * Note that at the moment we don't support sending SMP CCBs to
8634 * devices that aren't probed by CAM.
8636 ccb = cam_getccb(device);
8638 warnx("%s: error allocating CCB", __func__);
8642 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8643 STAILQ_INIT(&devlist.dev_queue);
8645 rgrequest = malloc(sizeof(*rgrequest));
8646 if (rgrequest == NULL) {
8647 warn("%s: unable to allocate %zd bytes", __func__,
8648 sizeof(*rgrequest));
8653 rgresponse = malloc(sizeof(*rgresponse));
8654 if (rgresponse == NULL) {
8655 warn("%s: unable to allocate %zd bytes", __func__,
8656 sizeof(*rgresponse));
8661 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8674 smp_report_general(&ccb->smpio,
8678 /*request_len*/ sizeof(*rgrequest),
8679 (uint8_t *)rgresponse,
8680 /*response_len*/ sizeof(*rgresponse),
8681 /*long_response*/ long_response,
8684 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8686 if (((retval = cam_send_ccb(device, ccb)) < 0)
8687 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8688 const char warnstr[] = "error sending command";
8695 if (arglist & CAM_ARG_VERBOSE) {
8696 cam_error_print(device, ccb, CAM_ESF_ALL,
8697 CAM_EPF_ALL, stderr);
8703 num_phys = rgresponse->num_phys;
8705 if (num_phys == 0) {
8707 fprintf(stdout, "%s: No Phys reported\n", __func__);
8712 devlist.path_id = device->path_id;
8714 retval = buildbusdevlist(&devlist);
8719 fprintf(stdout, "%d PHYs:\n", num_phys);
8720 fprintf(stdout, "PHY Attached SAS Address\n");
8723 disrequest = malloc(sizeof(*disrequest));
8724 if (disrequest == NULL) {
8725 warn("%s: unable to allocate %zd bytes", __func__,
8726 sizeof(*disrequest));
8731 disresponse = malloc(sizeof(*disresponse));
8732 if (disresponse == NULL) {
8733 warn("%s: unable to allocate %zd bytes", __func__,
8734 sizeof(*disresponse));
8739 for (i = 0; i < num_phys; i++) {
8740 struct cam_devitem *item;
8741 struct device_match_result *dev_match;
8742 char vendor[16], product[48], revision[16];
8746 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8748 ccb->ccb_h.status = CAM_REQ_INPROG;
8749 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8751 smp_discover(&ccb->smpio,
8755 sizeof(*disrequest),
8756 (uint8_t *)disresponse,
8757 sizeof(*disresponse),
8759 /*ignore_zone_group*/ 0,
8763 if (((retval = cam_send_ccb(device, ccb)) < 0)
8764 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
8765 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
8766 const char warnstr[] = "error sending command";
8773 if (arglist & CAM_ARG_VERBOSE) {
8774 cam_error_print(device, ccb, CAM_ESF_ALL,
8775 CAM_EPF_ALL, stderr);
8781 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
8783 fprintf(stdout, "%3d <vacant>\n", i);
8787 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
8790 item = findsasdevice(&devlist,
8791 scsi_8btou64(disresponse->attached_sas_address));
8795 || (item != NULL)) {
8796 fprintf(stdout, "%3d 0x%016jx", i,
8797 (uintmax_t)scsi_8btou64(
8798 disresponse->attached_sas_address));
8800 fprintf(stdout, "\n");
8803 } else if (quiet != 0)
8806 dev_match = &item->dev_match;
8808 if (dev_match->protocol == PROTO_SCSI) {
8809 cam_strvis(vendor, dev_match->inq_data.vendor,
8810 sizeof(dev_match->inq_data.vendor),
8812 cam_strvis(product, dev_match->inq_data.product,
8813 sizeof(dev_match->inq_data.product),
8815 cam_strvis(revision, dev_match->inq_data.revision,
8816 sizeof(dev_match->inq_data.revision),
8818 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8820 } else if ((dev_match->protocol == PROTO_ATA)
8821 || (dev_match->protocol == PROTO_SATAPM)) {
8822 cam_strvis(product, dev_match->ident_data.model,
8823 sizeof(dev_match->ident_data.model),
8825 cam_strvis(revision, dev_match->ident_data.revision,
8826 sizeof(dev_match->ident_data.revision),
8828 sprintf(tmpstr, "<%s %s>", product, revision);
8830 sprintf(tmpstr, "<>");
8832 fprintf(stdout, " %-33s ", tmpstr);
8835 * If we have 0 periphs, that's a bug...
8837 if (item->num_periphs == 0) {
8838 fprintf(stdout, "\n");
8842 fprintf(stdout, "(");
8843 for (j = 0; j < item->num_periphs; j++) {
8845 fprintf(stdout, ",");
8847 fprintf(stdout, "%s%d",
8848 item->periph_matches[j].periph_name,
8849 item->periph_matches[j].unit_number);
8852 fprintf(stdout, ")\n");
8866 freebusdevlist(&devlist);
8872 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
8874 struct ata_res *res;
8876 res = &ccb->ataio.res;
8877 if (res->status & ATA_STATUS_ERROR) {
8878 if (arglist & CAM_ARG_VERBOSE) {
8879 cam_error_print(device, ccb, CAM_ESF_ALL,
8880 CAM_EPF_ALL, stderr);
8881 printf("error = 0x%02x, sector_count = 0x%04x, "
8882 "device = 0x%02x, status = 0x%02x\n",
8883 res->error, res->sector_count,
8884 res->device, res->status);
8890 if (arglist & CAM_ARG_VERBOSE) {
8891 fprintf(stdout, "%s%d: Raw native check power data:\n",
8892 device->device_name, device->dev_unit_num);
8893 /* res is 4 byte aligned */
8894 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
8896 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
8897 "status = 0x%02x\n", res->error, res->sector_count,
8898 res->device, res->status);
8901 printf("%s%d: ", device->device_name, device->dev_unit_num);
8902 switch (res->sector_count) {
8904 printf("Standby mode\n");
8907 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
8910 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
8913 printf("Idle mode\n");
8916 printf("Active or Idle mode\n");
8919 printf("Unknown mode 0x%02x\n", res->sector_count);
8927 atapm(struct cam_device *device, int argc, char **argv,
8928 char *combinedopt, int retry_count, int timeout)
8934 u_int8_t ata_flags = 0;
8937 ccb = cam_getccb(device);
8940 warnx("%s: error allocating ccb", __func__);
8944 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8953 if (strcmp(argv[1], "idle") == 0) {
8955 cmd = ATA_IDLE_IMMEDIATE;
8958 } else if (strcmp(argv[1], "standby") == 0) {
8960 cmd = ATA_STANDBY_IMMEDIATE;
8962 cmd = ATA_STANDBY_CMD;
8963 } else if (strcmp(argv[1], "powermode") == 0) {
8964 cmd = ATA_CHECK_POWER_MODE;
8965 ata_flags = AP_FLAG_CHK_COND;
8974 else if (t <= (240 * 5))
8976 else if (t <= (252 * 5))
8977 /* special encoding for 21 minutes */
8979 else if (t <= (11 * 30 * 60))
8980 sc = (t - 1) / (30 * 60) + 241;
8984 retval = ata_do_cmd(device,
8986 /*retries*/retry_count,
8987 /*flags*/CAM_DIR_NONE,
8988 /*protocol*/AP_PROTO_NON_DATA,
8989 /*ata_flags*/ata_flags,
8990 /*tag_action*/MSG_SIMPLE_Q_TAG,
8997 /*timeout*/timeout ? timeout : 30 * 1000,
9002 if (retval || cmd != ATA_CHECK_POWER_MODE)
9005 return (atapm_proc_resp(device, ccb));
9009 ataaxm(struct cam_device *device, int argc, char **argv,
9010 char *combinedopt, int retry_count, int timeout)
9018 ccb = cam_getccb(device);
9021 warnx("%s: error allocating ccb", __func__);
9025 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9035 if (strcmp(argv[1], "apm") == 0) {
9051 retval = ata_do_28bit_cmd(device,
9053 /*retries*/retry_count,
9054 /*flags*/CAM_DIR_NONE,
9055 /*protocol*/AP_PROTO_NON_DATA,
9056 /*tag_action*/MSG_SIMPLE_Q_TAG,
9057 /*command*/ATA_SETFEATURES,
9063 /*timeout*/timeout ? timeout : 30 * 1000,
9071 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9072 int show_sa_errors, int sa_set, int service_action,
9073 int timeout_desc, int task_attr, int retry_count, int timeout,
9074 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9076 union ccb *ccb = NULL;
9077 uint8_t *buf = NULL;
9078 uint32_t alloc_len = 0, num_opcodes;
9079 uint32_t valid_len = 0;
9080 uint32_t avail_len = 0;
9081 struct scsi_report_supported_opcodes_all *all_hdr;
9082 struct scsi_report_supported_opcodes_one *one;
9087 * Make it clear that we haven't yet allocated or filled anything.
9092 ccb = cam_getccb(device);
9094 warnx("couldn't allocate CCB");
9099 /* cam_getccb cleans up the header, caller has to zero the payload */
9100 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9102 if (opcode_set != 0) {
9103 options |= RSO_OPTIONS_OC;
9105 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9108 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9109 sizeof(struct scsi_report_supported_opcodes_descr));
9112 if (timeout_desc != 0) {
9113 options |= RSO_RCTD;
9114 alloc_len += num_opcodes *
9115 sizeof(struct scsi_report_supported_opcodes_timeout);
9119 options |= RSO_OPTIONS_OC_SA;
9120 if (show_sa_errors != 0)
9121 options &= ~RSO_OPTIONS_OC;
9130 buf = malloc(alloc_len);
9132 warn("Unable to allocate %u bytes", alloc_len);
9136 bzero(buf, alloc_len);
9138 scsi_report_supported_opcodes(&ccb->csio,
9139 /*retries*/ retry_count,
9141 /*tag_action*/ task_attr,
9142 /*options*/ options,
9143 /*req_opcode*/ opcode,
9144 /*req_service_action*/ service_action,
9146 /*dxfer_len*/ alloc_len,
9147 /*sense_len*/ SSD_FULL_SIZE,
9148 /*timeout*/ timeout ? timeout : 10000);
9150 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9152 if (retry_count != 0)
9153 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9155 if (cam_send_ccb(device, ccb) < 0) {
9156 perror("error sending REPORT SUPPORTED OPERATION CODES");
9161 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9162 if (verbosemode != 0)
9163 cam_error_print(device, ccb, CAM_ESF_ALL,
9164 CAM_EPF_ALL, stderr);
9169 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9171 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9172 && (valid_len >= sizeof(*all_hdr))) {
9173 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9174 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9175 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9176 && (valid_len >= sizeof(*one))) {
9177 uint32_t cdb_length;
9179 one = (struct scsi_report_supported_opcodes_one *)buf;
9180 cdb_length = scsi_2btoul(one->cdb_length);
9181 avail_len = sizeof(*one) + cdb_length;
9182 if (one->support & RSO_ONE_CTDP) {
9183 struct scsi_report_supported_opcodes_timeout *td;
9185 td = (struct scsi_report_supported_opcodes_timeout *)
9187 if (valid_len >= (avail_len + sizeof(td->length))) {
9188 avail_len += scsi_2btoul(td->length) +
9191 avail_len += sizeof(*td);
9197 * avail_len could be zero if we didn't get enough data back from
9198 * thet target to determine
9200 if ((avail_len != 0)
9201 && (avail_len > valid_len)) {
9202 alloc_len = avail_len;
9206 *fill_len = valid_len;
9218 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9219 int req_sa, uint8_t *buf, uint32_t valid_len)
9221 struct scsi_report_supported_opcodes_one *one;
9222 struct scsi_report_supported_opcodes_timeout *td;
9223 uint32_t cdb_len = 0, td_len = 0;
9224 const char *op_desc = NULL;
9228 one = (struct scsi_report_supported_opcodes_one *)buf;
9231 * If we don't have the full single opcode descriptor, no point in
9234 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9236 warnx("Only %u bytes returned, not enough to verify support",
9242 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9244 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9247 printf(", SA 0x%x", req_sa);
9250 switch (one->support & RSO_ONE_SUP_MASK) {
9251 case RSO_ONE_SUP_UNAVAIL:
9252 printf("No command support information currently available\n");
9254 case RSO_ONE_SUP_NOT_SUP:
9255 printf("Command not supported\n");
9258 break; /*NOTREACHED*/
9259 case RSO_ONE_SUP_AVAIL:
9260 printf("Command is supported, complies with a SCSI standard\n");
9262 case RSO_ONE_SUP_VENDOR:
9263 printf("Command is supported, vendor-specific "
9264 "implementation\n");
9267 printf("Unknown command support flags 0x%#x\n",
9268 one->support & RSO_ONE_SUP_MASK);
9273 * If we don't have the CDB length, it isn't exactly an error, the
9274 * command probably isn't supported.
9276 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9280 cdb_len = scsi_2btoul(one->cdb_length);
9283 * If our valid data doesn't include the full reported length,
9284 * return. The caller should have detected this and adjusted his
9285 * allocation length to get all of the available data.
9287 if (valid_len < sizeof(*one) + cdb_len) {
9293 * If all we have is the opcode, there is no point in printing out
9301 printf("CDB usage bitmap:");
9302 for (i = 0; i < cdb_len; i++) {
9303 printf(" %02x", one->cdb_usage[i]);
9308 * If we don't have a timeout descriptor, we're done.
9310 if ((one->support & RSO_ONE_CTDP) == 0)
9314 * If we don't have enough valid length to include the timeout
9315 * descriptor length, we're done.
9317 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9320 td = (struct scsi_report_supported_opcodes_timeout *)
9321 &buf[sizeof(*one) + cdb_len];
9322 td_len = scsi_2btoul(td->length);
9323 td_len += sizeof(td->length);
9326 * If we don't have the full timeout descriptor, we're done.
9328 if (td_len < sizeof(*td))
9332 * If we don't have enough valid length to contain the full timeout
9333 * descriptor, we're done.
9335 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9338 printf("Timeout information:\n");
9339 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9340 printf("Nominal timeout: %u seconds\n",
9341 scsi_4btoul(td->nominal_time));
9342 printf("Recommended timeout: %u seconds\n",
9343 scsi_4btoul(td->recommended_time));
9350 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9353 struct scsi_report_supported_opcodes_all *hdr;
9354 struct scsi_report_supported_opcodes_descr *desc;
9355 uint32_t avail_len = 0, used_len = 0;
9359 if (valid_len < sizeof(*hdr)) {
9360 warnx("%s: not enough returned data (%u bytes) opcode list",
9361 __func__, valid_len);
9365 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9366 avail_len = scsi_4btoul(hdr->length);
9367 avail_len += sizeof(hdr->length);
9369 * Take the lesser of the amount of data the drive claims is
9370 * available, and the amount of data the HBA says was returned.
9372 avail_len = MIN(avail_len, valid_len);
9374 used_len = sizeof(hdr->length);
9376 printf("%-6s %4s %8s ",
9377 "Opcode", "SA", "CDB len" );
9380 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9381 printf(" Description\n");
9383 while ((avail_len - used_len) > sizeof(*desc)) {
9384 struct scsi_report_supported_opcodes_timeout *td;
9386 const char *op_desc = NULL;
9388 cur_ptr = &buf[used_len];
9389 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9391 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9392 if (op_desc == NULL)
9393 op_desc = "UNKNOWN";
9395 printf("0x%02x %#4x %8u ", desc->opcode,
9396 scsi_2btoul(desc->service_action),
9397 scsi_2btoul(desc->cdb_length));
9399 used_len += sizeof(*desc);
9401 if ((desc->flags & RSO_CTDP) == 0) {
9402 printf(" %s\n", op_desc);
9407 * If we don't have enough space to fit a timeout
9408 * descriptor, then we're done.
9410 if (avail_len - used_len < sizeof(*td)) {
9411 used_len = avail_len;
9412 printf(" %s\n", op_desc);
9415 cur_ptr = &buf[used_len];
9416 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9417 td_len = scsi_2btoul(td->length);
9418 td_len += sizeof(td->length);
9422 * If the given timeout descriptor length is less than what
9423 * we understand, skip it.
9425 if (td_len < sizeof(*td)) {
9426 printf(" %s\n", op_desc);
9430 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9431 scsi_4btoul(td->nominal_time),
9432 scsi_4btoul(td->recommended_time), op_desc);
9439 scsiopcodes(struct cam_device *device, int argc, char **argv,
9440 char *combinedopt, int task_attr, int retry_count, int timeout,
9444 uint32_t opcode = 0, service_action = 0;
9445 int td_set = 0, opcode_set = 0, sa_set = 0;
9446 int show_sa_errors = 1;
9447 uint32_t valid_len = 0;
9448 uint8_t *buf = NULL;
9452 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9458 opcode = strtoul(optarg, &endptr, 0);
9459 if (*endptr != '\0') {
9460 warnx("Invalid opcode \"%s\", must be a number",
9465 if (opcode > 0xff) {
9466 warnx("Invalid opcode 0x%#x, must be between"
9467 "0 and 0xff inclusive", opcode);
9474 service_action = strtoul(optarg, &endptr, 0);
9475 if (*endptr != '\0') {
9476 warnx("Invalid service action \"%s\", must "
9477 "be a number", optarg);
9481 if (service_action > 0xffff) {
9482 warnx("Invalid service action 0x%#x, must "
9483 "be between 0 and 0xffff inclusive",
9498 && (opcode_set == 0)) {
9499 warnx("You must specify an opcode with -o if a service "
9504 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9505 sa_set, service_action, td_set, task_attr,
9506 retry_count, timeout, verbosemode, &valid_len,
9511 if ((opcode_set != 0)
9513 retval = scsiprintoneopcode(device, opcode, sa_set,
9514 service_action, buf, valid_len);
9516 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9525 #endif /* MINIMALISTIC */
9528 scsireprobe(struct cam_device *device)
9533 ccb = cam_getccb(device);
9536 warnx("%s: error allocating ccb", __func__);
9540 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9542 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9544 if (cam_send_ccb(device, ccb) < 0) {
9545 warn("error sending XPT_REPROBE_LUN CCB");
9550 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9551 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9563 usage(int printlong)
9566 fprintf(printlong ? stdout : stderr,
9567 "usage: camcontrol <command> [device id][generic args][command args]\n"
9568 " camcontrol devlist [-b] [-v]\n"
9569 #ifndef MINIMALISTIC
9570 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9571 " camcontrol tur [dev_id][generic args]\n"
9572 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9573 " camcontrol identify [dev_id][generic args] [-v]\n"
9574 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9575 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9577 " camcontrol start [dev_id][generic args]\n"
9578 " camcontrol stop [dev_id][generic args]\n"
9579 " camcontrol load [dev_id][generic args]\n"
9580 " camcontrol eject [dev_id][generic args]\n"
9581 " camcontrol reprobe [dev_id][generic args]\n"
9582 #endif /* MINIMALISTIC */
9583 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9584 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9585 #ifndef MINIMALISTIC
9586 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9587 " [-q][-s][-S offset][-X]\n"
9588 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9589 " [-P pagectl][-e | -b][-d]\n"
9590 " camcontrol cmd [dev_id][generic args]\n"
9591 " <-a cmd [args] | -c cmd [args]>\n"
9592 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9593 " camcontrol smpcmd [dev_id][generic args]\n"
9594 " <-r len fmt [args]> <-R len fmt [args]>\n"
9595 " camcontrol smprg [dev_id][generic args][-l]\n"
9596 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9597 " [-o operation][-d name][-m rate][-M rate]\n"
9598 " [-T pp_timeout][-a enable|disable]\n"
9599 " [-A enable|disable][-s enable|disable]\n"
9600 " [-S enable|disable]\n"
9601 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9602 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9603 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9604 " <all|bus[:target[:lun]]|off>\n"
9605 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9606 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9607 " [-D <enable|disable>][-M mode][-O offset]\n"
9608 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9609 " [-U][-W bus_width]\n"
9610 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9611 " camcontrol sanitize [dev_id][generic args]\n"
9612 " [-a overwrite|block|crypto|exitfailure]\n"
9613 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9615 " camcontrol idle [dev_id][generic args][-t time]\n"
9616 " camcontrol standby [dev_id][generic args][-t time]\n"
9617 " camcontrol sleep [dev_id][generic args]\n"
9618 " camcontrol powermode [dev_id][generic args]\n"
9619 " camcontrol apm [dev_id][generic args][-l level]\n"
9620 " camcontrol aam [dev_id][generic args][-l level]\n"
9621 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9623 " camcontrol security [dev_id][generic args]\n"
9624 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9625 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9626 " [-U <user|master>] [-y]\n"
9627 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9628 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9629 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9630 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9631 " [-s scope][-S][-T type][-U]\n"
9632 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9633 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9634 " [-p part][-s start][-T type][-V vol]\n"
9635 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9637 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9638 " [-o rep_opts] [-P print_opts]\n"
9639 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9640 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9641 " [-S power_src] [-T timer]\n"
9642 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9643 " <-s <-f format -T time | -U >>\n"
9645 #endif /* MINIMALISTIC */
9646 " camcontrol help\n");
9649 #ifndef MINIMALISTIC
9651 "Specify one of the following options:\n"
9652 "devlist list all CAM devices\n"
9653 "periphlist list all CAM peripheral drivers attached to a device\n"
9654 "tur send a test unit ready to the named device\n"
9655 "inquiry send a SCSI inquiry command to the named device\n"
9656 "identify send a ATA identify command to the named device\n"
9657 "reportluns send a SCSI report luns command to the device\n"
9658 "readcap send a SCSI read capacity command to the device\n"
9659 "start send a Start Unit command to the device\n"
9660 "stop send a Stop Unit command to the device\n"
9661 "load send a Start Unit command to the device with the load bit set\n"
9662 "eject send a Stop Unit command to the device with the eject bit set\n"
9663 "reprobe update capacity information of the given device\n"
9664 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9665 "reset reset all buses, the given bus, bus:target:lun or device\n"
9666 "defects read the defect list of the specified device\n"
9667 "modepage display or edit (-e) the given mode page\n"
9668 "cmd send the given SCSI command, may need -i or -o as well\n"
9669 "smpcmd send the given SMP command, requires -o and -i\n"
9670 "smprg send the SMP Report General command\n"
9671 "smppc send the SMP PHY Control command, requires -p\n"
9672 "smpphylist display phys attached to a SAS expander\n"
9673 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9674 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9675 "tags report or set the number of transaction slots for a device\n"
9676 "negotiate report or set device negotiation parameters\n"
9677 "format send the SCSI FORMAT UNIT command to the named device\n"
9678 "sanitize send the SCSI SANITIZE command to the named device\n"
9679 "idle send the ATA IDLE command to the named device\n"
9680 "standby send the ATA STANDBY command to the named device\n"
9681 "sleep send the ATA SLEEP command to the named device\n"
9682 "powermode send the ATA CHECK POWER MODE command to the named device\n"
9683 "fwdownload program firmware of the named device with the given image\n"
9684 "security report or send ATA security commands to the named device\n"
9685 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9686 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9687 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9688 "zone manage Zoned Block (Shingled) devices\n"
9689 "epc send ATA Extended Power Conditions commands\n"
9690 "timestamp report or set the device's timestamp\n"
9691 "help this message\n"
9692 "Device Identifiers:\n"
9693 "bus:target specify the bus and target, lun defaults to 0\n"
9694 "bus:target:lun specify the bus, target and lun\n"
9695 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
9696 "Generic arguments:\n"
9697 "-v be verbose, print out sense information\n"
9698 "-t timeout command timeout in seconds, overrides default timeout\n"
9699 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
9700 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
9701 "-E have the kernel attempt to perform SCSI error recovery\n"
9702 "-C count specify the SCSI command retry count (needs -E to work)\n"
9703 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
9704 "modepage arguments:\n"
9705 "-l list all available mode pages\n"
9706 "-m page specify the mode page to view or edit\n"
9707 "-e edit the specified mode page\n"
9708 "-b force view to binary mode\n"
9709 "-d disable block descriptors for mode sense\n"
9710 "-P pgctl page control field 0-3\n"
9711 "defects arguments:\n"
9712 "-f format specify defect list format (block, bfi or phys)\n"
9713 "-G get the grown defect list\n"
9714 "-P get the permanent defect list\n"
9715 "inquiry arguments:\n"
9716 "-D get the standard inquiry data\n"
9717 "-S get the serial number\n"
9718 "-R get the transfer rate, etc.\n"
9719 "reportluns arguments:\n"
9720 "-c only report a count of available LUNs\n"
9721 "-l only print out luns, and not a count\n"
9722 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
9723 "readcap arguments\n"
9724 "-b only report the blocksize\n"
9725 "-h human readable device size, base 2\n"
9726 "-H human readable device size, base 10\n"
9727 "-N print the number of blocks instead of last block\n"
9728 "-q quiet, print numbers only\n"
9729 "-s only report the last block/device size\n"
9731 "-c cdb [args] specify the SCSI CDB\n"
9732 "-i len fmt specify input data and input data format\n"
9733 "-o len fmt [args] specify output data and output data fmt\n"
9734 "smpcmd arguments:\n"
9735 "-r len fmt [args] specify the SMP command to be sent\n"
9736 "-R len fmt [args] specify SMP response format\n"
9737 "smprg arguments:\n"
9738 "-l specify the long response format\n"
9739 "smppc arguments:\n"
9740 "-p phy specify the PHY to operate on\n"
9741 "-l specify the long request/response format\n"
9742 "-o operation specify the phy control operation\n"
9743 "-d name set the attached device name\n"
9744 "-m rate set the minimum physical link rate\n"
9745 "-M rate set the maximum physical link rate\n"
9746 "-T pp_timeout set the partial pathway timeout value\n"
9747 "-a enable|disable enable or disable SATA slumber\n"
9748 "-A enable|disable enable or disable SATA partial phy power\n"
9749 "-s enable|disable enable or disable SAS slumber\n"
9750 "-S enable|disable enable or disable SAS partial phy power\n"
9751 "smpphylist arguments:\n"
9752 "-l specify the long response format\n"
9753 "-q only print phys with attached devices\n"
9754 "smpmaninfo arguments:\n"
9755 "-l specify the long response format\n"
9756 "debug arguments:\n"
9757 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
9758 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
9759 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
9760 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
9762 "-N tags specify the number of tags to use for this device\n"
9763 "-q be quiet, don't report the number of tags\n"
9764 "-v report a number of tag-related parameters\n"
9765 "negotiate arguments:\n"
9766 "-a send a test unit ready after negotiation\n"
9767 "-c report/set current negotiation settings\n"
9768 "-D <arg> \"enable\" or \"disable\" disconnection\n"
9769 "-M mode set ATA mode\n"
9770 "-O offset set command delay offset\n"
9771 "-q be quiet, don't report anything\n"
9772 "-R syncrate synchronization rate in MHz\n"
9773 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
9774 "-U report/set user negotiation settings\n"
9775 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
9776 "-v also print a Path Inquiry CCB for the controller\n"
9777 "format arguments:\n"
9778 "-q be quiet, don't print status messages\n"
9779 "-r run in report only mode\n"
9780 "-w don't send immediate format command\n"
9781 "-y don't ask any questions\n"
9782 "sanitize arguments:\n"
9783 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
9784 "-c passes overwrite passes to perform (1 to 31)\n"
9785 "-I invert overwrite pattern after each pass\n"
9786 "-P pattern path to overwrite pattern file\n"
9787 "-q be quiet, don't print status messages\n"
9788 "-r run in report only mode\n"
9789 "-U run operation in unrestricted completion exit mode\n"
9790 "-w don't send immediate sanitize command\n"
9791 "-y don't ask any questions\n"
9792 "idle/standby arguments:\n"
9793 "-t <arg> number of seconds before respective state.\n"
9794 "fwdownload arguments:\n"
9795 "-f fw_image path to firmware image file\n"
9796 "-q don't print informational messages, only errors\n"
9797 "-s run in simulation mode\n"
9798 "-v print info for every firmware segment sent to device\n"
9799 "-y don't ask any questions\n"
9800 "security arguments:\n"
9801 "-d pwd disable security using the given password for the selected\n"
9803 "-e pwd erase the device using the given pwd for the selected user\n"
9804 "-f freeze the security configuration of the specified device\n"
9805 "-h pwd enhanced erase the device using the given pwd for the\n"
9807 "-k pwd unlock the device using the given pwd for the selected\n"
9809 "-l <high|maximum> specifies which security level to set: high or maximum\n"
9810 "-q be quiet, do not print any status messages\n"
9811 "-s pwd password the device (enable security) using the given\n"
9812 " pwd for the selected user\n"
9813 "-T timeout overrides the timeout (seconds) used for erase operation\n"
9814 "-U <user|master> specifies which user to set: user or master\n"
9815 "-y don't ask any questions\n"
9817 "-f freeze the HPA configuration of the device\n"
9818 "-l lock the HPA configuration of the device\n"
9819 "-P make the HPA max sectors persist\n"
9820 "-p pwd Set the HPA configuration password required for unlock\n"
9822 "-q be quiet, do not print any status messages\n"
9823 "-s sectors configures the maximum user accessible sectors of the\n"
9825 "-U pwd unlock the HPA configuration of the device\n"
9826 "-y don't ask any questions\n"
9827 "persist arguments:\n"
9828 "-i action specify read_keys, read_reservation, report_cap, or\n"
9829 " read_full_status\n"
9830 "-o action specify register, register_ignore, reserve, release,\n"
9831 " clear, preempt, preempt_abort, register_move, replace_lost\n"
9832 "-a set the All Target Ports (ALL_TG_PT) bit\n"
9833 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
9834 "-k key specify the Reservation Key\n"
9835 "-K sa_key specify the Service Action Reservation Key\n"
9836 "-p set the Activate Persist Through Power Loss bit\n"
9837 "-R rtp specify the Relative Target Port\n"
9838 "-s scope specify the scope: lun, extent, element or a number\n"
9839 "-S specify Transport ID for register, requires -I\n"
9840 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
9841 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
9842 "-U unregister the current initiator for register_move\n"
9843 "attrib arguments:\n"
9844 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
9846 "-w attr specify an attribute to write, one -w argument per attr\n"
9847 "-a attr_num only display this attribute number\n"
9848 "-c get cached attributes\n"
9849 "-e elem_addr request attributes for the given element in a changer\n"
9850 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
9851 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
9852 " field_none, field_desc, field_num, field_size, field_rw\n"
9853 "-p partition request attributes for the given partition\n"
9854 "-s start_attr request attributes starting at the given number\n"
9855 "-T elem_type specify the element type (used with -e)\n"
9856 "-V logical_vol specify the logical volume ID\n"
9857 "opcodes arguments:\n"
9858 "-o opcode specify the individual opcode to list\n"
9859 "-s service_action specify the service action for the opcode\n"
9860 "-N do not return SCSI error for unsupported SA\n"
9861 "-T request nominal and recommended timeout values\n"
9863 "-c cmd required: rz, open, close, finish, or rwp\n"
9864 "-a apply the action to all zones\n"
9865 "-l LBA specify the zone starting LBA\n"
9866 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
9867 " closed, full, ro, offline, reset, nonseq, nonwp\n"
9868 "-P print_opt report zones printing: normal, summary, script\n"
9870 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
9871 " source, status, list\n"
9872 "-d disable power mode (timer, state)\n"
9873 "-D delayed entry (goto)\n"
9874 "-e enable power mode (timer, state)\n"
9875 "-H hold power mode (goto)\n"
9876 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
9878 "-P only display power mode (status)\n"
9879 "-r rst_src restore settings from: default, saved (restore)\n"
9880 "-s save mode (timer, state, restore)\n"
9881 "-S power_src set power source: battery, nonbattery (source)\n"
9882 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
9883 "timestamp arguments:\n"
9884 "-r report the timestamp of the device\n"
9885 "-f format report the timestamp of the device with the given\n"
9886 " strftime(3) format string\n"
9887 "-m report the timestamp of the device as milliseconds since\n"
9888 " January 1st, 1970\n"
9889 "-U report the time with UTC instead of the local time zone\n"
9890 "-s set the timestamp of the device\n"
9891 "-f format the format of the time string passed into strptime(3)\n"
9892 "-T time the time value passed into strptime(3)\n"
9893 "-U set the timestamp of the device to UTC time\n"
9895 #endif /* MINIMALISTIC */
9899 main(int argc, char **argv)
9902 char *device = NULL;
9904 struct cam_device *cam_dev = NULL;
9905 int timeout = 0, retry_count = 1;
9906 camcontrol_optret optreturn;
9908 const char *mainopt = "C:En:Q:t:u:v";
9909 const char *subopt = NULL;
9910 char combinedopt[256];
9911 int error = 0, optstart = 2;
9912 int task_attr = MSG_SIMPLE_Q_TAG;
9914 #ifndef MINIMALISTIC
9918 #endif /* MINIMALISTIC */
9920 cmdlist = CAM_CMD_NONE;
9921 arglist = CAM_ARG_NONE;
9929 * Get the base option.
9931 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
9933 if (optreturn == CC_OR_AMBIGUOUS) {
9934 warnx("ambiguous option %s", argv[1]);
9937 } else if (optreturn == CC_OR_NOT_FOUND) {
9938 warnx("option %s not found", argv[1]);
9944 * Ahh, getopt(3) is a pain.
9946 * This is a gross hack. There really aren't many other good
9947 * options (excuse the pun) for parsing options in a situation like
9948 * this. getopt is kinda braindead, so you end up having to run
9949 * through the options twice, and give each invocation of getopt
9950 * the option string for the other invocation.
9952 * You would think that you could just have two groups of options.
9953 * The first group would get parsed by the first invocation of
9954 * getopt, and the second group would get parsed by the second
9955 * invocation of getopt. It doesn't quite work out that way. When
9956 * the first invocation of getopt finishes, it leaves optind pointing
9957 * to the argument _after_ the first argument in the second group.
9958 * So when the second invocation of getopt comes around, it doesn't
9959 * recognize the first argument it gets and then bails out.
9961 * A nice alternative would be to have a flag for getopt that says
9962 * "just keep parsing arguments even when you encounter an unknown
9963 * argument", but there isn't one. So there's no real clean way to
9964 * easily parse two sets of arguments without having one invocation
9965 * of getopt know about the other.
9967 * Without this hack, the first invocation of getopt would work as
9968 * long as the generic arguments are first, but the second invocation
9969 * (in the subfunction) would fail in one of two ways. In the case
9970 * where you don't set optreset, it would fail because optind may be
9971 * pointing to the argument after the one it should be pointing at.
9972 * In the case where you do set optreset, and reset optind, it would
9973 * fail because getopt would run into the first set of options, which
9974 * it doesn't understand.
9976 * All of this would "sort of" work if you could somehow figure out
9977 * whether optind had been incremented one option too far. The
9978 * mechanics of that, however, are more daunting than just giving
9979 * both invocations all of the expect options for either invocation.
9981 * Needless to say, I wouldn't mind if someone invented a better
9982 * (non-GPL!) command line parsing interface than getopt. I
9983 * wouldn't mind if someone added more knobs to getopt to make it
9984 * work better. Who knows, I may talk myself into doing it someday,
9985 * if the standards weenies let me. As it is, it just leads to
9986 * hackery like this and causes people to avoid it in some cases.
9988 * KDM, September 8th, 1998
9991 sprintf(combinedopt, "%s%s", mainopt, subopt);
9993 sprintf(combinedopt, "%s", mainopt);
9996 * For these options we do not parse optional device arguments and
9997 * we do not open a passthrough device.
9999 if ((cmdlist == CAM_CMD_RESCAN)
10000 || (cmdlist == CAM_CMD_RESET)
10001 || (cmdlist == CAM_CMD_DEVTREE)
10002 || (cmdlist == CAM_CMD_USAGE)
10003 || (cmdlist == CAM_CMD_DEBUG))
10006 #ifndef MINIMALISTIC
10008 && (argc > 2 && argv[2][0] != '-')) {
10012 if (isdigit(argv[2][0])) {
10013 /* device specified as bus:target[:lun] */
10014 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10016 errx(1, "numeric device specification must "
10017 "be either bus:target, or "
10019 /* default to 0 if lun was not specified */
10020 if ((arglist & CAM_ARG_LUN) == 0) {
10022 arglist |= CAM_ARG_LUN;
10026 if (cam_get_device(argv[2], name, sizeof name, &unit)
10028 errx(1, "%s", cam_errbuf);
10029 device = strdup(name);
10030 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10034 #endif /* MINIMALISTIC */
10036 * Start getopt processing at argv[2/3], since we've already
10037 * accepted argv[1..2] as the command name, and as a possible
10043 * Now we run through the argument list looking for generic
10044 * options, and ignoring options that possibly belong to
10047 while ((c = getopt(argc, argv, combinedopt))!= -1){
10050 retry_count = strtol(optarg, NULL, 0);
10051 if (retry_count < 0)
10052 errx(1, "retry count %d is < 0",
10054 arglist |= CAM_ARG_RETRIES;
10057 arglist |= CAM_ARG_ERR_RECOVER;
10060 arglist |= CAM_ARG_DEVICE;
10062 while (isspace(*tstr) && (*tstr != '\0'))
10064 device = (char *)strdup(tstr);
10068 int table_entry = 0;
10071 while (isspace(*tstr) && (*tstr != '\0'))
10073 if (isdigit(*tstr)) {
10074 task_attr = strtol(tstr, &endptr, 0);
10075 if (*endptr != '\0') {
10076 errx(1, "Invalid queue option "
10081 scsi_nv_status status;
10083 table_size = sizeof(task_attrs) /
10084 sizeof(task_attrs[0]);
10085 status = scsi_get_nv(task_attrs,
10086 table_size, tstr, &table_entry,
10087 SCSI_NV_FLAG_IG_CASE);
10088 if (status == SCSI_NV_FOUND)
10089 task_attr = task_attrs[
10090 table_entry].value;
10092 errx(1, "%s option %s",
10093 (status == SCSI_NV_AMBIGUOUS)?
10094 "ambiguous" : "invalid",
10101 timeout = strtol(optarg, NULL, 0);
10103 errx(1, "invalid timeout %d", timeout);
10104 /* Convert the timeout from seconds to ms */
10106 arglist |= CAM_ARG_TIMEOUT;
10109 arglist |= CAM_ARG_UNIT;
10110 unit = strtol(optarg, NULL, 0);
10113 arglist |= CAM_ARG_VERBOSE;
10120 #ifndef MINIMALISTIC
10122 * For most commands we'll want to open the passthrough device
10123 * associated with the specified device. In the case of the rescan
10124 * commands, we don't use a passthrough device at all, just the
10125 * transport layer device.
10127 if (devopen == 1) {
10128 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10129 && (((arglist & CAM_ARG_DEVICE) == 0)
10130 || ((arglist & CAM_ARG_UNIT) == 0))) {
10131 errx(1, "subcommand \"%s\" requires a valid device "
10132 "identifier", argv[1]);
10135 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10136 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10137 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10139 errx(1,"%s", cam_errbuf);
10141 #endif /* MINIMALISTIC */
10144 * Reset optind to 2, and reset getopt, so these routines can parse
10145 * the arguments again.
10151 #ifndef MINIMALISTIC
10152 case CAM_CMD_DEVLIST:
10153 error = getdevlist(cam_dev);
10156 error = atahpa(cam_dev, retry_count, timeout,
10157 argc, argv, combinedopt);
10159 #endif /* MINIMALISTIC */
10160 case CAM_CMD_DEVTREE:
10161 error = getdevtree(argc, argv, combinedopt);
10163 #ifndef MINIMALISTIC
10165 error = testunitready(cam_dev, task_attr, retry_count,
10168 case CAM_CMD_INQUIRY:
10169 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10170 task_attr, retry_count, timeout);
10172 case CAM_CMD_IDENTIFY:
10173 error = identify(cam_dev, retry_count, timeout);
10175 case CAM_CMD_STARTSTOP:
10176 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10177 arglist & CAM_ARG_EJECT, task_attr,
10178 retry_count, timeout);
10180 #endif /* MINIMALISTIC */
10181 case CAM_CMD_RESCAN:
10182 error = dorescan_or_reset(argc, argv, 1);
10184 case CAM_CMD_RESET:
10185 error = dorescan_or_reset(argc, argv, 0);
10187 #ifndef MINIMALISTIC
10188 case CAM_CMD_READ_DEFECTS:
10189 error = readdefects(cam_dev, argc, argv, combinedopt,
10190 task_attr, retry_count, timeout);
10192 case CAM_CMD_MODE_PAGE:
10193 modepage(cam_dev, argc, argv, combinedopt,
10194 task_attr, retry_count, timeout);
10196 case CAM_CMD_SCSI_CMD:
10197 error = scsicmd(cam_dev, argc, argv, combinedopt,
10198 task_attr, retry_count, timeout);
10200 case CAM_CMD_MMCSD_CMD:
10201 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10202 retry_count, timeout);
10204 case CAM_CMD_SMP_CMD:
10205 error = smpcmd(cam_dev, argc, argv, combinedopt,
10206 retry_count, timeout);
10208 case CAM_CMD_SMP_RG:
10209 error = smpreportgeneral(cam_dev, argc, argv,
10210 combinedopt, retry_count,
10213 case CAM_CMD_SMP_PC:
10214 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10215 retry_count, timeout);
10217 case CAM_CMD_SMP_PHYLIST:
10218 error = smpphylist(cam_dev, argc, argv, combinedopt,
10219 retry_count, timeout);
10221 case CAM_CMD_SMP_MANINFO:
10222 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10223 retry_count, timeout);
10225 case CAM_CMD_DEBUG:
10226 error = camdebug(argc, argv, combinedopt);
10229 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10232 error = ratecontrol(cam_dev, task_attr, retry_count,
10233 timeout, argc, argv, combinedopt);
10235 case CAM_CMD_FORMAT:
10236 error = scsiformat(cam_dev, argc, argv,
10237 combinedopt, task_attr, retry_count,
10240 case CAM_CMD_REPORTLUNS:
10241 error = scsireportluns(cam_dev, argc, argv,
10242 combinedopt, task_attr,
10243 retry_count, timeout);
10245 case CAM_CMD_READCAP:
10246 error = scsireadcapacity(cam_dev, argc, argv,
10247 combinedopt, task_attr,
10248 retry_count, timeout);
10251 case CAM_CMD_STANDBY:
10252 case CAM_CMD_SLEEP:
10253 case CAM_CMD_POWER_MODE:
10254 error = atapm(cam_dev, argc, argv,
10255 combinedopt, retry_count, timeout);
10259 error = ataaxm(cam_dev, argc, argv,
10260 combinedopt, retry_count, timeout);
10262 case CAM_CMD_SECURITY:
10263 error = atasecurity(cam_dev, retry_count, timeout,
10264 argc, argv, combinedopt);
10266 case CAM_CMD_DOWNLOAD_FW:
10267 error = fwdownload(cam_dev, argc, argv, combinedopt,
10268 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10271 case CAM_CMD_SANITIZE:
10272 error = scsisanitize(cam_dev, argc, argv,
10273 combinedopt, task_attr,
10274 retry_count, timeout);
10276 case CAM_CMD_PERSIST:
10277 error = scsipersist(cam_dev, argc, argv, combinedopt,
10278 task_attr, retry_count, timeout,
10279 arglist & CAM_ARG_VERBOSE,
10280 arglist & CAM_ARG_ERR_RECOVER);
10282 case CAM_CMD_ATTRIB:
10283 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10284 task_attr, retry_count, timeout,
10285 arglist & CAM_ARG_VERBOSE,
10286 arglist & CAM_ARG_ERR_RECOVER);
10288 case CAM_CMD_OPCODES:
10289 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10290 task_attr, retry_count, timeout,
10291 arglist & CAM_ARG_VERBOSE);
10293 case CAM_CMD_REPROBE:
10294 error = scsireprobe(cam_dev);
10297 error = zone(cam_dev, argc, argv, combinedopt,
10298 task_attr, retry_count, timeout,
10299 arglist & CAM_ARG_VERBOSE);
10302 error = epc(cam_dev, argc, argv, combinedopt,
10303 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10305 case CAM_CMD_TIMESTAMP:
10306 error = timestamp(cam_dev, argc, argv, combinedopt,
10307 task_attr, retry_count, timeout,
10308 arglist & CAM_ARG_VERBOSE);
10310 #endif /* MINIMALISTIC */
10311 case CAM_CMD_USAGE:
10320 if (cam_dev != NULL)
10321 cam_close_device(cam_dev);