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>
53 #include <cam/cam_debug.h>
54 #include <cam/cam_ccb.h>
55 #include <cam/scsi/scsi_all.h>
56 #include <cam/scsi/scsi_da.h>
57 #include <cam/scsi/scsi_pass.h>
58 #include <cam/scsi/scsi_message.h>
59 #include <cam/scsi/smp_all.h>
60 #include <cam/ata/ata_all.h>
61 #include <cam/mmc/mmc_all.h>
63 #include "camcontrol.h"
65 #include "nvmecontrol_ext.h"
69 CAM_CMD_NONE = 0x00000000,
70 CAM_CMD_DEVLIST = 0x00000001,
71 CAM_CMD_TUR = 0x00000002,
72 CAM_CMD_INQUIRY = 0x00000003,
73 CAM_CMD_STARTSTOP = 0x00000004,
74 CAM_CMD_RESCAN = 0x00000005,
75 CAM_CMD_READ_DEFECTS = 0x00000006,
76 CAM_CMD_MODE_PAGE = 0x00000007,
77 CAM_CMD_SCSI_CMD = 0x00000008,
78 CAM_CMD_DEVTREE = 0x00000009,
79 CAM_CMD_USAGE = 0x0000000a,
80 CAM_CMD_DEBUG = 0x0000000b,
81 CAM_CMD_RESET = 0x0000000c,
82 CAM_CMD_FORMAT = 0x0000000d,
83 CAM_CMD_TAG = 0x0000000e,
84 CAM_CMD_RATE = 0x0000000f,
85 CAM_CMD_DETACH = 0x00000010,
86 CAM_CMD_REPORTLUNS = 0x00000011,
87 CAM_CMD_READCAP = 0x00000012,
88 CAM_CMD_IDENTIFY = 0x00000013,
89 CAM_CMD_IDLE = 0x00000014,
90 CAM_CMD_STANDBY = 0x00000015,
91 CAM_CMD_SLEEP = 0x00000016,
92 CAM_CMD_SMP_CMD = 0x00000017,
93 CAM_CMD_SMP_RG = 0x00000018,
94 CAM_CMD_SMP_PC = 0x00000019,
95 CAM_CMD_SMP_PHYLIST = 0x0000001a,
96 CAM_CMD_SMP_MANINFO = 0x0000001b,
97 CAM_CMD_DOWNLOAD_FW = 0x0000001c,
98 CAM_CMD_SECURITY = 0x0000001d,
99 CAM_CMD_HPA = 0x0000001e,
100 CAM_CMD_SANITIZE = 0x0000001f,
101 CAM_CMD_PERSIST = 0x00000020,
102 CAM_CMD_APM = 0x00000021,
103 CAM_CMD_AAM = 0x00000022,
104 CAM_CMD_ATTRIB = 0x00000023,
105 CAM_CMD_OPCODES = 0x00000024,
106 CAM_CMD_REPROBE = 0x00000025,
107 CAM_CMD_ZONE = 0x00000026,
108 CAM_CMD_EPC = 0x00000027,
109 CAM_CMD_TIMESTAMP = 0x00000028,
110 CAM_CMD_MMCSD_CMD = 0x00000029,
111 CAM_CMD_POWER_MODE = 0x0000002a,
115 CAM_ARG_NONE = 0x00000000,
116 CAM_ARG_VERBOSE = 0x00000001,
117 CAM_ARG_DEVICE = 0x00000002,
118 CAM_ARG_BUS = 0x00000004,
119 CAM_ARG_TARGET = 0x00000008,
120 CAM_ARG_LUN = 0x00000010,
121 CAM_ARG_EJECT = 0x00000020,
122 CAM_ARG_UNIT = 0x00000040,
123 CAM_ARG_FORMAT_BLOCK = 0x00000080,
124 CAM_ARG_FORMAT_BFI = 0x00000100,
125 CAM_ARG_FORMAT_PHYS = 0x00000200,
126 CAM_ARG_PLIST = 0x00000400,
127 CAM_ARG_GLIST = 0x00000800,
128 CAM_ARG_GET_SERIAL = 0x00001000,
129 CAM_ARG_GET_STDINQ = 0x00002000,
130 CAM_ARG_GET_XFERRATE = 0x00004000,
131 CAM_ARG_INQ_MASK = 0x00007000,
132 CAM_ARG_TIMEOUT = 0x00020000,
133 CAM_ARG_CMD_IN = 0x00040000,
134 CAM_ARG_CMD_OUT = 0x00080000,
135 CAM_ARG_ERR_RECOVER = 0x00200000,
136 CAM_ARG_RETRIES = 0x00400000,
137 CAM_ARG_START_UNIT = 0x00800000,
138 CAM_ARG_DEBUG_INFO = 0x01000000,
139 CAM_ARG_DEBUG_TRACE = 0x02000000,
140 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
141 CAM_ARG_DEBUG_CDB = 0x08000000,
142 CAM_ARG_DEBUG_XPT = 0x10000000,
143 CAM_ARG_DEBUG_PERIPH = 0x20000000,
144 CAM_ARG_DEBUG_PROBE = 0x40000000,
147 struct camcontrol_opts {
154 struct ata_res_pass16 {
155 u_int16_t reserved[5];
158 u_int8_t sector_count_exp;
159 u_int8_t sector_count;
160 u_int8_t lba_low_exp;
162 u_int8_t lba_mid_exp;
164 u_int8_t lba_high_exp;
170 struct ata_set_max_pwd
173 u_int8_t password[32];
174 u_int16_t reserved2[239];
177 static struct scsi_nv task_attrs[] = {
178 { "simple", MSG_SIMPLE_Q_TAG },
179 { "head", MSG_HEAD_OF_Q_TAG },
180 { "ordered", MSG_ORDERED_Q_TAG },
181 { "iwr", MSG_IGN_WIDE_RESIDUE },
182 { "aca", MSG_ACA_TASK }
185 static const char scsicmd_opts[] = "a:c:dfi:o:r";
186 static const char readdefect_opts[] = "f:GPqsS:X";
187 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
188 static const char smprg_opts[] = "l";
189 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
190 static const char smpphylist_opts[] = "lq";
193 static struct camcontrol_opts option_table[] = {
194 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
195 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
196 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
197 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
198 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
199 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
200 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
201 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
202 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHlNqs"},
203 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
204 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
205 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
206 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
207 {"mmcsdcmd", CAM_CMD_MMCSD_CMD, CAM_ARG_NONE, "c:a:f:Wb:l:41S:I"},
208 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
209 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
210 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
211 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
212 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
213 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
214 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
215 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
216 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
217 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
218 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
219 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
220 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
221 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
222 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
223 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
224 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
225 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
226 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
227 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
228 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
229 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
230 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
231 {"powermode", CAM_CMD_POWER_MODE, CAM_ARG_NONE, ""},
232 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
233 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
234 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
235 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
236 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
237 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
238 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
239 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
240 {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
241 {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
242 {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
243 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
244 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
245 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
250 struct device_match_result dev_match;
252 struct periph_match_result *periph_matches;
253 struct scsi_vpd_device_id *device_id;
255 STAILQ_ENTRY(cam_devitem) links;
259 STAILQ_HEAD(, cam_devitem) dev_queue;
263 static cam_cmdmask cmdlist;
264 static cam_argmask arglist;
266 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
267 uint32_t *cmdnum, cam_argmask *argnum,
268 const char **subopt);
269 static int getdevlist(struct cam_device *device);
270 static int getdevtree(int argc, char **argv, char *combinedopt);
271 static int print_dev_scsi(struct device_match_result *dev_result, char *tmpstr);
272 static int print_dev_ata(struct device_match_result *dev_result, char *tmpstr);
273 static int print_dev_semb(struct device_match_result *dev_result, char *tmpstr);
274 static int print_dev_mmcsd(struct device_match_result *dev_result,
277 static int print_dev_nvme(struct device_match_result *dev_result, char *tmpstr);
279 static int testunitready(struct cam_device *device, int task_attr,
280 int retry_count, int timeout, int quiet);
281 static int scsistart(struct cam_device *device, int startstop, int loadeject,
282 int task_attr, int retry_count, int timeout);
283 static int scsiinquiry(struct cam_device *device, int task_attr,
284 int retry_count, int timeout);
285 static int scsiserial(struct cam_device *device, int task_attr,
286 int retry_count, int timeout);
287 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
288 lun_id_t *lun, cam_argmask *arglst);
289 static int dorescan_or_reset(int argc, char **argv, int rescan);
290 static int rescan_or_reset_bus(path_id_t bus, int rescan);
291 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
292 lun_id_t lun, int scan);
293 static int readdefects(struct cam_device *device, int argc, char **argv,
294 char *combinedopt, int task_attr, int retry_count,
296 static void modepage(struct cam_device *device, int argc, char **argv,
297 char *combinedopt, int task_attr, int retry_count,
299 static int scsicmd(struct cam_device *device, int argc, char **argv,
300 char *combinedopt, int task_attr, int retry_count,
302 static int smpcmd(struct cam_device *device, int argc, char **argv,
303 char *combinedopt, int retry_count, int timeout);
304 static int mmcsdcmd(struct cam_device *device, int argc, char **argv,
305 char *combinedopt, int retry_count, int timeout);
306 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
307 char *combinedopt, int retry_count, int timeout);
308 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
309 char *combinedopt, int retry_count, int timeout);
310 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
311 char *combinedopt, int retry_count, int timeout);
312 static int getdevid(struct cam_devitem *item);
313 static int buildbusdevlist(struct cam_devlist *devlist);
314 static void freebusdevlist(struct cam_devlist *devlist);
315 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
317 static int smpphylist(struct cam_device *device, int argc, char **argv,
318 char *combinedopt, int retry_count, int timeout);
319 static int tagcontrol(struct cam_device *device, int argc, char **argv,
321 static void cts_print(struct cam_device *device,
322 struct ccb_trans_settings *cts);
323 static void cpi_print(struct ccb_pathinq *cpi);
324 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
325 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
326 static int get_print_cts(struct cam_device *device, int user_settings,
327 int quiet, struct ccb_trans_settings *cts);
328 static int ratecontrol(struct cam_device *device, int task_attr,
329 int retry_count, int timeout, int argc, char **argv,
331 static int scsiformat(struct cam_device *device, int argc, char **argv,
332 char *combinedopt, int task_attr, int retry_count,
334 static int scsisanitize(struct cam_device *device, int argc, char **argv,
335 char *combinedopt, int task_attr, int retry_count,
337 static int scsireportluns(struct cam_device *device, int argc, char **argv,
338 char *combinedopt, int task_attr, int retry_count,
340 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
341 char *combinedopt, int task_attr, int retry_count,
343 static int atapm(struct cam_device *device, int argc, char **argv,
344 char *combinedopt, int retry_count, int timeout);
345 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
346 int argc, char **argv, char *combinedopt);
347 static int atahpa(struct cam_device *device, int retry_count, int timeout,
348 int argc, char **argv, char *combinedopt);
349 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
350 int sa_set, int req_sa, uint8_t *buf,
352 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
354 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
355 char *combinedopt, int task_attr, int retry_count,
356 int timeout, int verbose);
357 static int scsireprobe(struct cam_device *device);
360 #define min(a,b) (((a)<(b))?(a):(b))
363 #define max(a,b) (((a)>(b))?(a):(b))
367 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
368 cam_argmask *argnum, const char **subopt)
370 struct camcontrol_opts *opts;
373 for (opts = table; (opts != NULL) && (opts->optname != NULL);
375 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
376 *cmdnum = opts->cmdnum;
377 *argnum = opts->argnum;
378 *subopt = opts->subopt;
379 if (++num_matches > 1)
380 return (CC_OR_AMBIGUOUS);
385 return (CC_OR_FOUND);
387 return (CC_OR_NOT_FOUND);
391 getdevlist(struct cam_device *device)
397 ccb = cam_getccb(device);
399 ccb->ccb_h.func_code = XPT_GDEVLIST;
400 ccb->ccb_h.flags = CAM_DIR_NONE;
401 ccb->ccb_h.retry_count = 1;
403 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
404 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
405 if (cam_send_ccb(device, ccb) < 0) {
406 perror("error getting device list");
413 switch (ccb->cgdl.status) {
414 case CAM_GDEVLIST_MORE_DEVS:
415 strcpy(status, "MORE");
417 case CAM_GDEVLIST_LAST_DEVICE:
418 strcpy(status, "LAST");
420 case CAM_GDEVLIST_LIST_CHANGED:
421 strcpy(status, "CHANGED");
423 case CAM_GDEVLIST_ERROR:
424 strcpy(status, "ERROR");
429 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
430 ccb->cgdl.periph_name,
431 ccb->cgdl.unit_number,
432 ccb->cgdl.generation,
437 * If the list has changed, we need to start over from the
440 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
450 getdevtree(int argc, char **argv, char *combinedopt)
461 while ((c = getopt(argc, argv, combinedopt)) != -1) {
464 if ((arglist & CAM_ARG_VERBOSE) == 0)
472 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
473 warn("couldn't open %s", XPT_DEVICE);
477 bzero(&ccb, sizeof(union ccb));
479 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
480 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
481 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
483 ccb.ccb_h.func_code = XPT_DEV_MATCH;
484 bufsize = sizeof(struct dev_match_result) * 100;
485 ccb.cdm.match_buf_len = bufsize;
486 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
487 if (ccb.cdm.matches == NULL) {
488 warnx("can't malloc memory for matches");
492 ccb.cdm.num_matches = 0;
495 * We fetch all nodes, since we display most of them in the default
496 * case, and all in the verbose case.
498 ccb.cdm.num_patterns = 0;
499 ccb.cdm.pattern_buf_len = 0;
502 * We do the ioctl multiple times if necessary, in case there are
503 * more than 100 nodes in the EDT.
506 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
507 warn("error sending CAMIOCOMMAND ioctl");
512 if ((ccb.ccb_h.status != CAM_REQ_CMP)
513 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
514 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
515 warnx("got CAM error %#x, CDM error %d\n",
516 ccb.ccb_h.status, ccb.cdm.status);
521 for (i = 0; i < ccb.cdm.num_matches; i++) {
522 switch (ccb.cdm.matches[i].type) {
523 case DEV_MATCH_BUS: {
524 struct bus_match_result *bus_result;
527 * Only print the bus information if the
528 * user turns on the verbose flag.
530 if ((busonly == 0) &&
531 (arglist & CAM_ARG_VERBOSE) == 0)
535 &ccb.cdm.matches[i].result.bus_result;
538 fprintf(stdout, ")\n");
542 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
544 bus_result->dev_name,
545 bus_result->unit_number,
547 (busonly ? "" : ":"));
550 case DEV_MATCH_DEVICE: {
551 struct device_match_result *dev_result;
558 &ccb.cdm.matches[i].result.device_result;
560 if ((dev_result->flags
561 & DEV_RESULT_UNCONFIGURED)
562 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
568 if (dev_result->protocol == PROTO_SCSI) {
569 if (print_dev_scsi(dev_result,
574 } else if (dev_result->protocol == PROTO_ATA ||
575 dev_result->protocol == PROTO_SATAPM) {
576 if (print_dev_ata(dev_result,
581 } else if (dev_result->protocol == PROTO_MMCSD){
582 if (print_dev_mmcsd(dev_result,
587 } else if (dev_result->protocol == PROTO_SEMB) {
588 if (print_dev_semb(dev_result,
594 } else if (dev_result->protocol == PROTO_NVME) {
595 if (print_dev_nvme(dev_result,
602 sprintf(tmpstr, "<>");
605 fprintf(stdout, ")\n");
609 fprintf(stdout, "%-33s at scbus%d "
610 "target %d lun %jx (",
613 dev_result->target_id,
614 (uintmax_t)dev_result->target_lun);
620 case DEV_MATCH_PERIPH: {
621 struct periph_match_result *periph_result;
624 &ccb.cdm.matches[i].result.periph_result;
626 if (busonly || skip_device != 0)
630 fprintf(stdout, ",");
632 fprintf(stdout, "%s%d",
633 periph_result->periph_name,
634 periph_result->unit_number);
640 fprintf(stdout, "unknown match type\n");
645 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
646 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
649 fprintf(stdout, ")\n");
657 print_dev_scsi(struct device_match_result *dev_result, char *tmpstr)
659 char vendor[16], product[48], revision[16];
661 cam_strvis(vendor, dev_result->inq_data.vendor,
662 sizeof(dev_result->inq_data.vendor), sizeof(vendor));
663 cam_strvis(product, dev_result->inq_data.product,
664 sizeof(dev_result->inq_data.product), sizeof(product));
665 cam_strvis(revision, dev_result->inq_data.revision,
666 sizeof(dev_result->inq_data.revision), sizeof(revision));
667 sprintf(tmpstr, "<%s %s %s>", vendor, product, revision);
673 print_dev_ata(struct device_match_result *dev_result, char *tmpstr)
675 char product[48], revision[16];
677 cam_strvis(product, dev_result->ident_data.model,
678 sizeof(dev_result->ident_data.model), sizeof(product));
679 cam_strvis(revision, dev_result->ident_data.revision,
680 sizeof(dev_result->ident_data.revision), sizeof(revision));
681 sprintf(tmpstr, "<%s %s>", product, revision);
687 print_dev_semb(struct device_match_result *dev_result, char *tmpstr)
689 struct sep_identify_data *sid;
690 char vendor[16], product[48], revision[16], fw[5];
692 sid = (struct sep_identify_data *)&dev_result->ident_data;
693 cam_strvis(vendor, sid->vendor_id,
694 sizeof(sid->vendor_id), sizeof(vendor));
695 cam_strvis(product, sid->product_id,
696 sizeof(sid->product_id), sizeof(product));
697 cam_strvis(revision, sid->product_rev,
698 sizeof(sid->product_rev), sizeof(revision));
699 cam_strvis(fw, sid->firmware_rev,
700 sizeof(sid->firmware_rev), sizeof(fw));
701 sprintf(tmpstr, "<%s %s %s %s>", vendor, product, revision, fw);
707 print_dev_mmcsd(struct device_match_result *dev_result, char *tmpstr)
710 struct ccb_dev_advinfo *advi;
711 struct cam_device *dev;
712 struct mmc_params mmc_ident_data;
714 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
715 dev_result->target_lun, O_RDWR, NULL);
717 warnx("%s", cam_errbuf);
721 ccb = cam_getccb(dev);
723 warnx("couldn't allocate CCB");
724 cam_close_device(dev);
729 advi->ccb_h.flags = CAM_DIR_IN;
730 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
731 advi->flags = CDAI_FLAG_NONE;
732 advi->buftype = CDAI_TYPE_MMC_PARAMS;
733 advi->bufsiz = sizeof(struct mmc_params);
734 advi->buf = (uint8_t *)&mmc_ident_data;
736 if (cam_send_ccb(dev, ccb) < 0) {
737 warn("error sending CAMIOCOMMAND ioctl");
739 cam_close_device(dev);
743 if (strlen(mmc_ident_data.model) > 0) {
744 sprintf(tmpstr, "<%s>", mmc_ident_data.model);
746 sprintf(tmpstr, "<%s card>",
747 mmc_ident_data.card_features &
748 CARD_FEATURE_SDIO ? "SDIO" : "unknown");
752 cam_close_device(dev);
758 nvme_get_cdata(struct cam_device *dev, struct nvme_controller_data *cdata)
761 struct ccb_dev_advinfo *advi;
763 ccb = cam_getccb(dev);
765 warnx("couldn't allocate CCB");
766 cam_close_device(dev);
771 advi->ccb_h.flags = CAM_DIR_IN;
772 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
773 advi->flags = CDAI_FLAG_NONE;
774 advi->buftype = CDAI_TYPE_NVME_CNTRL;
775 advi->bufsiz = sizeof(struct nvme_controller_data);
776 advi->buf = (uint8_t *)cdata;
778 if (cam_send_ccb(dev, ccb) < 0) {
779 warn("error sending CAMIOCOMMAND ioctl");
781 cam_close_device(dev);
784 if (advi->ccb_h.status != CAM_REQ_CMP) {
785 warnx("got CAM error %#x", advi->ccb_h.status);
787 cam_close_device(dev);
795 print_dev_nvme(struct device_match_result *dev_result, char *tmpstr)
797 struct cam_device *dev;
798 struct nvme_controller_data cdata;
799 char vendor[64], product[64];
801 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
802 dev_result->target_lun, O_RDWR, NULL);
804 warnx("%s", cam_errbuf);
808 if (nvme_get_cdata(dev, &cdata))
811 cam_strvis(vendor, cdata.mn, sizeof(cdata.mn), sizeof(vendor));
812 cam_strvis(product, cdata.fr, sizeof(cdata.fr), sizeof(product));
813 sprintf(tmpstr, "<%s %s>", vendor, product);
815 cam_close_device(dev);
821 testunitready(struct cam_device *device, int task_attr, int retry_count,
822 int timeout, int quiet)
827 ccb = cam_getccb(device);
829 scsi_test_unit_ready(&ccb->csio,
830 /* retries */ retry_count,
832 /* tag_action */ task_attr,
833 /* sense_len */ SSD_FULL_SIZE,
834 /* timeout */ timeout ? timeout : 5000);
836 /* Disable freezing the device queue */
837 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
839 if (arglist & CAM_ARG_ERR_RECOVER)
840 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
842 if (cam_send_ccb(device, ccb) < 0) {
844 perror("error sending test unit ready");
846 if (arglist & CAM_ARG_VERBOSE) {
847 cam_error_print(device, ccb, CAM_ESF_ALL,
848 CAM_EPF_ALL, stderr);
855 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
857 fprintf(stdout, "Unit is ready\n");
860 fprintf(stdout, "Unit is not ready\n");
863 if (arglist & CAM_ARG_VERBOSE) {
864 cam_error_print(device, ccb, CAM_ESF_ALL,
865 CAM_EPF_ALL, stderr);
875 scsistart(struct cam_device *device, int startstop, int loadeject,
876 int task_attr, int retry_count, int timeout)
881 ccb = cam_getccb(device);
884 * If we're stopping, send an ordered tag so the drive in question
885 * will finish any previously queued writes before stopping. If
886 * the device isn't capable of tagged queueing, or if tagged
887 * queueing is turned off, the tag action is a no-op. We override
888 * the default simple tag, although this also has the effect of
889 * overriding the user's wishes if he wanted to specify a simple
893 && (task_attr == MSG_SIMPLE_Q_TAG))
894 task_attr = MSG_ORDERED_Q_TAG;
896 scsi_start_stop(&ccb->csio,
897 /* retries */ retry_count,
899 /* tag_action */ task_attr,
900 /* start/stop */ startstop,
901 /* load_eject */ loadeject,
903 /* sense_len */ SSD_FULL_SIZE,
904 /* timeout */ timeout ? timeout : 120000);
906 /* Disable freezing the device queue */
907 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
909 if (arglist & CAM_ARG_ERR_RECOVER)
910 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
912 if (cam_send_ccb(device, ccb) < 0) {
913 perror("error sending start unit");
915 if (arglist & CAM_ARG_VERBOSE) {
916 cam_error_print(device, ccb, CAM_ESF_ALL,
917 CAM_EPF_ALL, stderr);
924 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
926 fprintf(stdout, "Unit started successfully");
928 fprintf(stdout,", Media loaded\n");
930 fprintf(stdout,"\n");
932 fprintf(stdout, "Unit stopped successfully");
934 fprintf(stdout, ", Media ejected\n");
936 fprintf(stdout, "\n");
942 "Error received from start unit command\n");
945 "Error received from stop unit command\n");
947 if (arglist & CAM_ARG_VERBOSE) {
948 cam_error_print(device, ccb, CAM_ESF_ALL,
949 CAM_EPF_ALL, stderr);
959 scsidoinquiry(struct cam_device *device, int argc, char **argv,
960 char *combinedopt, int task_attr, int retry_count, int timeout)
965 while ((c = getopt(argc, argv, combinedopt)) != -1) {
968 arglist |= CAM_ARG_GET_STDINQ;
971 arglist |= CAM_ARG_GET_XFERRATE;
974 arglist |= CAM_ARG_GET_SERIAL;
982 * If the user didn't specify any inquiry options, he wants all of
985 if ((arglist & CAM_ARG_INQ_MASK) == 0)
986 arglist |= CAM_ARG_INQ_MASK;
988 if (arglist & CAM_ARG_GET_STDINQ)
989 error = scsiinquiry(device, task_attr, retry_count, timeout);
994 if (arglist & CAM_ARG_GET_SERIAL)
995 scsiserial(device, task_attr, retry_count, timeout);
997 if (arglist & CAM_ARG_GET_XFERRATE)
998 error = camxferrate(device);
1004 scsiinquiry(struct cam_device *device, int task_attr, int retry_count,
1008 struct scsi_inquiry_data *inq_buf;
1011 ccb = cam_getccb(device);
1014 warnx("couldn't allocate CCB");
1018 /* cam_getccb cleans up the header, caller has to zero the payload */
1019 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1021 inq_buf = (struct scsi_inquiry_data *)malloc(
1022 sizeof(struct scsi_inquiry_data));
1024 if (inq_buf == NULL) {
1026 warnx("can't malloc memory for inquiry\n");
1029 bzero(inq_buf, sizeof(*inq_buf));
1032 * Note that although the size of the inquiry buffer is the full
1033 * 256 bytes specified in the SCSI spec, we only tell the device
1034 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
1035 * two reasons for this:
1037 * - The SCSI spec says that when a length field is only 1 byte,
1038 * a value of 0 will be interpreted as 256. Therefore
1039 * scsi_inquiry() will convert an inq_len (which is passed in as
1040 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
1041 * to 0. Evidently, very few devices meet the spec in that
1042 * regard. Some devices, like many Seagate disks, take the 0 as
1043 * 0, and don't return any data. One Pioneer DVD-R drive
1044 * returns more data than the command asked for.
1046 * So, since there are numerous devices that just don't work
1047 * right with the full inquiry size, we don't send the full size.
1049 * - The second reason not to use the full inquiry data length is
1050 * that we don't need it here. The only reason we issue a
1051 * standard inquiry is to get the vendor name, device name,
1052 * and revision so scsi_print_inquiry() can print them.
1054 * If, at some point in the future, more inquiry data is needed for
1055 * some reason, this code should use a procedure similar to the
1056 * probe code. i.e., issue a short inquiry, and determine from
1057 * the additional length passed back from the device how much
1058 * inquiry data the device supports. Once the amount the device
1059 * supports is determined, issue an inquiry for that amount and no
1064 scsi_inquiry(&ccb->csio,
1065 /* retries */ retry_count,
1067 /* tag_action */ task_attr,
1068 /* inq_buf */ (u_int8_t *)inq_buf,
1069 /* inq_len */ SHORT_INQUIRY_LENGTH,
1072 /* sense_len */ SSD_FULL_SIZE,
1073 /* timeout */ timeout ? timeout : 5000);
1075 /* Disable freezing the device queue */
1076 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1078 if (arglist & CAM_ARG_ERR_RECOVER)
1079 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1081 if (cam_send_ccb(device, ccb) < 0) {
1082 perror("error sending SCSI inquiry");
1084 if (arglist & CAM_ARG_VERBOSE) {
1085 cam_error_print(device, ccb, CAM_ESF_ALL,
1086 CAM_EPF_ALL, stderr);
1093 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1096 if (arglist & CAM_ARG_VERBOSE) {
1097 cam_error_print(device, ccb, CAM_ESF_ALL,
1098 CAM_EPF_ALL, stderr);
1109 fprintf(stdout, "%s%d: ", device->device_name,
1110 device->dev_unit_num);
1111 scsi_print_inquiry(inq_buf);
1119 scsiserial(struct cam_device *device, int task_attr, int retry_count,
1123 struct scsi_vpd_unit_serial_number *serial_buf;
1124 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
1127 ccb = cam_getccb(device);
1130 warnx("couldn't allocate CCB");
1134 /* cam_getccb cleans up the header, caller has to zero the payload */
1135 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1137 serial_buf = (struct scsi_vpd_unit_serial_number *)
1138 malloc(sizeof(*serial_buf));
1140 if (serial_buf == NULL) {
1142 warnx("can't malloc memory for serial number");
1146 scsi_inquiry(&ccb->csio,
1147 /*retries*/ retry_count,
1149 /* tag_action */ task_attr,
1150 /* inq_buf */ (u_int8_t *)serial_buf,
1151 /* inq_len */ sizeof(*serial_buf),
1153 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
1154 /* sense_len */ SSD_FULL_SIZE,
1155 /* timeout */ timeout ? timeout : 5000);
1157 /* Disable freezing the device queue */
1158 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1160 if (arglist & CAM_ARG_ERR_RECOVER)
1161 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1163 if (cam_send_ccb(device, ccb) < 0) {
1164 warn("error getting serial number");
1166 if (arglist & CAM_ARG_VERBOSE) {
1167 cam_error_print(device, ccb, CAM_ESF_ALL,
1168 CAM_EPF_ALL, stderr);
1176 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1179 if (arglist & CAM_ARG_VERBOSE) {
1180 cam_error_print(device, ccb, CAM_ESF_ALL,
1181 CAM_EPF_ALL, stderr);
1192 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1193 serial_num[serial_buf->length] = '\0';
1195 if ((arglist & CAM_ARG_GET_STDINQ)
1196 || (arglist & CAM_ARG_GET_XFERRATE))
1197 fprintf(stdout, "%s%d: Serial Number ",
1198 device->device_name, device->dev_unit_num);
1200 fprintf(stdout, "%.60s\n", serial_num);
1208 camxferrate(struct cam_device *device)
1210 struct ccb_pathinq cpi;
1212 u_int32_t speed = 0;
1217 if ((retval = get_cpi(device, &cpi)) != 0)
1220 ccb = cam_getccb(device);
1223 warnx("couldn't allocate CCB");
1227 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
1229 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1230 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1232 if (((retval = cam_send_ccb(device, ccb)) < 0)
1233 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1234 const char error_string[] = "error getting transfer settings";
1239 warnx(error_string);
1241 if (arglist & CAM_ARG_VERBOSE)
1242 cam_error_print(device, ccb, CAM_ESF_ALL,
1243 CAM_EPF_ALL, stderr);
1247 goto xferrate_bailout;
1251 speed = cpi.base_transfer_speed;
1253 if (ccb->cts.transport == XPORT_SPI) {
1254 struct ccb_trans_settings_spi *spi =
1255 &ccb->cts.xport_specific.spi;
1257 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1258 freq = scsi_calc_syncsrate(spi->sync_period);
1261 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1262 speed *= (0x01 << spi->bus_width);
1264 } else if (ccb->cts.transport == XPORT_FC) {
1265 struct ccb_trans_settings_fc *fc =
1266 &ccb->cts.xport_specific.fc;
1268 if (fc->valid & CTS_FC_VALID_SPEED)
1269 speed = fc->bitrate;
1270 } else if (ccb->cts.transport == XPORT_SAS) {
1271 struct ccb_trans_settings_sas *sas =
1272 &ccb->cts.xport_specific.sas;
1274 if (sas->valid & CTS_SAS_VALID_SPEED)
1275 speed = sas->bitrate;
1276 } else if (ccb->cts.transport == XPORT_ATA) {
1277 struct ccb_trans_settings_pata *pata =
1278 &ccb->cts.xport_specific.ata;
1280 if (pata->valid & CTS_ATA_VALID_MODE)
1281 speed = ata_mode2speed(pata->mode);
1282 } else if (ccb->cts.transport == XPORT_SATA) {
1283 struct ccb_trans_settings_sata *sata =
1284 &ccb->cts.xport_specific.sata;
1286 if (sata->valid & CTS_SATA_VALID_REVISION)
1287 speed = ata_revision2speed(sata->revision);
1292 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1293 device->device_name, device->dev_unit_num,
1296 fprintf(stdout, "%s%d: %dKB/s transfers",
1297 device->device_name, device->dev_unit_num,
1301 if (ccb->cts.transport == XPORT_SPI) {
1302 struct ccb_trans_settings_spi *spi =
1303 &ccb->cts.xport_specific.spi;
1305 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1306 && (spi->sync_offset != 0))
1307 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1308 freq % 1000, spi->sync_offset);
1310 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1311 && (spi->bus_width > 0)) {
1312 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1313 && (spi->sync_offset != 0)) {
1314 fprintf(stdout, ", ");
1316 fprintf(stdout, " (");
1318 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1319 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1320 && (spi->sync_offset != 0)) {
1321 fprintf(stdout, ")");
1323 } else if (ccb->cts.transport == XPORT_ATA) {
1324 struct ccb_trans_settings_pata *pata =
1325 &ccb->cts.xport_specific.ata;
1328 if (pata->valid & CTS_ATA_VALID_MODE)
1329 printf("%s, ", ata_mode2string(pata->mode));
1330 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1331 printf("ATAPI %dbytes, ", pata->atapi);
1332 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1333 printf("PIO %dbytes", pata->bytecount);
1335 } else if (ccb->cts.transport == XPORT_SATA) {
1336 struct ccb_trans_settings_sata *sata =
1337 &ccb->cts.xport_specific.sata;
1340 if (sata->valid & CTS_SATA_VALID_REVISION)
1341 printf("SATA %d.x, ", sata->revision);
1344 if (sata->valid & CTS_SATA_VALID_MODE)
1345 printf("%s, ", ata_mode2string(sata->mode));
1346 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1347 printf("ATAPI %dbytes, ", sata->atapi);
1348 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1349 printf("PIO %dbytes", sata->bytecount);
1353 if (ccb->cts.protocol == PROTO_SCSI) {
1354 struct ccb_trans_settings_scsi *scsi =
1355 &ccb->cts.proto_specific.scsi;
1356 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1357 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1358 fprintf(stdout, ", Command Queueing Enabled");
1363 fprintf(stdout, "\n");
1373 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1375 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1376 ((u_int32_t)parm->lba_size_2 << 16);
1378 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1379 ((u_int64_t)parm->lba_size48_2 << 16) |
1380 ((u_int64_t)parm->lba_size48_3 << 32) |
1381 ((u_int64_t)parm->lba_size48_4 << 48);
1385 "Support Enabled Value\n");
1388 printf("Host Protected Area (HPA) ");
1389 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1390 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1391 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1394 printf("HPA - Security ");
1395 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1405 atasata(struct ata_params *parm)
1409 if (parm->satacapabilities != 0xffff &&
1410 parm->satacapabilities != 0x0000)
1417 atacapprint(struct ata_params *parm)
1419 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1420 ((u_int32_t)parm->lba_size_2 << 16);
1422 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1423 ((u_int64_t)parm->lba_size48_2 << 16) |
1424 ((u_int64_t)parm->lba_size48_3 << 32) |
1425 ((u_int64_t)parm->lba_size48_4 << 48);
1428 printf("protocol ");
1429 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1430 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1431 if (parm->satacapabilities & ATA_SATA_GEN3)
1432 printf(" SATA 3.x\n");
1433 else if (parm->satacapabilities & ATA_SATA_GEN2)
1434 printf(" SATA 2.x\n");
1435 else if (parm->satacapabilities & ATA_SATA_GEN1)
1436 printf(" SATA 1.x\n");
1442 printf("device model %.40s\n", parm->model);
1443 printf("firmware revision %.8s\n", parm->revision);
1444 printf("serial number %.20s\n", parm->serial);
1445 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1446 printf("WWN %04x%04x%04x%04x\n",
1447 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1449 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1450 printf("media serial number %.30s\n",
1451 parm->media_serial);
1454 printf("cylinders %d\n", parm->cylinders);
1455 printf("heads %d\n", parm->heads);
1456 printf("sectors/track %d\n", parm->sectors);
1457 printf("sector size logical %u, physical %lu, offset %lu\n",
1458 ata_logical_sector_size(parm),
1459 (unsigned long)ata_physical_sector_size(parm),
1460 (unsigned long)ata_logical_sector_offset(parm));
1462 if (parm->config == ATA_PROTO_CFA ||
1463 (parm->support.command2 & ATA_SUPPORT_CFA))
1464 printf("CFA supported\n");
1466 printf("LBA%ssupported ",
1467 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1469 printf("%d sectors\n", lbasize);
1473 printf("LBA48%ssupported ",
1474 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1476 printf("%ju sectors\n", (uintmax_t)lbasize48);
1480 printf("PIO supported PIO");
1481 switch (ata_max_pmode(parm)) {
1497 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1498 printf(" w/o IORDY");
1501 printf("DMA%ssupported ",
1502 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1503 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1504 if (parm->mwdmamodes & 0xff) {
1506 if (parm->mwdmamodes & 0x04)
1508 else if (parm->mwdmamodes & 0x02)
1510 else if (parm->mwdmamodes & 0x01)
1514 if ((parm->atavalid & ATA_FLAG_88) &&
1515 (parm->udmamodes & 0xff)) {
1517 if (parm->udmamodes & 0x40)
1519 else if (parm->udmamodes & 0x20)
1521 else if (parm->udmamodes & 0x10)
1523 else if (parm->udmamodes & 0x08)
1525 else if (parm->udmamodes & 0x04)
1527 else if (parm->udmamodes & 0x02)
1529 else if (parm->udmamodes & 0x01)
1536 if (parm->media_rotation_rate == 1) {
1537 printf("media RPM non-rotating\n");
1538 } else if (parm->media_rotation_rate >= 0x0401 &&
1539 parm->media_rotation_rate <= 0xFFFE) {
1540 printf("media RPM %d\n",
1541 parm->media_rotation_rate);
1544 printf("Zoned-Device Commands ");
1545 switch (parm->support3 & ATA_SUPPORT_ZONE_MASK) {
1546 case ATA_SUPPORT_ZONE_DEV_MANAGED:
1547 printf("device managed\n");
1549 case ATA_SUPPORT_ZONE_HOST_AWARE:
1550 printf("host aware\n");
1557 "Support Enabled Value Vendor\n");
1558 printf("read ahead %s %s\n",
1559 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1560 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1561 printf("write cache %s %s\n",
1562 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1563 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1564 printf("flush cache %s %s\n",
1565 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1566 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1567 printf("overlap %s\n",
1568 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1569 printf("Tagged Command Queuing (TCQ) %s %s",
1570 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1571 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1572 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1573 printf(" %d tags\n",
1574 ATA_QUEUE_LEN(parm->queue) + 1);
1577 printf("Native Command Queuing (NCQ) ");
1578 if (parm->satacapabilities != 0xffff &&
1579 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1580 printf("yes %d tags\n",
1581 ATA_QUEUE_LEN(parm->queue) + 1);
1585 printf("NCQ Queue Management %s\n", atasata(parm) &&
1586 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1588 printf("NCQ Streaming %s\n", atasata(parm) &&
1589 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1591 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1592 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1595 printf("SMART %s %s\n",
1596 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1597 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1598 printf("microcode download %s %s\n",
1599 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1600 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1601 printf("security %s %s\n",
1602 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1603 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1604 printf("power management %s %s\n",
1605 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1606 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1607 printf("advanced power management %s %s",
1608 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1609 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1610 if (parm->support.command2 & ATA_SUPPORT_APM) {
1611 printf(" %d/0x%02X\n",
1612 parm->apm_value & 0xff, parm->apm_value & 0xff);
1615 printf("automatic acoustic management %s %s",
1616 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1617 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1618 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1619 printf(" %d/0x%02X %d/0x%02X\n",
1620 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1621 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1622 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1623 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1626 printf("media status notification %s %s\n",
1627 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1628 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1629 printf("power-up in Standby %s %s\n",
1630 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1631 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1632 printf("write-read-verify %s %s",
1633 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1634 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1635 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1636 printf(" %d/0x%x\n",
1637 parm->wrv_mode, parm->wrv_mode);
1640 printf("unload %s %s\n",
1641 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1642 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1643 printf("general purpose logging %s %s\n",
1644 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1645 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1646 printf("free-fall %s %s\n",
1647 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1648 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1649 printf("Data Set Management (DSM/TRIM) ");
1650 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1652 printf("DSM - max 512byte blocks ");
1653 if (parm->max_dsm_blocks == 0x00)
1654 printf("yes not specified\n");
1657 parm->max_dsm_blocks);
1659 printf("DSM - deterministic read ");
1660 if (parm->support3 & ATA_SUPPORT_DRAT) {
1661 if (parm->support3 & ATA_SUPPORT_RZAT)
1662 printf("yes zeroed\n");
1664 printf("yes any value\n");
1674 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1676 struct ata_pass_16 *ata_pass_16;
1677 struct ata_cmd ata_cmd;
1679 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1680 ata_cmd.command = ata_pass_16->command;
1681 ata_cmd.control = ata_pass_16->control;
1682 ata_cmd.features = ata_pass_16->features;
1684 if (arglist & CAM_ARG_VERBOSE) {
1685 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1686 ata_op_string(&ata_cmd),
1687 ccb->csio.ccb_h.timeout);
1690 /* Disable freezing the device queue */
1691 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1693 if (arglist & CAM_ARG_ERR_RECOVER)
1694 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1696 if (cam_send_ccb(device, ccb) < 0) {
1697 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1698 warn("error sending ATA %s via pass_16",
1699 ata_op_string(&ata_cmd));
1702 if (arglist & CAM_ARG_VERBOSE) {
1703 cam_error_print(device, ccb, CAM_ESF_ALL,
1704 CAM_EPF_ALL, stderr);
1710 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1711 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1712 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1713 warnx("ATA %s via pass_16 failed",
1714 ata_op_string(&ata_cmd));
1716 if (arglist & CAM_ARG_VERBOSE) {
1717 cam_error_print(device, ccb, CAM_ESF_ALL,
1718 CAM_EPF_ALL, stderr);
1729 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1731 if (arglist & CAM_ARG_VERBOSE) {
1732 warnx("sending ATA %s with timeout of %u msecs",
1733 ata_op_string(&(ccb->ataio.cmd)),
1734 ccb->ataio.ccb_h.timeout);
1737 /* Disable freezing the device queue */
1738 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1740 if (arglist & CAM_ARG_ERR_RECOVER)
1741 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1743 if (cam_send_ccb(device, ccb) < 0) {
1744 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1745 warn("error sending ATA %s",
1746 ata_op_string(&(ccb->ataio.cmd)));
1749 if (arglist & CAM_ARG_VERBOSE) {
1750 cam_error_print(device, ccb, CAM_ESF_ALL,
1751 CAM_EPF_ALL, stderr);
1757 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1758 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1759 warnx("ATA %s failed: %d",
1760 ata_op_string(&(ccb->ataio.cmd)), quiet);
1763 if (arglist & CAM_ARG_VERBOSE) {
1764 cam_error_print(device, ccb, CAM_ESF_ALL,
1765 CAM_EPF_ALL, stderr);
1775 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1776 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1777 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1778 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1779 u_int16_t dxfer_len, int timeout, int quiet)
1781 if (data_ptr != NULL) {
1782 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1783 AP_FLAG_TLEN_SECT_CNT;
1784 if (flags & CAM_DIR_OUT)
1785 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1787 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1789 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1792 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1794 scsi_ata_pass_16(&ccb->csio,
1808 /*sense_len*/SSD_FULL_SIZE,
1811 return scsi_cam_pass_16_send(device, ccb, quiet);
1815 ata_try_pass_16(struct cam_device *device)
1817 struct ccb_pathinq cpi;
1819 if (get_cpi(device, &cpi) != 0) {
1820 warnx("couldn't get CPI");
1824 if (cpi.protocol == PROTO_SCSI) {
1825 /* possibly compatible with pass_16 */
1829 /* likely not compatible with pass_16 */
1834 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1835 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1836 u_int8_t command, u_int8_t features, u_int32_t lba,
1837 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1838 int timeout, int quiet)
1842 switch (ata_try_pass_16(device)) {
1846 /* Try using SCSI Passthrough */
1847 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1848 0, tag_action, command, features, lba,
1849 sector_count, data_ptr, dxfer_len,
1853 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1854 cam_fill_ataio(&ccb->ataio,
1863 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1864 return ata_cam_send(device, ccb, quiet);
1868 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1869 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1870 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1871 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1872 u_int16_t dxfer_len, int timeout, int force48bit)
1876 retval = ata_try_pass_16(device);
1883 /* Try using SCSI Passthrough */
1884 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1885 ata_flags, tag_action, command, features,
1886 lba, sector_count, data_ptr, dxfer_len,
1889 if (ata_flags & AP_FLAG_CHK_COND) {
1890 /* Decode ata_res from sense data */
1891 struct ata_res_pass16 *res_pass16;
1892 struct ata_res *res;
1896 /* sense_data is 4 byte aligned */
1897 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1898 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1899 ptr[i] = le16toh(ptr[i]);
1901 /* sense_data is 4 byte aligned */
1902 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1903 &ccb->csio.sense_data;
1904 res = &ccb->ataio.res;
1905 res->flags = res_pass16->flags;
1906 res->status = res_pass16->status;
1907 res->error = res_pass16->error;
1908 res->lba_low = res_pass16->lba_low;
1909 res->lba_mid = res_pass16->lba_mid;
1910 res->lba_high = res_pass16->lba_high;
1911 res->device = res_pass16->device;
1912 res->lba_low_exp = res_pass16->lba_low_exp;
1913 res->lba_mid_exp = res_pass16->lba_mid_exp;
1914 res->lba_high_exp = res_pass16->lba_high_exp;
1915 res->sector_count = res_pass16->sector_count;
1916 res->sector_count_exp = res_pass16->sector_count_exp;
1922 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1923 cam_fill_ataio(&ccb->ataio,
1932 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1933 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1935 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1937 if (ata_flags & AP_FLAG_CHK_COND)
1938 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1940 return ata_cam_send(device, ccb, 0);
1944 dump_data(uint16_t *ptr, uint32_t len)
1948 for (i = 0; i < len / 2; i++) {
1950 printf(" %3d: ", i);
1951 printf("%04hx ", ptr[i]);
1960 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1961 int is48bit, u_int64_t *hpasize)
1963 struct ata_res *res;
1965 res = &ccb->ataio.res;
1966 if (res->status & ATA_STATUS_ERROR) {
1967 if (arglist & CAM_ARG_VERBOSE) {
1968 cam_error_print(device, ccb, CAM_ESF_ALL,
1969 CAM_EPF_ALL, stderr);
1970 printf("error = 0x%02x, sector_count = 0x%04x, "
1971 "device = 0x%02x, status = 0x%02x\n",
1972 res->error, res->sector_count,
1973 res->device, res->status);
1976 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1977 warnx("Max address has already been set since "
1978 "last power-on or hardware reset");
1984 if (arglist & CAM_ARG_VERBOSE) {
1985 fprintf(stdout, "%s%d: Raw native max data:\n",
1986 device->device_name, device->dev_unit_num);
1987 /* res is 4 byte aligned */
1988 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1990 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1991 "status = 0x%02x\n", res->error, res->sector_count,
1992 res->device, res->status);
1995 if (hpasize != NULL) {
1997 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1998 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1999 ((res->lba_high << 16) | (res->lba_mid << 8) |
2002 *hpasize = (((res->device & 0x0f) << 24) |
2003 (res->lba_high << 16) | (res->lba_mid << 8) |
2012 ata_read_native_max(struct cam_device *device, int retry_count,
2013 u_int32_t timeout, union ccb *ccb,
2014 struct ata_params *parm, u_int64_t *hpasize)
2020 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
2021 protocol = AP_PROTO_NON_DATA;
2024 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
2025 protocol |= AP_EXTEND;
2027 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
2030 error = ata_do_cmd(device,
2033 /*flags*/CAM_DIR_NONE,
2034 /*protocol*/protocol,
2035 /*ata_flags*/AP_FLAG_CHK_COND,
2036 /*tag_action*/MSG_SIMPLE_Q_TAG,
2043 timeout ? timeout : 5000,
2049 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
2053 atahpa_set_max(struct cam_device *device, int retry_count,
2054 u_int32_t timeout, union ccb *ccb,
2055 int is48bit, u_int64_t maxsize, int persist)
2061 protocol = AP_PROTO_NON_DATA;
2064 cmd = ATA_SET_MAX_ADDRESS48;
2065 protocol |= AP_EXTEND;
2067 cmd = ATA_SET_MAX_ADDRESS;
2070 /* lba's are zero indexed so the max lba is requested max - 1 */
2074 error = ata_do_cmd(device,
2077 /*flags*/CAM_DIR_NONE,
2078 /*protocol*/protocol,
2079 /*ata_flags*/AP_FLAG_CHK_COND,
2080 /*tag_action*/MSG_SIMPLE_Q_TAG,
2082 /*features*/ATA_HPA_FEAT_MAX_ADDR,
2084 /*sector_count*/persist,
2087 timeout ? timeout : 1000,
2093 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2097 atahpa_password(struct cam_device *device, int retry_count,
2098 u_int32_t timeout, union ccb *ccb,
2099 int is48bit, struct ata_set_max_pwd *pwd)
2105 protocol = AP_PROTO_PIO_OUT;
2106 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2108 error = ata_do_cmd(device,
2111 /*flags*/CAM_DIR_OUT,
2112 /*protocol*/protocol,
2113 /*ata_flags*/AP_FLAG_CHK_COND,
2114 /*tag_action*/MSG_SIMPLE_Q_TAG,
2116 /*features*/ATA_HPA_FEAT_SET_PWD,
2119 /*data_ptr*/(u_int8_t*)pwd,
2120 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2121 timeout ? timeout : 1000,
2127 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2131 atahpa_lock(struct cam_device *device, int retry_count,
2132 u_int32_t timeout, union ccb *ccb, int is48bit)
2138 protocol = AP_PROTO_NON_DATA;
2139 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2141 error = ata_do_cmd(device,
2144 /*flags*/CAM_DIR_NONE,
2145 /*protocol*/protocol,
2146 /*ata_flags*/AP_FLAG_CHK_COND,
2147 /*tag_action*/MSG_SIMPLE_Q_TAG,
2149 /*features*/ATA_HPA_FEAT_LOCK,
2154 timeout ? timeout : 1000,
2160 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2164 atahpa_unlock(struct cam_device *device, int retry_count,
2165 u_int32_t timeout, union ccb *ccb,
2166 int is48bit, struct ata_set_max_pwd *pwd)
2172 protocol = AP_PROTO_PIO_OUT;
2173 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2175 error = ata_do_cmd(device,
2178 /*flags*/CAM_DIR_OUT,
2179 /*protocol*/protocol,
2180 /*ata_flags*/AP_FLAG_CHK_COND,
2181 /*tag_action*/MSG_SIMPLE_Q_TAG,
2183 /*features*/ATA_HPA_FEAT_UNLOCK,
2186 /*data_ptr*/(u_int8_t*)pwd,
2187 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2188 timeout ? timeout : 1000,
2194 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2198 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2199 u_int32_t timeout, union ccb *ccb, int is48bit)
2205 protocol = AP_PROTO_NON_DATA;
2206 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2208 error = ata_do_cmd(device,
2211 /*flags*/CAM_DIR_NONE,
2212 /*protocol*/protocol,
2213 /*ata_flags*/AP_FLAG_CHK_COND,
2214 /*tag_action*/MSG_SIMPLE_Q_TAG,
2216 /*features*/ATA_HPA_FEAT_FREEZE,
2221 timeout ? timeout : 1000,
2227 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2232 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2233 union ccb *ccb, struct ata_params** ident_bufp)
2235 struct ata_params *ident_buf;
2236 struct ccb_pathinq cpi;
2237 struct ccb_getdev cgd;
2240 u_int8_t command, retry_command;
2242 if (get_cpi(device, &cpi) != 0) {
2243 warnx("couldn't get CPI");
2247 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2248 if (cpi.protocol == PROTO_ATA) {
2249 if (get_cgd(device, &cgd) != 0) {
2250 warnx("couldn't get CGD");
2254 command = (cgd.protocol == PROTO_ATA) ?
2255 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2258 /* We don't know which for sure so try both */
2259 command = ATA_ATA_IDENTIFY;
2260 retry_command = ATA_ATAPI_IDENTIFY;
2263 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2265 warnx("can't calloc memory for identify\n");
2269 error = ata_do_28bit_cmd(device,
2271 /*retries*/retry_count,
2272 /*flags*/CAM_DIR_IN,
2273 /*protocol*/AP_PROTO_PIO_IN,
2274 /*tag_action*/MSG_SIMPLE_Q_TAG,
2279 /*data_ptr*/(u_int8_t *)ptr,
2280 /*dxfer_len*/sizeof(struct ata_params),
2281 /*timeout*/timeout ? timeout : 30 * 1000,
2285 if (retry_command == 0) {
2289 error = ata_do_28bit_cmd(device,
2291 /*retries*/retry_count,
2292 /*flags*/CAM_DIR_IN,
2293 /*protocol*/AP_PROTO_PIO_IN,
2294 /*tag_action*/MSG_SIMPLE_Q_TAG,
2295 /*command*/retry_command,
2299 /*data_ptr*/(u_int8_t *)ptr,
2300 /*dxfer_len*/sizeof(struct ata_params),
2301 /*timeout*/timeout ? timeout : 30 * 1000,
2310 ident_buf = (struct ata_params *)ptr;
2311 ata_param_fixup(ident_buf);
2314 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2319 if (arglist & CAM_ARG_VERBOSE) {
2320 fprintf(stdout, "%s%d: Raw identify data:\n",
2321 device->device_name, device->dev_unit_num);
2322 dump_data(ptr, sizeof(struct ata_params));
2325 /* check for invalid (all zero) response */
2327 warnx("Invalid identify response detected");
2332 *ident_bufp = ident_buf;
2339 ataidentify(struct cam_device *device, int retry_count, int timeout)
2342 struct ata_params *ident_buf;
2345 if ((ccb = cam_getccb(device)) == NULL) {
2346 warnx("couldn't allocate CCB");
2350 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2355 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2356 if (ata_read_native_max(device, retry_count, timeout, ccb,
2357 ident_buf, &hpasize) != 0) {
2365 printf("%s%d: ", device->device_name, device->dev_unit_num);
2366 ata_print_ident(ident_buf);
2367 camxferrate(device);
2368 atacapprint(ident_buf);
2369 atahpa_print(ident_buf, hpasize, 0);
2379 nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused)
2381 struct nvme_controller_data cdata;
2383 if (nvme_get_cdata(device, &cdata))
2385 nvme_print_controller(&cdata);
2392 identify(struct cam_device *device, int retry_count, int timeout)
2395 struct ccb_pathinq cpi;
2397 if (get_cpi(device, &cpi) != 0) {
2398 warnx("couldn't get CPI");
2402 if (cpi.protocol == PROTO_NVME) {
2403 return (nvmeidentify(device, retry_count, timeout));
2406 return (ataidentify(device, retry_count, timeout));
2411 ATA_SECURITY_ACTION_PRINT,
2412 ATA_SECURITY_ACTION_FREEZE,
2413 ATA_SECURITY_ACTION_UNLOCK,
2414 ATA_SECURITY_ACTION_DISABLE,
2415 ATA_SECURITY_ACTION_ERASE,
2416 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2417 ATA_SECURITY_ACTION_SET_PASSWORD
2421 atasecurity_print_time(u_int16_t tw)
2425 printf("unspecified");
2427 printf("> 508 min");
2429 printf("%i min", 2 * tw);
2433 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2437 return 2 * 3600 * 1000; /* default: two hours */
2438 else if (timeout > 255)
2439 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2441 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2446 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2450 bzero(&cmd, sizeof(cmd));
2451 cmd.command = command;
2452 printf("Issuing %s", ata_op_string(&cmd));
2455 char pass[sizeof(pwd->password)+1];
2457 /* pwd->password may not be null terminated */
2458 pass[sizeof(pwd->password)] = '\0';
2459 strncpy(pass, pwd->password, sizeof(pwd->password));
2460 printf(" password='%s', user='%s'",
2462 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2465 if (command == ATA_SECURITY_SET_PASSWORD) {
2466 printf(", mode='%s'",
2467 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2468 "maximum" : "high");
2476 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2477 int retry_count, u_int32_t timeout, int quiet)
2481 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2483 return ata_do_28bit_cmd(device,
2486 /*flags*/CAM_DIR_NONE,
2487 /*protocol*/AP_PROTO_NON_DATA,
2488 /*tag_action*/MSG_SIMPLE_Q_TAG,
2489 /*command*/ATA_SECURITY_FREEZE_LOCK,
2500 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2501 int retry_count, u_int32_t timeout,
2502 struct ata_security_password *pwd, int quiet)
2506 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2508 return ata_do_28bit_cmd(device,
2511 /*flags*/CAM_DIR_OUT,
2512 /*protocol*/AP_PROTO_PIO_OUT,
2513 /*tag_action*/MSG_SIMPLE_Q_TAG,
2514 /*command*/ATA_SECURITY_UNLOCK,
2518 /*data_ptr*/(u_int8_t *)pwd,
2519 /*dxfer_len*/sizeof(*pwd),
2525 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2526 int retry_count, u_int32_t timeout,
2527 struct ata_security_password *pwd, int quiet)
2531 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2532 return ata_do_28bit_cmd(device,
2535 /*flags*/CAM_DIR_OUT,
2536 /*protocol*/AP_PROTO_PIO_OUT,
2537 /*tag_action*/MSG_SIMPLE_Q_TAG,
2538 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2542 /*data_ptr*/(u_int8_t *)pwd,
2543 /*dxfer_len*/sizeof(*pwd),
2550 atasecurity_erase_confirm(struct cam_device *device,
2551 struct ata_params* ident_buf)
2554 printf("\nYou are about to ERASE ALL DATA from the following"
2555 " device:\n%s%d,%s%d: ", device->device_name,
2556 device->dev_unit_num, device->given_dev_name,
2557 device->given_unit_number);
2558 ata_print_ident(ident_buf);
2562 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2564 if (fgets(str, sizeof(str), stdin) != NULL) {
2565 if (strncasecmp(str, "yes", 3) == 0) {
2567 } else if (strncasecmp(str, "no", 2) == 0) {
2570 printf("Please answer \"yes\" or "
2581 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2582 int retry_count, u_int32_t timeout,
2583 u_int32_t erase_timeout,
2584 struct ata_security_password *pwd, int quiet)
2589 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2591 error = ata_do_28bit_cmd(device,
2594 /*flags*/CAM_DIR_NONE,
2595 /*protocol*/AP_PROTO_NON_DATA,
2596 /*tag_action*/MSG_SIMPLE_Q_TAG,
2597 /*command*/ATA_SECURITY_ERASE_PREPARE,
2610 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2612 error = ata_do_28bit_cmd(device,
2615 /*flags*/CAM_DIR_OUT,
2616 /*protocol*/AP_PROTO_PIO_OUT,
2617 /*tag_action*/MSG_SIMPLE_Q_TAG,
2618 /*command*/ATA_SECURITY_ERASE_UNIT,
2622 /*data_ptr*/(u_int8_t *)pwd,
2623 /*dxfer_len*/sizeof(*pwd),
2624 /*timeout*/erase_timeout,
2627 if (error == 0 && quiet == 0)
2628 printf("\nErase Complete\n");
2634 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2635 int retry_count, u_int32_t timeout,
2636 struct ata_security_password *pwd, int quiet)
2640 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2642 return ata_do_28bit_cmd(device,
2645 /*flags*/CAM_DIR_OUT,
2646 /*protocol*/AP_PROTO_PIO_OUT,
2647 /*tag_action*/MSG_SIMPLE_Q_TAG,
2648 /*command*/ATA_SECURITY_SET_PASSWORD,
2652 /*data_ptr*/(u_int8_t *)pwd,
2653 /*dxfer_len*/sizeof(*pwd),
2659 atasecurity_print(struct ata_params *parm)
2662 printf("\nSecurity Option Value\n");
2663 if (arglist & CAM_ARG_VERBOSE) {
2664 printf("status %04x\n",
2665 parm->security_status);
2667 printf("supported %s\n",
2668 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2669 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2671 printf("enabled %s\n",
2672 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2673 printf("drive locked %s\n",
2674 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2675 printf("security config frozen %s\n",
2676 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2677 printf("count expired %s\n",
2678 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2679 printf("security level %s\n",
2680 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2681 printf("enhanced erase supported %s\n",
2682 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2683 printf("erase time ");
2684 atasecurity_print_time(parm->erase_time);
2686 printf("enhanced erase time ");
2687 atasecurity_print_time(parm->enhanced_erase_time);
2689 printf("master password rev %04x%s\n",
2690 parm->master_passwd_revision,
2691 parm->master_passwd_revision == 0x0000 ||
2692 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2696 * Validates and copies the password in optarg to the passed buffer.
2697 * If the password in optarg is the same length as the buffer then
2698 * the data will still be copied but no null termination will occur.
2701 ata_getpwd(u_int8_t *passwd, int max, char opt)
2705 len = strlen(optarg);
2707 warnx("-%c password is too long", opt);
2709 } else if (len == 0) {
2710 warnx("-%c password is missing", opt);
2712 } else if (optarg[0] == '-'){
2713 warnx("-%c password starts with '-' (generic arg?)", opt);
2715 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2716 warnx("-%c password conflicts with existing password from -%c",
2721 /* Callers pass in a buffer which does NOT need to be terminated */
2722 strncpy(passwd, optarg, max);
2729 ATA_HPA_ACTION_PRINT,
2730 ATA_HPA_ACTION_SET_MAX,
2731 ATA_HPA_ACTION_SET_PWD,
2732 ATA_HPA_ACTION_LOCK,
2733 ATA_HPA_ACTION_UNLOCK,
2734 ATA_HPA_ACTION_FREEZE_LOCK
2738 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2739 u_int64_t maxsize, int persist)
2741 printf("\nYou are about to configure HPA to limit the user accessible\n"
2742 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2743 persist ? "persistently" : "temporarily",
2744 device->device_name, device->dev_unit_num,
2745 device->given_dev_name, device->given_unit_number);
2746 ata_print_ident(ident_buf);
2750 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2752 if (NULL != fgets(str, sizeof(str), stdin)) {
2753 if (0 == strncasecmp(str, "yes", 3)) {
2755 } else if (0 == strncasecmp(str, "no", 2)) {
2758 printf("Please answer \"yes\" or "
2769 atahpa(struct cam_device *device, int retry_count, int timeout,
2770 int argc, char **argv, char *combinedopt)
2773 struct ata_params *ident_buf;
2774 struct ccb_getdev cgd;
2775 struct ata_set_max_pwd pwd;
2776 int error, confirm, quiet, c, action, actions, persist;
2777 int security, is48bit, pwdsize;
2778 u_int64_t hpasize, maxsize;
2787 memset(&pwd, 0, sizeof(pwd));
2789 /* default action is to print hpa information */
2790 action = ATA_HPA_ACTION_PRINT;
2791 pwdsize = sizeof(pwd.password);
2793 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2796 action = ATA_HPA_ACTION_SET_MAX;
2797 maxsize = strtoumax(optarg, NULL, 0);
2802 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2804 action = ATA_HPA_ACTION_SET_PWD;
2810 action = ATA_HPA_ACTION_LOCK;
2816 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2818 action = ATA_HPA_ACTION_UNLOCK;
2824 action = ATA_HPA_ACTION_FREEZE_LOCK;
2844 warnx("too many hpa actions specified");
2848 if (get_cgd(device, &cgd) != 0) {
2849 warnx("couldn't get CGD");
2853 ccb = cam_getccb(device);
2855 warnx("couldn't allocate CCB");
2859 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2866 printf("%s%d: ", device->device_name, device->dev_unit_num);
2867 ata_print_ident(ident_buf);
2868 camxferrate(device);
2871 if (action == ATA_HPA_ACTION_PRINT) {
2872 error = ata_read_native_max(device, retry_count, timeout, ccb,
2873 ident_buf, &hpasize);
2875 atahpa_print(ident_buf, hpasize, 1);
2882 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2883 warnx("HPA is not supported by this device");
2889 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2890 warnx("HPA Security is not supported by this device");
2896 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2899 * The ATA spec requires:
2900 * 1. Read native max addr is called directly before set max addr
2901 * 2. Read native max addr is NOT called before any other set max call
2904 case ATA_HPA_ACTION_SET_MAX:
2906 atahpa_set_confirm(device, ident_buf, maxsize,
2913 error = ata_read_native_max(device, retry_count, timeout,
2914 ccb, ident_buf, &hpasize);
2916 error = atahpa_set_max(device, retry_count, timeout,
2917 ccb, is48bit, maxsize, persist);
2919 /* redo identify to get new lba values */
2920 error = ata_do_identify(device, retry_count,
2923 atahpa_print(ident_buf, hpasize, 1);
2928 case ATA_HPA_ACTION_SET_PWD:
2929 error = atahpa_password(device, retry_count, timeout,
2930 ccb, is48bit, &pwd);
2932 printf("HPA password has been set\n");
2935 case ATA_HPA_ACTION_LOCK:
2936 error = atahpa_lock(device, retry_count, timeout,
2939 printf("HPA has been locked\n");
2942 case ATA_HPA_ACTION_UNLOCK:
2943 error = atahpa_unlock(device, retry_count, timeout,
2944 ccb, is48bit, &pwd);
2946 printf("HPA has been unlocked\n");
2949 case ATA_HPA_ACTION_FREEZE_LOCK:
2950 error = atahpa_freeze_lock(device, retry_count, timeout,
2953 printf("HPA has been frozen\n");
2957 errx(1, "Option currently not supported");
2967 atasecurity(struct cam_device *device, int retry_count, int timeout,
2968 int argc, char **argv, char *combinedopt)
2971 struct ata_params *ident_buf;
2972 int error, confirm, quiet, c, action, actions, setpwd;
2973 int security_enabled, erase_timeout, pwdsize;
2974 struct ata_security_password pwd;
2982 memset(&pwd, 0, sizeof(pwd));
2984 /* default action is to print security information */
2985 action = ATA_SECURITY_ACTION_PRINT;
2987 /* user is master by default as its safer that way */
2988 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2989 pwdsize = sizeof(pwd.password);
2991 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2994 action = ATA_SECURITY_ACTION_FREEZE;
2999 if (strcasecmp(optarg, "user") == 0) {
3000 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
3001 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
3002 } else if (strcasecmp(optarg, "master") == 0) {
3003 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3004 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
3006 warnx("-U argument '%s' is invalid (must be "
3007 "'user' or 'master')", optarg);
3013 if (strcasecmp(optarg, "high") == 0) {
3014 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3015 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3016 } else if (strcasecmp(optarg, "maximum") == 0) {
3017 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3018 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3020 warnx("-l argument '%s' is unknown (must be "
3021 "'high' or 'maximum')", optarg);
3027 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3029 action = ATA_SECURITY_ACTION_UNLOCK;
3034 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3036 action = ATA_SECURITY_ACTION_DISABLE;
3041 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3043 action = ATA_SECURITY_ACTION_ERASE;
3048 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3050 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3051 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3056 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3059 if (action == ATA_SECURITY_ACTION_PRINT)
3060 action = ATA_SECURITY_ACTION_SET_PASSWORD;
3062 * Don't increment action as this can be combined
3063 * with other actions.
3076 erase_timeout = atoi(optarg) * 1000;
3082 warnx("too many security actions specified");
3086 if ((ccb = cam_getccb(device)) == NULL) {
3087 warnx("couldn't allocate CCB");
3091 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3098 printf("%s%d: ", device->device_name, device->dev_unit_num);
3099 ata_print_ident(ident_buf);
3100 camxferrate(device);
3103 if (action == ATA_SECURITY_ACTION_PRINT) {
3104 atasecurity_print(ident_buf);
3110 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3111 warnx("Security not supported");
3117 /* default timeout 15 seconds the same as linux hdparm */
3118 timeout = timeout ? timeout : 15 * 1000;
3120 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3122 /* first set the password if requested */
3124 /* confirm we can erase before setting the password if erasing */
3126 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3127 action == ATA_SECURITY_ACTION_ERASE) &&
3128 atasecurity_erase_confirm(device, ident_buf) == 0) {
3134 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3135 pwd.revision = ident_buf->master_passwd_revision;
3136 if (pwd.revision != 0 && pwd.revision != 0xfff &&
3137 --pwd.revision == 0) {
3138 pwd.revision = 0xfffe;
3141 error = atasecurity_set_password(device, ccb, retry_count,
3142 timeout, &pwd, quiet);
3148 security_enabled = 1;
3152 case ATA_SECURITY_ACTION_FREEZE:
3153 error = atasecurity_freeze(device, ccb, retry_count,
3157 case ATA_SECURITY_ACTION_UNLOCK:
3158 if (security_enabled) {
3159 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3160 error = atasecurity_unlock(device, ccb,
3161 retry_count, timeout, &pwd, quiet);
3163 warnx("Can't unlock, drive is not locked");
3167 warnx("Can't unlock, security is disabled");
3172 case ATA_SECURITY_ACTION_DISABLE:
3173 if (security_enabled) {
3174 /* First unlock the drive if its locked */
3175 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3176 error = atasecurity_unlock(device, ccb,
3184 error = atasecurity_disable(device,
3192 warnx("Can't disable security (already disabled)");
3197 case ATA_SECURITY_ACTION_ERASE:
3198 if (security_enabled) {
3199 if (erase_timeout == 0) {
3200 erase_timeout = atasecurity_erase_timeout_msecs(
3201 ident_buf->erase_time);
3204 error = atasecurity_erase(device, ccb, retry_count,
3205 timeout, erase_timeout, &pwd, quiet);
3207 warnx("Can't secure erase (security is disabled)");
3212 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3213 if (security_enabled) {
3214 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3215 if (erase_timeout == 0) {
3217 atasecurity_erase_timeout_msecs(
3218 ident_buf->enhanced_erase_time);
3221 error = atasecurity_erase(device, ccb,
3222 retry_count, timeout,
3223 erase_timeout, &pwd,
3226 warnx("Enhanced erase is not supported");
3230 warnx("Can't secure erase (enhanced), "
3231 "(security is disabled)");
3244 * Parse out a bus, or a bus, target and lun in the following
3250 * Returns the number of parsed components, or 0.
3253 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3254 cam_argmask *arglst)
3259 while (isspace(*tstr) && (*tstr != '\0'))
3262 tmpstr = (char *)strtok(tstr, ":");
3263 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3264 *bus = strtol(tmpstr, NULL, 0);
3265 *arglst |= CAM_ARG_BUS;
3267 tmpstr = (char *)strtok(NULL, ":");
3268 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3269 *target = strtol(tmpstr, NULL, 0);
3270 *arglst |= CAM_ARG_TARGET;
3272 tmpstr = (char *)strtok(NULL, ":");
3273 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3274 *lun = strtol(tmpstr, NULL, 0);
3275 *arglst |= CAM_ARG_LUN;
3285 dorescan_or_reset(int argc, char **argv, int rescan)
3287 static const char must[] =
3288 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3290 path_id_t bus = CAM_BUS_WILDCARD;
3291 target_id_t target = CAM_TARGET_WILDCARD;
3292 lun_id_t lun = CAM_LUN_WILDCARD;
3296 warnx(must, rescan? "rescan" : "reset");
3300 tstr = argv[optind];
3301 while (isspace(*tstr) && (*tstr != '\0'))
3303 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3304 arglist |= CAM_ARG_BUS;
3305 else if (isdigit(*tstr)) {
3306 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3307 if (rv != 1 && rv != 3) {
3308 warnx(must, rescan? "rescan" : "reset");
3318 * Note that resetting or rescanning a device used to
3319 * require a bus or bus:target:lun. This is because the
3320 * device in question may not exist and you're trying to
3321 * get the controller to rescan to find it. It may also be
3322 * because the device is hung / unresponsive, and opening
3323 * an unresponsive device is not desireable.
3325 * It can be more convenient to reference a device by
3326 * peripheral name and unit number, though, and it is
3327 * possible to get the bus:target:lun for devices that
3328 * currently exist in the EDT. So this can work for
3329 * devices that we want to reset, or devices that exist
3330 * that we want to rescan, but not devices that do not
3333 * So, we are careful here to look up the bus/target/lun
3334 * for the device the user wants to operate on, specified
3335 * by peripheral instance (e.g. da0, pass32) without
3336 * actually opening that device. The process is similar to
3337 * what cam_lookup_pass() does, except that we don't
3338 * actually open the passthrough driver instance in the end.
3341 if (cam_get_device(tstr, name, sizeof(name), &unit) == -1) {
3342 warnx("%s", cam_errbuf);
3347 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3348 warn("Unable to open %s", XPT_DEVICE);
3353 bzero(&ccb, sizeof(ccb));
3356 * The function code isn't strictly necessary for the
3357 * GETPASSTHRU ioctl.
3359 ccb.ccb_h.func_code = XPT_GDEVLIST;
3362 * These two are necessary for the GETPASSTHRU ioctl to
3365 strlcpy(ccb.cgdl.periph_name, name,
3366 sizeof(ccb.cgdl.periph_name));
3367 ccb.cgdl.unit_number = unit;
3370 * Attempt to get the passthrough device. This ioctl will
3371 * fail if the device name is null, if the device doesn't
3372 * exist, or if the passthrough driver isn't in the kernel.
3374 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3375 warn("Unable to find bus:target:lun for device %s%d",
3381 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3382 const struct cam_status_entry *entry;
3384 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3385 warnx("Unable to find bus:target_lun for device %s%d, "
3386 "CAM status: %s (%#x)", name, unit,
3387 entry ? entry->status_text : "Unknown",
3395 * The kernel fills in the bus/target/lun. We don't
3396 * need the passthrough device name and unit number since
3397 * we aren't going to open it.
3399 bus = ccb.ccb_h.path_id;
3400 target = ccb.ccb_h.target_id;
3401 lun = ccb.ccb_h.target_lun;
3403 arglist |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3408 if ((arglist & CAM_ARG_BUS)
3409 && (arglist & CAM_ARG_TARGET)
3410 && (arglist & CAM_ARG_LUN))
3411 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3413 error = rescan_or_reset_bus(bus, rescan);
3421 rescan_or_reset_bus(path_id_t bus, int rescan)
3423 union ccb *ccb = NULL, *matchccb = NULL;
3424 int fd = -1, retval;
3429 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3430 warnx("error opening transport layer device %s", XPT_DEVICE);
3431 warn("%s", XPT_DEVICE);
3435 ccb = malloc(sizeof(*ccb));
3437 warn("failed to allocate CCB");
3441 bzero(ccb, sizeof(*ccb));
3443 if (bus != CAM_BUS_WILDCARD) {
3444 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3445 ccb->ccb_h.path_id = bus;
3446 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3447 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3448 ccb->crcn.flags = CAM_FLAG_NONE;
3450 /* run this at a low priority */
3451 ccb->ccb_h.pinfo.priority = 5;
3453 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3454 warn("CAMIOCOMMAND ioctl failed");
3459 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3460 fprintf(stdout, "%s of bus %d was successful\n",
3461 rescan ? "Re-scan" : "Reset", bus);
3463 fprintf(stdout, "%s of bus %d returned error %#x\n",
3464 rescan ? "Re-scan" : "Reset", bus,
3465 ccb->ccb_h.status & CAM_STATUS_MASK);
3474 * The right way to handle this is to modify the xpt so that it can
3475 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3476 * that isn't implemented, so instead we enumerate the buses and
3477 * send the rescan or reset to those buses in the case where the
3478 * given bus is -1 (wildcard). We don't send a rescan or reset
3479 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3480 * no-op, sending a rescan to the xpt bus would result in a status of
3483 matchccb = malloc(sizeof(*matchccb));
3484 if (matchccb == NULL) {
3485 warn("failed to allocate CCB");
3489 bzero(matchccb, sizeof(*matchccb));
3490 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3491 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3492 bufsize = sizeof(struct dev_match_result) * 20;
3493 matchccb->cdm.match_buf_len = bufsize;
3494 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3495 if (matchccb->cdm.matches == NULL) {
3496 warnx("can't malloc memory for matches");
3500 matchccb->cdm.num_matches = 0;
3502 matchccb->cdm.num_patterns = 1;
3503 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3505 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3506 matchccb->cdm.pattern_buf_len);
3507 if (matchccb->cdm.patterns == NULL) {
3508 warnx("can't malloc memory for patterns");
3512 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3513 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3518 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3519 warn("CAMIOCOMMAND ioctl failed");
3524 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3525 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3526 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3527 warnx("got CAM error %#x, CDM error %d\n",
3528 matchccb->ccb_h.status, matchccb->cdm.status);
3533 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3534 struct bus_match_result *bus_result;
3536 /* This shouldn't happen. */
3537 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3540 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3543 * We don't want to rescan or reset the xpt bus.
3546 if (bus_result->path_id == CAM_XPT_PATH_ID)
3549 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3551 ccb->ccb_h.path_id = bus_result->path_id;
3552 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3553 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3554 ccb->crcn.flags = CAM_FLAG_NONE;
3556 /* run this at a low priority */
3557 ccb->ccb_h.pinfo.priority = 5;
3559 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3560 warn("CAMIOCOMMAND ioctl failed");
3565 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3566 fprintf(stdout, "%s of bus %d was successful\n",
3567 rescan? "Re-scan" : "Reset",
3568 bus_result->path_id);
3571 * Don't bail out just yet, maybe the other
3572 * rescan or reset commands will complete
3575 fprintf(stderr, "%s of bus %d returned error "
3576 "%#x\n", rescan? "Re-scan" : "Reset",
3577 bus_result->path_id,
3578 ccb->ccb_h.status & CAM_STATUS_MASK);
3582 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3583 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3590 if (matchccb != NULL) {
3591 free(matchccb->cdm.patterns);
3592 free(matchccb->cdm.matches);
3601 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3604 struct cam_device *device;
3609 if (bus == CAM_BUS_WILDCARD) {
3610 warnx("invalid bus number %d", bus);
3614 if (target == CAM_TARGET_WILDCARD) {
3615 warnx("invalid target number %d", target);
3619 if (lun == CAM_LUN_WILDCARD) {
3620 warnx("invalid lun number %jx", (uintmax_t)lun);
3626 bzero(&ccb, sizeof(union ccb));
3629 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3630 warnx("error opening transport layer device %s\n",
3632 warn("%s", XPT_DEVICE);
3636 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3637 if (device == NULL) {
3638 warnx("%s", cam_errbuf);
3643 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3644 ccb.ccb_h.path_id = bus;
3645 ccb.ccb_h.target_id = target;
3646 ccb.ccb_h.target_lun = lun;
3647 ccb.ccb_h.timeout = 5000;
3648 ccb.crcn.flags = CAM_FLAG_NONE;
3650 /* run this at a low priority */
3651 ccb.ccb_h.pinfo.priority = 5;
3654 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3655 warn("CAMIOCOMMAND ioctl failed");
3660 if (cam_send_ccb(device, &ccb) < 0) {
3661 warn("error sending XPT_RESET_DEV CCB");
3662 cam_close_device(device);
3670 cam_close_device(device);
3673 * An error code of CAM_BDR_SENT is normal for a BDR request.
3675 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3677 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3678 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3679 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3682 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3683 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3684 ccb.ccb_h.status & CAM_STATUS_MASK);
3690 static struct scsi_nv defect_list_type_map[] = {
3691 { "block", SRDD10_BLOCK_FORMAT },
3692 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3693 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3694 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3695 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3696 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3700 readdefects(struct cam_device *device, int argc, char **argv,
3701 char *combinedopt, int task_attr, int retry_count, int timeout)
3703 union ccb *ccb = NULL;
3704 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3705 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3706 size_t hdr_size = 0, entry_size = 0;
3709 u_int8_t *defect_list = NULL;
3710 u_int8_t list_format = 0;
3711 int list_type_set = 0;
3712 u_int32_t dlist_length = 0;
3713 u_int32_t returned_length = 0, valid_len = 0;
3714 u_int32_t num_returned = 0, num_valid = 0;
3715 u_int32_t max_possible_size = 0, hdr_max = 0;
3716 u_int32_t starting_offset = 0;
3717 u_int8_t returned_format, returned_type;
3719 int summary = 0, quiet = 0;
3721 int lists_specified = 0;
3722 int get_length = 1, first_pass = 1;
3725 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3729 scsi_nv_status status;
3732 status = scsi_get_nv(defect_list_type_map,
3733 sizeof(defect_list_type_map) /
3734 sizeof(defect_list_type_map[0]), optarg,
3735 &entry_num, SCSI_NV_FLAG_IG_CASE);
3737 if (status == SCSI_NV_FOUND) {
3738 list_format = defect_list_type_map[
3742 warnx("%s: %s %s option %s", __func__,
3743 (status == SCSI_NV_AMBIGUOUS) ?
3744 "ambiguous" : "invalid", "defect list type",
3747 goto defect_bailout;
3752 arglist |= CAM_ARG_GLIST;
3755 arglist |= CAM_ARG_PLIST;
3766 starting_offset = strtoul(optarg, &endptr, 0);
3767 if (*endptr != '\0') {
3769 warnx("invalid starting offset %s", optarg);
3770 goto defect_bailout;
3782 if (list_type_set == 0) {
3784 warnx("no defect list format specified");
3785 goto defect_bailout;
3788 if (arglist & CAM_ARG_PLIST) {
3789 list_format |= SRDD10_PLIST;
3793 if (arglist & CAM_ARG_GLIST) {
3794 list_format |= SRDD10_GLIST;
3799 * This implies a summary, and was the previous behavior.
3801 if (lists_specified == 0)
3804 ccb = cam_getccb(device);
3809 * We start off asking for just the header to determine how much
3810 * defect data is available. Some Hitachi drives return an error
3811 * if you ask for more data than the drive has. Once we know the
3812 * length, we retry the command with the returned length.
3814 if (use_12byte == 0)
3815 dlist_length = sizeof(*hdr10);
3817 dlist_length = sizeof(*hdr12);
3820 if (defect_list != NULL) {
3824 defect_list = malloc(dlist_length);
3825 if (defect_list == NULL) {
3826 warnx("can't malloc memory for defect list");
3828 goto defect_bailout;
3832 bzero(defect_list, dlist_length);
3835 * cam_getccb() zeros the CCB header only. So we need to zero the
3836 * payload portion of the ccb.
3838 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3840 scsi_read_defects(&ccb->csio,
3841 /*retries*/ retry_count,
3843 /*tag_action*/ task_attr,
3844 /*list_format*/ list_format,
3845 /*addr_desc_index*/ starting_offset,
3846 /*data_ptr*/ defect_list,
3847 /*dxfer_len*/ dlist_length,
3848 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3849 /*sense_len*/ SSD_FULL_SIZE,
3850 /*timeout*/ timeout ? timeout : 5000);
3852 /* Disable freezing the device queue */
3853 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3855 if (cam_send_ccb(device, ccb) < 0) {
3856 perror("error reading defect list");
3858 if (arglist & CAM_ARG_VERBOSE) {
3859 cam_error_print(device, ccb, CAM_ESF_ALL,
3860 CAM_EPF_ALL, stderr);
3864 goto defect_bailout;
3867 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3869 if (use_12byte == 0) {
3870 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3871 hdr_size = sizeof(*hdr10);
3872 hdr_max = SRDDH10_MAX_LENGTH;
3874 if (valid_len >= hdr_size) {
3875 returned_length = scsi_2btoul(hdr10->length);
3876 returned_format = hdr10->format;
3878 returned_length = 0;
3879 returned_format = 0;
3882 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3883 hdr_size = sizeof(*hdr12);
3884 hdr_max = SRDDH12_MAX_LENGTH;
3886 if (valid_len >= hdr_size) {
3887 returned_length = scsi_4btoul(hdr12->length);
3888 returned_format = hdr12->format;
3890 returned_length = 0;
3891 returned_format = 0;
3895 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3896 switch (returned_type) {
3897 case SRDD10_BLOCK_FORMAT:
3898 entry_size = sizeof(struct scsi_defect_desc_block);
3900 case SRDD10_LONG_BLOCK_FORMAT:
3901 entry_size = sizeof(struct scsi_defect_desc_long_block);
3903 case SRDD10_EXT_PHYS_FORMAT:
3904 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3905 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3907 case SRDD10_EXT_BFI_FORMAT:
3908 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3909 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3912 warnx("Unknown defect format 0x%x\n", returned_type);
3914 goto defect_bailout;
3918 max_possible_size = (hdr_max / entry_size) * entry_size;
3919 num_returned = returned_length / entry_size;
3920 num_valid = min(returned_length, valid_len - hdr_size);
3921 num_valid /= entry_size;
3923 if (get_length != 0) {
3926 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3927 CAM_SCSI_STATUS_ERROR) {
3928 struct scsi_sense_data *sense;
3929 int error_code, sense_key, asc, ascq;
3931 sense = &ccb->csio.sense_data;
3932 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3933 ccb->csio.sense_resid, &error_code, &sense_key,
3934 &asc, &ascq, /*show_errors*/ 1);
3937 * If the drive is reporting that it just doesn't
3938 * support the defect list format, go ahead and use
3939 * the length it reported. Otherwise, the length
3940 * may not be valid, so use the maximum.
3942 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3943 && (asc == 0x1c) && (ascq == 0x00)
3944 && (returned_length > 0)) {
3945 if ((use_12byte == 0)
3946 && (returned_length >= max_possible_size)) {
3951 dlist_length = returned_length + hdr_size;
3952 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3953 && (asc == 0x1f) && (ascq == 0x00)
3954 && (returned_length > 0)) {
3955 /* Partial defect list transfer */
3957 * Hitachi drives return this error
3958 * along with a partial defect list if they
3959 * have more defects than the 10 byte
3960 * command can support. Retry with the 12
3963 if (use_12byte == 0) {
3968 dlist_length = returned_length + hdr_size;
3969 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
3970 && (asc == 0x24) && (ascq == 0x00)) {
3971 /* Invalid field in CDB */
3973 * SBC-3 says that if the drive has more
3974 * defects than can be reported with the
3975 * 10 byte command, it should return this
3976 * error and no data. Retry with the 12
3979 if (use_12byte == 0) {
3984 dlist_length = returned_length + hdr_size;
3987 * If we got a SCSI error and no valid length,
3988 * just use the 10 byte maximum. The 12
3989 * byte maximum is too large.
3991 if (returned_length == 0)
3992 dlist_length = SRDD10_MAX_LENGTH;
3994 if ((use_12byte == 0)
3995 && (returned_length >=
3996 max_possible_size)) {
4001 dlist_length = returned_length +
4005 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4008 warnx("Error reading defect header");
4009 if (arglist & CAM_ARG_VERBOSE)
4010 cam_error_print(device, ccb, CAM_ESF_ALL,
4011 CAM_EPF_ALL, stderr);
4012 goto defect_bailout;
4014 if ((use_12byte == 0)
4015 && (returned_length >= max_possible_size)) {
4020 dlist_length = returned_length + hdr_size;
4023 fprintf(stdout, "%u", num_returned);
4025 fprintf(stdout, " defect%s",
4026 (num_returned != 1) ? "s" : "");
4028 fprintf(stdout, "\n");
4030 goto defect_bailout;
4034 * We always limit the list length to the 10-byte maximum
4035 * length (0xffff). The reason is that some controllers
4036 * can't handle larger I/Os, and we can transfer the entire
4037 * 10 byte list in one shot. For drives that support the 12
4038 * byte read defects command, we'll step through the list
4039 * by specifying a starting offset. For drives that don't
4040 * support the 12 byte command's starting offset, we'll
4041 * just display the first 64K.
4043 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4049 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4050 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4051 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4052 struct scsi_sense_data *sense;
4053 int error_code, sense_key, asc, ascq;
4055 sense = &ccb->csio.sense_data;
4056 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4057 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4058 &ascq, /*show_errors*/ 1);
4061 * According to the SCSI spec, if the disk doesn't support
4062 * the requested format, it will generally return a sense
4063 * key of RECOVERED ERROR, and an additional sense code
4064 * of "DEFECT LIST NOT FOUND". HGST drives also return
4065 * Primary/Grown defect list not found errors. So just
4066 * check for an ASC of 0x1c.
4068 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4070 const char *format_str;
4072 format_str = scsi_nv_to_str(defect_list_type_map,
4073 sizeof(defect_list_type_map) /
4074 sizeof(defect_list_type_map[0]),
4075 list_format & SRDD10_DLIST_FORMAT_MASK);
4076 warnx("requested defect format %s not available",
4077 format_str ? format_str : "unknown");
4079 format_str = scsi_nv_to_str(defect_list_type_map,
4080 sizeof(defect_list_type_map) /
4081 sizeof(defect_list_type_map[0]), returned_type);
4082 if (format_str != NULL) {
4083 warnx("Device returned %s format",
4087 warnx("Device returned unknown defect"
4088 " data format %#x", returned_type);
4089 goto defect_bailout;
4093 warnx("Error returned from read defect data command");
4094 if (arglist & CAM_ARG_VERBOSE)
4095 cam_error_print(device, ccb, CAM_ESF_ALL,
4096 CAM_EPF_ALL, stderr);
4097 goto defect_bailout;
4099 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4101 warnx("Error returned from read defect data command");
4102 if (arglist & CAM_ARG_VERBOSE)
4103 cam_error_print(device, ccb, CAM_ESF_ALL,
4104 CAM_EPF_ALL, stderr);
4105 goto defect_bailout;
4108 if (first_pass != 0) {
4109 fprintf(stderr, "Got %d defect", num_returned);
4111 if ((lists_specified == 0) || (num_returned == 0)) {
4112 fprintf(stderr, "s.\n");
4113 goto defect_bailout;
4114 } else if (num_returned == 1)
4115 fprintf(stderr, ":\n");
4117 fprintf(stderr, "s:\n");
4123 * XXX KDM I should probably clean up the printout format for the
4126 switch (returned_type) {
4127 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4128 case SRDD10_EXT_PHYS_FORMAT:
4130 struct scsi_defect_desc_phys_sector *dlist;
4132 dlist = (struct scsi_defect_desc_phys_sector *)
4133 (defect_list + hdr_size);
4135 for (i = 0; i < num_valid; i++) {
4138 sector = scsi_4btoul(dlist[i].sector);
4139 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4140 mads = (sector & SDD_EXT_PHYS_MADS) ?
4142 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4144 if (hex_format == 0)
4145 fprintf(stdout, "%d:%d:%d%s",
4146 scsi_3btoul(dlist[i].cylinder),
4148 scsi_4btoul(dlist[i].sector),
4149 mads ? " - " : "\n");
4151 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4152 scsi_3btoul(dlist[i].cylinder),
4154 scsi_4btoul(dlist[i].sector),
4155 mads ? " - " : "\n");
4158 if (num_valid < num_returned) {
4159 starting_offset += num_valid;
4164 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4165 case SRDD10_EXT_BFI_FORMAT:
4167 struct scsi_defect_desc_bytes_from_index *dlist;
4169 dlist = (struct scsi_defect_desc_bytes_from_index *)
4170 (defect_list + hdr_size);
4172 for (i = 0; i < num_valid; i++) {
4175 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4176 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4177 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4178 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4180 if (hex_format == 0)
4181 fprintf(stdout, "%d:%d:%d%s",
4182 scsi_3btoul(dlist[i].cylinder),
4184 scsi_4btoul(dlist[i].bytes_from_index),
4185 mads ? " - " : "\n");
4187 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4188 scsi_3btoul(dlist[i].cylinder),
4190 scsi_4btoul(dlist[i].bytes_from_index),
4191 mads ? " - " : "\n");
4195 if (num_valid < num_returned) {
4196 starting_offset += num_valid;
4201 case SRDDH10_BLOCK_FORMAT:
4203 struct scsi_defect_desc_block *dlist;
4205 dlist = (struct scsi_defect_desc_block *)
4206 (defect_list + hdr_size);
4208 for (i = 0; i < num_valid; i++) {
4209 if (hex_format == 0)
4210 fprintf(stdout, "%u\n",
4211 scsi_4btoul(dlist[i].address));
4213 fprintf(stdout, "0x%x\n",
4214 scsi_4btoul(dlist[i].address));
4217 if (num_valid < num_returned) {
4218 starting_offset += num_valid;
4224 case SRDD10_LONG_BLOCK_FORMAT:
4226 struct scsi_defect_desc_long_block *dlist;
4228 dlist = (struct scsi_defect_desc_long_block *)
4229 (defect_list + hdr_size);
4231 for (i = 0; i < num_valid; i++) {
4232 if (hex_format == 0)
4233 fprintf(stdout, "%ju\n",
4234 (uintmax_t)scsi_8btou64(
4237 fprintf(stdout, "0x%jx\n",
4238 (uintmax_t)scsi_8btou64(
4242 if (num_valid < num_returned) {
4243 starting_offset += num_valid;
4249 fprintf(stderr, "Unknown defect format 0x%x\n",
4256 if (defect_list != NULL)
4267 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4271 ccb = cam_getccb(device);
4278 mode_sense(struct cam_device *device, int dbd, int pc, int page, int subpage,
4279 int task_attr, int retry_count, int timeout, u_int8_t *data,
4285 ccb = cam_getccb(device);
4288 errx(1, "mode_sense: couldn't allocate CCB");
4290 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4292 scsi_mode_sense_subpage(&ccb->csio,
4293 /* retries */ retry_count,
4295 /* tag_action */ task_attr,
4299 /* subpage */ subpage,
4300 /* param_buf */ data,
4301 /* param_len */ datalen,
4302 /* minimum_cmd_size */ 0,
4303 /* sense_len */ SSD_FULL_SIZE,
4304 /* timeout */ timeout ? timeout : 5000);
4306 if (arglist & CAM_ARG_ERR_RECOVER)
4307 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4309 /* Disable freezing the device queue */
4310 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4312 if (((retval = cam_send_ccb(device, ccb)) < 0)
4313 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4314 if (arglist & CAM_ARG_VERBOSE) {
4315 cam_error_print(device, ccb, CAM_ESF_ALL,
4316 CAM_EPF_ALL, stderr);
4319 cam_close_device(device);
4321 err(1, "error sending mode sense command");
4323 errx(1, "error sending mode sense command");
4330 mode_select(struct cam_device *device, int save_pages, int task_attr,
4331 int retry_count, int timeout, u_int8_t *data, int datalen)
4336 ccb = cam_getccb(device);
4339 errx(1, "mode_select: couldn't allocate CCB");
4341 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4343 scsi_mode_select(&ccb->csio,
4344 /* retries */ retry_count,
4346 /* tag_action */ task_attr,
4347 /* scsi_page_fmt */ 1,
4348 /* save_pages */ save_pages,
4349 /* param_buf */ data,
4350 /* param_len */ datalen,
4351 /* sense_len */ SSD_FULL_SIZE,
4352 /* timeout */ timeout ? timeout : 5000);
4354 if (arglist & CAM_ARG_ERR_RECOVER)
4355 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4357 /* Disable freezing the device queue */
4358 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4360 if (((retval = cam_send_ccb(device, ccb)) < 0)
4361 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4362 if (arglist & CAM_ARG_VERBOSE) {
4363 cam_error_print(device, ccb, CAM_ESF_ALL,
4364 CAM_EPF_ALL, stderr);
4367 cam_close_device(device);
4370 err(1, "error sending mode select command");
4372 errx(1, "error sending mode select command");
4380 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4381 int task_attr, int retry_count, int timeout)
4384 int c, page = -1, subpage = -1, pc = 0;
4385 int binary = 0, dbd = 0, edit = 0, list = 0;
4387 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4402 str_subpage = optarg;
4403 strsep(&str_subpage, ",");
4404 page = strtol(optarg, NULL, 0);
4406 subpage = strtol(str_subpage, NULL, 0);
4410 errx(1, "invalid mode page %d", page);
4412 errx(1, "invalid mode subpage %d", subpage);
4415 pc = strtol(optarg, NULL, 0);
4416 if ((pc < 0) || (pc > 3))
4417 errx(1, "invalid page control field %d", pc);
4424 if (page == -1 && list == 0)
4425 errx(1, "you must specify a mode page!");
4428 mode_list(device, dbd, pc, list > 1, task_attr, retry_count,
4431 mode_edit(device, dbd, pc, page, subpage, edit, binary,
4432 task_attr, retry_count, timeout);
4437 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4438 int task_attr, int retry_count, int timeout)
4441 u_int32_t flags = CAM_DIR_NONE;
4442 u_int8_t *data_ptr = NULL;
4444 u_int8_t atacmd[12];
4445 struct get_hook hook;
4446 int c, data_bytes = 0, valid_bytes;
4452 char *datastr = NULL, *tstr, *resstr = NULL;
4454 int fd_data = 0, fd_res = 0;
4457 ccb = cam_getccb(device);
4460 warnx("scsicmd: error allocating ccb");
4464 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4466 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4470 while (isspace(*tstr) && (*tstr != '\0'))
4472 hook.argc = argc - optind;
4473 hook.argv = argv + optind;
4475 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4478 * Increment optind by the number of arguments the
4479 * encoding routine processed. After each call to
4480 * getopt(3), optind points to the argument that
4481 * getopt should process _next_. In this case,
4482 * that means it points to the first command string
4483 * argument, if there is one. Once we increment
4484 * this, it should point to either the next command
4485 * line argument, or it should be past the end of
4492 while (isspace(*tstr) && (*tstr != '\0'))
4494 hook.argc = argc - optind;
4495 hook.argv = argv + optind;
4497 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4500 * Increment optind by the number of arguments the
4501 * encoding routine processed. After each call to
4502 * getopt(3), optind points to the argument that
4503 * getopt should process _next_. In this case,
4504 * that means it points to the first command string
4505 * argument, if there is one. Once we increment
4506 * this, it should point to either the next command
4507 * line argument, or it should be past the end of
4519 if (arglist & CAM_ARG_CMD_OUT) {
4520 warnx("command must either be "
4521 "read or write, not both");
4523 goto scsicmd_bailout;
4525 arglist |= CAM_ARG_CMD_IN;
4527 data_bytes = strtol(optarg, NULL, 0);
4528 if (data_bytes <= 0) {
4529 warnx("invalid number of input bytes %d",
4532 goto scsicmd_bailout;
4534 hook.argc = argc - optind;
4535 hook.argv = argv + optind;
4538 datastr = cget(&hook, NULL);
4540 * If the user supplied "-" instead of a format, he
4541 * wants the data to be written to stdout.
4543 if ((datastr != NULL)
4544 && (datastr[0] == '-'))
4547 data_ptr = (u_int8_t *)malloc(data_bytes);
4548 if (data_ptr == NULL) {
4549 warnx("can't malloc memory for data_ptr");
4551 goto scsicmd_bailout;
4555 if (arglist & CAM_ARG_CMD_IN) {
4556 warnx("command must either be "
4557 "read or write, not both");
4559 goto scsicmd_bailout;
4561 arglist |= CAM_ARG_CMD_OUT;
4562 flags = CAM_DIR_OUT;
4563 data_bytes = strtol(optarg, NULL, 0);
4564 if (data_bytes <= 0) {
4565 warnx("invalid number of output bytes %d",
4568 goto scsicmd_bailout;
4570 hook.argc = argc - optind;
4571 hook.argv = argv + optind;
4573 datastr = cget(&hook, NULL);
4574 data_ptr = (u_int8_t *)malloc(data_bytes);
4575 if (data_ptr == NULL) {
4576 warnx("can't malloc memory for data_ptr");
4578 goto scsicmd_bailout;
4580 bzero(data_ptr, data_bytes);
4582 * If the user supplied "-" instead of a format, he
4583 * wants the data to be read from stdin.
4585 if ((datastr != NULL)
4586 && (datastr[0] == '-'))
4589 buff_encode_visit(data_ptr, data_bytes, datastr,
4595 hook.argc = argc - optind;
4596 hook.argv = argv + optind;
4598 resstr = cget(&hook, NULL);
4599 if ((resstr != NULL) && (resstr[0] == '-'))
4609 * If fd_data is set, and we're writing to the device, we need to
4610 * read the data the user wants written from stdin.
4612 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4614 int amt_to_read = data_bytes;
4615 u_int8_t *buf_ptr = data_ptr;
4617 for (amt_read = 0; amt_to_read > 0;
4618 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4619 if (amt_read == -1) {
4620 warn("error reading data from stdin");
4622 goto scsicmd_bailout;
4624 amt_to_read -= amt_read;
4625 buf_ptr += amt_read;
4629 if (arglist & CAM_ARG_ERR_RECOVER)
4630 flags |= CAM_PASS_ERR_RECOVER;
4632 /* Disable freezing the device queue */
4633 flags |= CAM_DEV_QFRZDIS;
4637 * This is taken from the SCSI-3 draft spec.
4638 * (T10/1157D revision 0.3)
4639 * The top 3 bits of an opcode are the group code.
4640 * The next 5 bits are the command code.
4641 * Group 0: six byte commands
4642 * Group 1: ten byte commands
4643 * Group 2: ten byte commands
4645 * Group 4: sixteen byte commands
4646 * Group 5: twelve byte commands
4647 * Group 6: vendor specific
4648 * Group 7: vendor specific
4650 switch((cdb[0] >> 5) & 0x7) {
4661 /* computed by buff_encode_visit */
4672 * We should probably use csio_build_visit or something like that
4673 * here, but it's easier to encode arguments as you go. The
4674 * alternative would be skipping the CDB argument and then encoding
4675 * it here, since we've got the data buffer argument by now.
4677 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4679 cam_fill_csio(&ccb->csio,
4680 /*retries*/ retry_count,
4683 /*tag_action*/ task_attr,
4684 /*data_ptr*/ data_ptr,
4685 /*dxfer_len*/ data_bytes,
4686 /*sense_len*/ SSD_FULL_SIZE,
4687 /*cdb_len*/ cdb_len,
4688 /*timeout*/ timeout ? timeout : 5000);
4691 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4693 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4695 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4697 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4699 cam_fill_ataio(&ccb->ataio,
4700 /*retries*/ retry_count,
4704 /*data_ptr*/ data_ptr,
4705 /*dxfer_len*/ data_bytes,
4706 /*timeout*/ timeout ? timeout : 5000);
4709 if (((retval = cam_send_ccb(device, ccb)) < 0)
4710 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4711 const char warnstr[] = "error sending command";
4718 if (arglist & CAM_ARG_VERBOSE) {
4719 cam_error_print(device, ccb, CAM_ESF_ALL,
4720 CAM_EPF_ALL, stderr);
4724 goto scsicmd_bailout;
4727 if (atacmd_len && need_res) {
4729 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4731 fprintf(stdout, "\n");
4734 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4735 ccb->ataio.res.status,
4736 ccb->ataio.res.error,
4737 ccb->ataio.res.lba_low,
4738 ccb->ataio.res.lba_mid,
4739 ccb->ataio.res.lba_high,
4740 ccb->ataio.res.device,
4741 ccb->ataio.res.lba_low_exp,
4742 ccb->ataio.res.lba_mid_exp,
4743 ccb->ataio.res.lba_high_exp,
4744 ccb->ataio.res.sector_count,
4745 ccb->ataio.res.sector_count_exp);
4751 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4753 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4754 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4755 && (arglist & CAM_ARG_CMD_IN)
4756 && (valid_bytes > 0)) {
4758 buff_decode_visit(data_ptr, valid_bytes, datastr,
4760 fprintf(stdout, "\n");
4762 ssize_t amt_written;
4763 int amt_to_write = valid_bytes;
4764 u_int8_t *buf_ptr = data_ptr;
4766 for (amt_written = 0; (amt_to_write > 0) &&
4767 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4768 amt_to_write -= amt_written;
4769 buf_ptr += amt_written;
4771 if (amt_written == -1) {
4772 warn("error writing data to stdout");
4774 goto scsicmd_bailout;
4775 } else if ((amt_written == 0)
4776 && (amt_to_write > 0)) {
4777 warnx("only wrote %u bytes out of %u",
4778 valid_bytes - amt_to_write, valid_bytes);
4785 if ((data_bytes > 0) && (data_ptr != NULL))
4794 camdebug(int argc, char **argv, char *combinedopt)
4797 path_id_t bus = CAM_BUS_WILDCARD;
4798 target_id_t target = CAM_TARGET_WILDCARD;
4799 lun_id_t lun = CAM_LUN_WILDCARD;
4800 char *tstr, *tmpstr = NULL;
4804 bzero(&ccb, sizeof(union ccb));
4806 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4809 arglist |= CAM_ARG_DEBUG_INFO;
4810 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4813 arglist |= CAM_ARG_DEBUG_PERIPH;
4814 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4817 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4818 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4821 arglist |= CAM_ARG_DEBUG_TRACE;
4822 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4825 arglist |= CAM_ARG_DEBUG_XPT;
4826 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4829 arglist |= CAM_ARG_DEBUG_CDB;
4830 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4833 arglist |= CAM_ARG_DEBUG_PROBE;
4834 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4841 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4842 warnx("error opening transport layer device %s", XPT_DEVICE);
4843 warn("%s", XPT_DEVICE);
4850 warnx("you must specify \"off\", \"all\" or a bus,");
4851 warnx("bus:target, or bus:target:lun");
4858 while (isspace(*tstr) && (*tstr != '\0'))
4861 if (strncmp(tstr, "off", 3) == 0) {
4862 ccb.cdbg.flags = CAM_DEBUG_NONE;
4863 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4864 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4865 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4866 } else if (strncmp(tstr, "all", 3) != 0) {
4867 tmpstr = (char *)strtok(tstr, ":");
4868 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4869 bus = strtol(tmpstr, NULL, 0);
4870 arglist |= CAM_ARG_BUS;
4871 tmpstr = (char *)strtok(NULL, ":");
4872 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4873 target = strtol(tmpstr, NULL, 0);
4874 arglist |= CAM_ARG_TARGET;
4875 tmpstr = (char *)strtok(NULL, ":");
4876 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4877 lun = strtol(tmpstr, NULL, 0);
4878 arglist |= CAM_ARG_LUN;
4883 warnx("you must specify \"all\", \"off\", or a bus,");
4884 warnx("bus:target, or bus:target:lun to debug");
4890 ccb.ccb_h.func_code = XPT_DEBUG;
4891 ccb.ccb_h.path_id = bus;
4892 ccb.ccb_h.target_id = target;
4893 ccb.ccb_h.target_lun = lun;
4895 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4896 warn("CAMIOCOMMAND ioctl failed");
4901 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4902 CAM_FUNC_NOTAVAIL) {
4903 warnx("CAM debugging not available");
4904 warnx("you need to put options CAMDEBUG in"
4905 " your kernel config file!");
4907 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4909 warnx("XPT_DEBUG CCB failed with status %#x",
4913 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4915 "Debugging turned off\n");
4918 "Debugging enabled for "
4920 bus, target, (uintmax_t)lun);
4931 tagcontrol(struct cam_device *device, int argc, char **argv,
4941 ccb = cam_getccb(device);
4944 warnx("tagcontrol: error allocating ccb");
4948 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4951 numtags = strtol(optarg, NULL, 0);
4953 warnx("tag count %d is < 0", numtags);
4955 goto tagcontrol_bailout;
4966 cam_path_string(device, pathstr, sizeof(pathstr));
4969 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
4970 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4971 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4972 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4973 ccb->crs.openings = numtags;
4976 if (cam_send_ccb(device, ccb) < 0) {
4977 perror("error sending XPT_REL_SIMQ CCB");
4979 goto tagcontrol_bailout;
4982 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4983 warnx("XPT_REL_SIMQ CCB failed");
4984 cam_error_print(device, ccb, CAM_ESF_ALL,
4985 CAM_EPF_ALL, stderr);
4987 goto tagcontrol_bailout;
4992 fprintf(stdout, "%stagged openings now %d\n",
4993 pathstr, ccb->crs.openings);
4996 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
4998 ccb->ccb_h.func_code = XPT_GDEV_STATS;
5000 if (cam_send_ccb(device, ccb) < 0) {
5001 perror("error sending XPT_GDEV_STATS CCB");
5003 goto tagcontrol_bailout;
5006 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5007 warnx("XPT_GDEV_STATS CCB failed");
5008 cam_error_print(device, ccb, CAM_ESF_ALL,
5009 CAM_EPF_ALL, stderr);
5011 goto tagcontrol_bailout;
5014 if (arglist & CAM_ARG_VERBOSE) {
5015 fprintf(stdout, "%s", pathstr);
5016 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5017 fprintf(stdout, "%s", pathstr);
5018 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5019 fprintf(stdout, "%s", pathstr);
5020 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5021 fprintf(stdout, "%s", pathstr);
5022 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5023 fprintf(stdout, "%s", pathstr);
5024 fprintf(stdout, "held %d\n", ccb->cgds.held);
5025 fprintf(stdout, "%s", pathstr);
5026 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5027 fprintf(stdout, "%s", pathstr);
5028 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5031 fprintf(stdout, "%s", pathstr);
5032 fprintf(stdout, "device openings: ");
5034 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5035 ccb->cgds.dev_active);
5045 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5049 cam_path_string(device, pathstr, sizeof(pathstr));
5051 if (cts->transport == XPORT_SPI) {
5052 struct ccb_trans_settings_spi *spi =
5053 &cts->xport_specific.spi;
5055 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5057 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5060 if (spi->sync_offset != 0) {
5063 freq = scsi_calc_syncsrate(spi->sync_period);
5064 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5065 pathstr, freq / 1000, freq % 1000);
5069 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5070 fprintf(stdout, "%soffset: %d\n", pathstr,
5074 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5075 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5076 (0x01 << spi->bus_width) * 8);
5079 if (spi->valid & CTS_SPI_VALID_DISC) {
5080 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5081 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5082 "enabled" : "disabled");
5085 if (cts->transport == XPORT_FC) {
5086 struct ccb_trans_settings_fc *fc =
5087 &cts->xport_specific.fc;
5089 if (fc->valid & CTS_FC_VALID_WWNN)
5090 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5091 (long long) fc->wwnn);
5092 if (fc->valid & CTS_FC_VALID_WWPN)
5093 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5094 (long long) fc->wwpn);
5095 if (fc->valid & CTS_FC_VALID_PORT)
5096 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5097 if (fc->valid & CTS_FC_VALID_SPEED)
5098 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5099 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5101 if (cts->transport == XPORT_SAS) {
5102 struct ccb_trans_settings_sas *sas =
5103 &cts->xport_specific.sas;
5105 if (sas->valid & CTS_SAS_VALID_SPEED)
5106 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5107 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5109 if (cts->transport == XPORT_ATA) {
5110 struct ccb_trans_settings_pata *pata =
5111 &cts->xport_specific.ata;
5113 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5114 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5115 ata_mode2string(pata->mode));
5117 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5118 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5121 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5122 fprintf(stdout, "%sPIO transaction length: %d\n",
5123 pathstr, pata->bytecount);
5126 if (cts->transport == XPORT_SATA) {
5127 struct ccb_trans_settings_sata *sata =
5128 &cts->xport_specific.sata;
5130 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5131 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5134 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5135 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5136 ata_mode2string(sata->mode));
5138 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5139 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5142 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5143 fprintf(stdout, "%sPIO transaction length: %d\n",
5144 pathstr, sata->bytecount);
5146 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5147 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5150 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5151 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5154 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5155 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5159 if (cts->protocol == PROTO_ATA) {
5160 struct ccb_trans_settings_ata *ata=
5161 &cts->proto_specific.ata;
5163 if (ata->valid & CTS_ATA_VALID_TQ) {
5164 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5165 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5166 "enabled" : "disabled");
5169 if (cts->protocol == PROTO_SCSI) {
5170 struct ccb_trans_settings_scsi *scsi=
5171 &cts->proto_specific.scsi;
5173 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5174 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5175 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5176 "enabled" : "disabled");
5180 if (cts->protocol == PROTO_NVME) {
5181 struct ccb_trans_settings_nvme *nvmex =
5182 &cts->xport_specific.nvme;
5184 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5185 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5186 NVME_MAJOR(nvmex->spec),
5187 NVME_MINOR(nvmex->spec));
5189 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5190 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5191 nvmex->lanes, nvmex->max_lanes);
5192 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5193 nvmex->speed, nvmex->max_speed);
5200 * Get a path inquiry CCB for the specified device.
5203 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5208 ccb = cam_getccb(device);
5210 warnx("get_cpi: couldn't allocate CCB");
5213 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5214 ccb->ccb_h.func_code = XPT_PATH_INQ;
5215 if (cam_send_ccb(device, ccb) < 0) {
5216 warn("get_cpi: error sending Path Inquiry CCB");
5217 if (arglist & CAM_ARG_VERBOSE)
5218 cam_error_print(device, ccb, CAM_ESF_ALL,
5219 CAM_EPF_ALL, stderr);
5221 goto get_cpi_bailout;
5223 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5224 if (arglist & CAM_ARG_VERBOSE)
5225 cam_error_print(device, ccb, CAM_ESF_ALL,
5226 CAM_EPF_ALL, stderr);
5228 goto get_cpi_bailout;
5230 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5238 * Get a get device CCB for the specified device.
5241 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5246 ccb = cam_getccb(device);
5248 warnx("get_cgd: couldn't allocate CCB");
5251 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5252 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5253 if (cam_send_ccb(device, ccb) < 0) {
5254 warn("get_cgd: error sending Path Inquiry CCB");
5255 if (arglist & CAM_ARG_VERBOSE)
5256 cam_error_print(device, ccb, CAM_ESF_ALL,
5257 CAM_EPF_ALL, stderr);
5259 goto get_cgd_bailout;
5261 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5262 if (arglist & CAM_ARG_VERBOSE)
5263 cam_error_print(device, ccb, CAM_ESF_ALL,
5264 CAM_EPF_ALL, stderr);
5266 goto get_cgd_bailout;
5268 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5276 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5280 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5281 int timeout, int verbosemode)
5283 union ccb *ccb = NULL;
5284 struct scsi_vpd_supported_page_list sup_pages;
5288 ccb = cam_getccb(dev);
5290 warn("Unable to allocate CCB");
5295 /* cam_getccb cleans up the header, caller has to zero the payload */
5296 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5298 bzero(&sup_pages, sizeof(sup_pages));
5300 scsi_inquiry(&ccb->csio,
5301 /*retries*/ retry_count,
5303 /* tag_action */ MSG_SIMPLE_Q_TAG,
5304 /* inq_buf */ (u_int8_t *)&sup_pages,
5305 /* inq_len */ sizeof(sup_pages),
5307 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5308 /* sense_len */ SSD_FULL_SIZE,
5309 /* timeout */ timeout ? timeout : 5000);
5311 /* Disable freezing the device queue */
5312 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5314 if (retry_count != 0)
5315 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5317 if (cam_send_ccb(dev, ccb) < 0) {
5324 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5325 if (verbosemode != 0)
5326 cam_error_print(dev, ccb, CAM_ESF_ALL,
5327 CAM_EPF_ALL, stderr);
5332 for (i = 0; i < sup_pages.length; i++) {
5333 if (sup_pages.list[i] == page_id) {
5346 * devtype is filled in with the type of device.
5347 * Returns 0 for success, non-zero for failure.
5350 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5351 int verbosemode, camcontrol_devtype *devtype)
5353 struct ccb_getdev cgd;
5356 retval = get_cgd(dev, &cgd);
5360 switch (cgd.protocol) {
5366 *devtype = CC_DT_ATA;
5368 break; /*NOTREACHED*/
5370 *devtype = CC_DT_NVME;
5372 break; /*NOTREACHED*/
5374 *devtype = CC_DT_MMCSD;
5376 break; /*NOTREACHED*/
5378 *devtype = CC_DT_UNKNOWN;
5380 break; /*NOTREACHED*/
5384 * Check for the ATA Information VPD page (0x89). If this is an
5385 * ATA device behind a SCSI to ATA translation layer, this VPD page
5386 * should be present.
5388 * If that VPD page isn't present, or we get an error back from the
5389 * INQUIRY command, we'll just treat it as a normal SCSI device.
5391 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5392 timeout, verbosemode);
5394 *devtype = CC_DT_ATA_BEHIND_SCSI;
5396 *devtype = CC_DT_SCSI;
5405 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5406 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5407 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5408 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5409 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5410 int is48bit, camcontrol_devtype devtype)
5414 if (devtype == CC_DT_ATA) {
5415 cam_fill_ataio(&ccb->ataio,
5416 /*retries*/ retry_count,
5419 /*tag_action*/ tag_action,
5420 /*data_ptr*/ data_ptr,
5421 /*dxfer_len*/ dxfer_len,
5422 /*timeout*/ timeout);
5423 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5424 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5427 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5430 if (auxiliary != 0) {
5431 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5432 ccb->ataio.aux = auxiliary;
5435 if (ata_flags & AP_FLAG_CHK_COND)
5436 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5438 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5439 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5440 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5441 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5443 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5444 protocol |= AP_EXTEND;
5446 retval = scsi_ata_pass(&ccb->csio,
5447 /*retries*/ retry_count,
5450 /*tag_action*/ tag_action,
5451 /*protocol*/ protocol,
5452 /*ata_flags*/ ata_flags,
5453 /*features*/ features,
5454 /*sector_count*/ sector_count,
5456 /*command*/ command,
5459 /*auxiliary*/ auxiliary,
5461 /*data_ptr*/ data_ptr,
5462 /*dxfer_len*/ dxfer_len,
5463 /*cdb_storage*/ cdb_storage,
5464 /*cdb_storage_len*/ cdb_storage_len,
5465 /*minimum_cmd_size*/ 0,
5466 /*sense_len*/ sense_len,
5467 /*timeout*/ timeout);
5474 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5475 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5479 switch (ccb->ccb_h.func_code) {
5482 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5485 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5486 * or 16 byte, and need to see what
5488 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5489 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5491 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5492 if ((opcode != ATA_PASS_12)
5493 && (opcode != ATA_PASS_16)) {
5495 warnx("%s: unsupported opcode %02x", __func__, opcode);
5499 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5501 /* Note: the _ccb() variant returns 0 for an error */
5508 switch (error_code) {
5509 case SSD_DESC_CURRENT_ERROR:
5510 case SSD_DESC_DEFERRED_ERROR: {
5511 struct scsi_sense_data_desc *sense;
5512 struct scsi_sense_ata_ret_desc *desc;
5515 sense = (struct scsi_sense_data_desc *)
5516 &ccb->csio.sense_data;
5518 desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len -
5519 ccb->csio.sense_resid, SSD_DESC_ATA);
5520 if (desc_ptr == NULL) {
5521 cam_error_print(dev, ccb, CAM_ESF_ALL,
5522 CAM_EPF_ALL, stderr);
5526 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5528 *error = desc->error;
5529 *count = (desc->count_15_8 << 8) |
5531 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5532 ((uint64_t)desc->lba_39_32 << 32) |
5533 ((uint64_t)desc->lba_31_24 << 24) |
5534 (desc->lba_23_16 << 16) |
5535 (desc->lba_15_8 << 8) |
5537 *device = desc->device;
5538 *status = desc->status;
5541 * If the extend bit isn't set, the result is for a
5542 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5543 * command without the extend bit set. This means
5544 * that the device is supposed to return 28-bit
5545 * status. The count field is only 8 bits, and the
5546 * LBA field is only 8 bits.
5548 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5554 case SSD_CURRENT_ERROR:
5555 case SSD_DEFERRED_ERROR: {
5557 struct scsi_sense_data_fixed *sense;
5560 * XXX KDM need to support fixed sense data.
5562 warnx("%s: Fixed sense data not supported yet",
5566 break; /*NOTREACHED*/
5577 struct ata_res *res;
5580 * In this case, we have an ATA command, and we need to
5581 * fill in the requested values from the result register
5584 res = &ccb->ataio.res;
5585 *error = res->error;
5586 *status = res->status;
5587 *device = res->device;
5588 *count = res->sector_count;
5589 *lba = (res->lba_high << 16) |
5590 (res->lba_mid << 8) |
5592 if (res->flags & CAM_ATAIO_48BIT) {
5593 *count |= (res->sector_count_exp << 8);
5594 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5595 ((uint64_t)res->lba_mid_exp << 32) |
5596 ((uint64_t)res->lba_high_exp << 40);
5598 *lba |= (res->device & 0xf) << 24;
5611 cpi_print(struct ccb_pathinq *cpi)
5613 char adapter_str[1024];
5616 snprintf(adapter_str, sizeof(adapter_str),
5617 "%s%d:", cpi->dev_name, cpi->unit_number);
5619 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5622 for (i = 1; i < UINT8_MAX; i = i << 1) {
5625 if ((i & cpi->hba_inquiry) == 0)
5628 fprintf(stdout, "%s supports ", adapter_str);
5632 str = "MDP message";
5635 str = "32 bit wide SCSI";
5638 str = "16 bit wide SCSI";
5641 str = "SDTR message";
5644 str = "linked CDBs";
5647 str = "tag queue messages";
5650 str = "soft reset alternative";
5653 str = "SATA Port Multiplier";
5656 str = "unknown PI bit set";
5659 fprintf(stdout, "%s\n", str);
5662 for (i = 1; i < UINT32_MAX; i = i << 1) {
5665 if ((i & cpi->hba_misc) == 0)
5668 fprintf(stdout, "%s ", adapter_str);
5672 str = "can understand ata_ext requests";
5675 str = "64bit extended LUNs supported";
5678 str = "bus scans from high ID to low ID";
5681 str = "removable devices not included in scan";
5683 case PIM_NOINITIATOR:
5684 str = "initiator role not supported";
5686 case PIM_NOBUSRESET:
5687 str = "user has disabled initial BUS RESET or"
5688 " controller is in target/mixed mode";
5691 str = "do not send 6-byte commands";
5694 str = "scan bus sequentially";
5697 str = "unmapped I/O supported";
5700 str = "does its own scanning";
5703 str = "unknown PIM bit set";
5706 fprintf(stdout, "%s\n", str);
5709 for (i = 1; i < UINT16_MAX; i = i << 1) {
5712 if ((i & cpi->target_sprt) == 0)
5715 fprintf(stdout, "%s supports ", adapter_str);
5718 str = "target mode processor mode";
5721 str = "target mode phase cog. mode";
5723 case PIT_DISCONNECT:
5724 str = "disconnects in target mode";
5727 str = "terminate I/O message in target mode";
5730 str = "group 6 commands in target mode";
5733 str = "group 7 commands in target mode";
5736 str = "unknown PIT bit set";
5740 fprintf(stdout, "%s\n", str);
5742 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5744 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5746 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5748 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5749 adapter_str, cpi->hpath_id);
5750 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5752 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5753 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5754 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5755 adapter_str, cpi->hba_vendor);
5756 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5757 adapter_str, cpi->hba_device);
5758 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5759 adapter_str, cpi->hba_subvendor);
5760 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5761 adapter_str, cpi->hba_subdevice);
5762 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5763 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5764 if (cpi->base_transfer_speed > 1000)
5765 fprintf(stdout, "%d.%03dMB/sec\n",
5766 cpi->base_transfer_speed / 1000,
5767 cpi->base_transfer_speed % 1000);
5769 fprintf(stdout, "%dKB/sec\n",
5770 (cpi->base_transfer_speed % 1000) * 1000);
5771 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5772 adapter_str, cpi->maxio);
5776 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5777 struct ccb_trans_settings *cts)
5783 ccb = cam_getccb(device);
5786 warnx("get_print_cts: error allocating ccb");
5790 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5792 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5794 if (user_settings == 0)
5795 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5797 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5799 if (cam_send_ccb(device, ccb) < 0) {
5800 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5801 if (arglist & CAM_ARG_VERBOSE)
5802 cam_error_print(device, ccb, CAM_ESF_ALL,
5803 CAM_EPF_ALL, stderr);
5805 goto get_print_cts_bailout;
5808 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5809 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5810 if (arglist & CAM_ARG_VERBOSE)
5811 cam_error_print(device, ccb, CAM_ESF_ALL,
5812 CAM_EPF_ALL, stderr);
5814 goto get_print_cts_bailout;
5818 cts_print(device, &ccb->cts);
5821 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5823 get_print_cts_bailout:
5831 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
5832 int timeout, int argc, char **argv, char *combinedopt)
5836 int user_settings = 0;
5838 int disc_enable = -1, tag_enable = -1;
5841 double syncrate = -1;
5844 int change_settings = 0, send_tur = 0;
5845 struct ccb_pathinq cpi;
5847 ccb = cam_getccb(device);
5849 warnx("ratecontrol: error allocating ccb");
5852 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5861 if (strncasecmp(optarg, "enable", 6) == 0)
5863 else if (strncasecmp(optarg, "disable", 7) == 0)
5866 warnx("-D argument \"%s\" is unknown", optarg);
5868 goto ratecontrol_bailout;
5870 change_settings = 1;
5873 mode = ata_string2mode(optarg);
5875 warnx("unknown mode '%s'", optarg);
5877 goto ratecontrol_bailout;
5879 change_settings = 1;
5882 offset = strtol(optarg, NULL, 0);
5884 warnx("offset value %d is < 0", offset);
5886 goto ratecontrol_bailout;
5888 change_settings = 1;
5894 syncrate = atof(optarg);
5896 warnx("sync rate %f is < 0", syncrate);
5898 goto ratecontrol_bailout;
5900 change_settings = 1;
5903 if (strncasecmp(optarg, "enable", 6) == 0)
5905 else if (strncasecmp(optarg, "disable", 7) == 0)
5908 warnx("-T argument \"%s\" is unknown", optarg);
5910 goto ratecontrol_bailout;
5912 change_settings = 1;
5918 bus_width = strtol(optarg, NULL, 0);
5919 if (bus_width < 0) {
5920 warnx("bus width %d is < 0", bus_width);
5922 goto ratecontrol_bailout;
5924 change_settings = 1;
5930 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5932 * Grab path inquiry information, so we can determine whether
5933 * or not the initiator is capable of the things that the user
5936 ccb->ccb_h.func_code = XPT_PATH_INQ;
5937 if (cam_send_ccb(device, ccb) < 0) {
5938 perror("error sending XPT_PATH_INQ CCB");
5939 if (arglist & CAM_ARG_VERBOSE) {
5940 cam_error_print(device, ccb, CAM_ESF_ALL,
5941 CAM_EPF_ALL, stderr);
5944 goto ratecontrol_bailout;
5946 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5947 warnx("XPT_PATH_INQ CCB failed");
5948 if (arglist & CAM_ARG_VERBOSE) {
5949 cam_error_print(device, ccb, CAM_ESF_ALL,
5950 CAM_EPF_ALL, stderr);
5953 goto ratecontrol_bailout;
5955 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5956 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5958 fprintf(stdout, "%s parameters:\n",
5959 user_settings ? "User" : "Current");
5961 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5963 goto ratecontrol_bailout;
5965 if (arglist & CAM_ARG_VERBOSE)
5968 if (change_settings) {
5969 int didsettings = 0;
5970 struct ccb_trans_settings_spi *spi = NULL;
5971 struct ccb_trans_settings_pata *pata = NULL;
5972 struct ccb_trans_settings_sata *sata = NULL;
5973 struct ccb_trans_settings_ata *ata = NULL;
5974 struct ccb_trans_settings_scsi *scsi = NULL;
5976 if (ccb->cts.transport == XPORT_SPI)
5977 spi = &ccb->cts.xport_specific.spi;
5978 if (ccb->cts.transport == XPORT_ATA)
5979 pata = &ccb->cts.xport_specific.ata;
5980 if (ccb->cts.transport == XPORT_SATA)
5981 sata = &ccb->cts.xport_specific.sata;
5982 if (ccb->cts.protocol == PROTO_ATA)
5983 ata = &ccb->cts.proto_specific.ata;
5984 if (ccb->cts.protocol == PROTO_SCSI)
5985 scsi = &ccb->cts.proto_specific.scsi;
5986 ccb->cts.xport_specific.valid = 0;
5987 ccb->cts.proto_specific.valid = 0;
5988 if (spi && disc_enable != -1) {
5989 spi->valid |= CTS_SPI_VALID_DISC;
5990 if (disc_enable == 0)
5991 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5993 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5996 if (tag_enable != -1) {
5997 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5998 warnx("HBA does not support tagged queueing, "
5999 "so you cannot modify tag settings");
6001 goto ratecontrol_bailout;
6004 ata->valid |= CTS_SCSI_VALID_TQ;
6005 if (tag_enable == 0)
6006 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6008 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6011 scsi->valid |= CTS_SCSI_VALID_TQ;
6012 if (tag_enable == 0)
6013 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6015 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6019 if (spi && offset != -1) {
6020 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6021 warnx("HBA is not capable of changing offset");
6023 goto ratecontrol_bailout;
6025 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6026 spi->sync_offset = offset;
6029 if (spi && syncrate != -1) {
6030 int prelim_sync_period;
6032 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6033 warnx("HBA is not capable of changing "
6036 goto ratecontrol_bailout;
6038 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6040 * The sync rate the user gives us is in MHz.
6041 * We need to translate it into KHz for this
6046 * Next, we calculate a "preliminary" sync period
6047 * in tenths of a nanosecond.
6050 prelim_sync_period = 0;
6052 prelim_sync_period = 10000000 / syncrate;
6054 scsi_calc_syncparam(prelim_sync_period);
6057 if (sata && syncrate != -1) {
6058 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6059 warnx("HBA is not capable of changing "
6062 goto ratecontrol_bailout;
6064 if (!user_settings) {
6065 warnx("You can modify only user rate "
6066 "settings for SATA");
6068 goto ratecontrol_bailout;
6070 sata->revision = ata_speed2revision(syncrate * 100);
6071 if (sata->revision < 0) {
6072 warnx("Invalid rate %f", syncrate);
6074 goto ratecontrol_bailout;
6076 sata->valid |= CTS_SATA_VALID_REVISION;
6079 if ((pata || sata) && mode != -1) {
6080 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6081 warnx("HBA is not capable of changing "
6084 goto ratecontrol_bailout;
6086 if (!user_settings) {
6087 warnx("You can modify only user mode "
6088 "settings for ATA/SATA");
6090 goto ratecontrol_bailout;
6094 pata->valid |= CTS_ATA_VALID_MODE;
6097 sata->valid |= CTS_SATA_VALID_MODE;
6102 * The bus_width argument goes like this:
6106 * Therefore, if you shift the number of bits given on the
6107 * command line right by 4, you should get the correct
6110 if (spi && bus_width != -1) {
6112 * We might as well validate things here with a
6113 * decipherable error message, rather than what
6114 * will probably be an indecipherable error message
6115 * by the time it gets back to us.
6117 if ((bus_width == 16)
6118 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6119 warnx("HBA does not support 16 bit bus width");
6121 goto ratecontrol_bailout;
6122 } else if ((bus_width == 32)
6123 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6124 warnx("HBA does not support 32 bit bus width");
6126 goto ratecontrol_bailout;
6127 } else if ((bus_width != 8)
6128 && (bus_width != 16)
6129 && (bus_width != 32)) {
6130 warnx("Invalid bus width %d", bus_width);
6132 goto ratecontrol_bailout;
6134 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6135 spi->bus_width = bus_width >> 4;
6138 if (didsettings == 0) {
6139 goto ratecontrol_bailout;
6141 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6142 if (cam_send_ccb(device, ccb) < 0) {
6143 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
6144 if (arglist & CAM_ARG_VERBOSE) {
6145 cam_error_print(device, ccb, CAM_ESF_ALL,
6146 CAM_EPF_ALL, stderr);
6149 goto ratecontrol_bailout;
6151 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6152 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6153 if (arglist & CAM_ARG_VERBOSE) {
6154 cam_error_print(device, ccb, CAM_ESF_ALL,
6155 CAM_EPF_ALL, stderr);
6158 goto ratecontrol_bailout;
6162 retval = testunitready(device, task_attr, retry_count, timeout,
6163 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6165 * If the TUR didn't succeed, just bail.
6169 fprintf(stderr, "Test Unit Ready failed\n");
6170 goto ratecontrol_bailout;
6173 if ((change_settings || send_tur) && !quiet &&
6174 (ccb->cts.transport == XPORT_ATA ||
6175 ccb->cts.transport == XPORT_SATA || send_tur)) {
6176 fprintf(stdout, "New parameters:\n");
6177 retval = get_print_cts(device, user_settings, 0, NULL);
6180 ratecontrol_bailout:
6186 scsiformat(struct cam_device *device, int argc, char **argv,
6187 char *combinedopt, int task_attr, int retry_count, int timeout)
6191 int ycount = 0, quiet = 0;
6192 int error = 0, retval = 0;
6193 int use_timeout = 10800 * 1000;
6195 struct format_defect_list_header fh;
6196 u_int8_t *data_ptr = NULL;
6197 u_int32_t dxfer_len = 0;
6199 int num_warnings = 0;
6202 ccb = cam_getccb(device);
6205 warnx("scsiformat: error allocating ccb");
6209 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6211 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6232 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6233 "following device:\n");
6235 error = scsidoinquiry(device, argc, argv, combinedopt,
6236 task_attr, retry_count, timeout);
6239 warnx("scsiformat: error sending inquiry");
6240 goto scsiformat_bailout;
6245 if (!get_confirmation()) {
6247 goto scsiformat_bailout;
6252 use_timeout = timeout;
6255 fprintf(stdout, "Current format timeout is %d seconds\n",
6256 use_timeout / 1000);
6260 * If the user hasn't disabled questions and didn't specify a
6261 * timeout on the command line, ask them if they want the current
6265 && (timeout == 0)) {
6267 int new_timeout = 0;
6269 fprintf(stdout, "Enter new timeout in seconds or press\n"
6270 "return to keep the current timeout [%d] ",
6271 use_timeout / 1000);
6273 if (fgets(str, sizeof(str), stdin) != NULL) {
6275 new_timeout = atoi(str);
6278 if (new_timeout != 0) {
6279 use_timeout = new_timeout * 1000;
6280 fprintf(stdout, "Using new timeout value %d\n",
6281 use_timeout / 1000);
6286 * Keep this outside the if block below to silence any unused
6287 * variable warnings.
6289 bzero(&fh, sizeof(fh));
6292 * If we're in immediate mode, we've got to include the format
6295 if (immediate != 0) {
6296 fh.byte2 = FU_DLH_IMMED;
6297 data_ptr = (u_int8_t *)&fh;
6298 dxfer_len = sizeof(fh);
6299 byte2 = FU_FMT_DATA;
6300 } else if (quiet == 0) {
6301 fprintf(stdout, "Formatting...");
6305 scsi_format_unit(&ccb->csio,
6306 /* retries */ retry_count,
6308 /* tag_action */ task_attr,
6311 /* data_ptr */ data_ptr,
6312 /* dxfer_len */ dxfer_len,
6313 /* sense_len */ SSD_FULL_SIZE,
6314 /* timeout */ use_timeout);
6316 /* Disable freezing the device queue */
6317 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6319 if (arglist & CAM_ARG_ERR_RECOVER)
6320 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6322 if (((retval = cam_send_ccb(device, ccb)) < 0)
6323 || ((immediate == 0)
6324 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6325 const char errstr[] = "error sending format command";
6332 if (arglist & CAM_ARG_VERBOSE) {
6333 cam_error_print(device, ccb, CAM_ESF_ALL,
6334 CAM_EPF_ALL, stderr);
6337 goto scsiformat_bailout;
6341 * If we ran in non-immediate mode, we already checked for errors
6342 * above and printed out any necessary information. If we're in
6343 * immediate mode, we need to loop through and get status
6344 * information periodically.
6346 if (immediate == 0) {
6348 fprintf(stdout, "Format Complete\n");
6350 goto scsiformat_bailout;
6357 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6360 * There's really no need to do error recovery or
6361 * retries here, since we're just going to sit in a
6362 * loop and wait for the device to finish formatting.
6364 scsi_test_unit_ready(&ccb->csio,
6367 /* tag_action */ task_attr,
6368 /* sense_len */ SSD_FULL_SIZE,
6369 /* timeout */ 5000);
6371 /* Disable freezing the device queue */
6372 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6374 retval = cam_send_ccb(device, ccb);
6377 * If we get an error from the ioctl, bail out. SCSI
6378 * errors are expected.
6381 warn("error sending CAMIOCOMMAND ioctl");
6382 if (arglist & CAM_ARG_VERBOSE) {
6383 cam_error_print(device, ccb, CAM_ESF_ALL,
6384 CAM_EPF_ALL, stderr);
6387 goto scsiformat_bailout;
6390 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6392 if ((status != CAM_REQ_CMP)
6393 && (status == CAM_SCSI_STATUS_ERROR)
6394 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6395 struct scsi_sense_data *sense;
6396 int error_code, sense_key, asc, ascq;
6398 sense = &ccb->csio.sense_data;
6399 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6400 ccb->csio.sense_resid, &error_code, &sense_key,
6401 &asc, &ascq, /*show_errors*/ 1);
6404 * According to the SCSI-2 and SCSI-3 specs, a
6405 * drive that is in the middle of a format should
6406 * return NOT READY with an ASC of "logical unit
6407 * not ready, format in progress". The sense key
6408 * specific bytes will then be a progress indicator.
6410 if ((sense_key == SSD_KEY_NOT_READY)
6411 && (asc == 0x04) && (ascq == 0x04)) {
6414 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6415 ccb->csio.sense_resid, sks) == 0)
6418 u_int64_t percentage;
6420 val = scsi_2btoul(&sks[1]);
6421 percentage = 10000ull * val;
6424 "\rFormatting: %ju.%02u %% "
6426 (uintmax_t)(percentage /
6428 (unsigned)((percentage /
6432 } else if ((quiet == 0)
6433 && (++num_warnings <= 1)) {
6434 warnx("Unexpected SCSI Sense Key "
6435 "Specific value returned "
6437 scsi_sense_print(device, &ccb->csio,
6439 warnx("Unable to print status "
6440 "information, but format will "
6442 warnx("will exit when format is "
6447 warnx("Unexpected SCSI error during format");
6448 cam_error_print(device, ccb, CAM_ESF_ALL,
6449 CAM_EPF_ALL, stderr);
6451 goto scsiformat_bailout;
6454 } else if (status != CAM_REQ_CMP) {
6455 warnx("Unexpected CAM status %#x", status);
6456 if (arglist & CAM_ARG_VERBOSE)
6457 cam_error_print(device, ccb, CAM_ESF_ALL,
6458 CAM_EPF_ALL, stderr);
6460 goto scsiformat_bailout;
6463 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6466 fprintf(stdout, "\nFormat Complete\n");
6476 scsisanitize(struct cam_device *device, int argc, char **argv,
6477 char *combinedopt, int task_attr, int retry_count, int timeout)
6480 u_int8_t action = 0;
6482 int ycount = 0, quiet = 0;
6483 int error = 0, retval = 0;
6484 int use_timeout = 10800 * 1000;
6490 const char *pattern = NULL;
6491 u_int8_t *data_ptr = NULL;
6492 u_int32_t dxfer_len = 0;
6494 int num_warnings = 0;
6497 ccb = cam_getccb(device);
6500 warnx("scsisanitize: error allocating ccb");
6504 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6506 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6509 if (strcasecmp(optarg, "overwrite") == 0)
6510 action = SSZ_SERVICE_ACTION_OVERWRITE;
6511 else if (strcasecmp(optarg, "block") == 0)
6512 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6513 else if (strcasecmp(optarg, "crypto") == 0)
6514 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6515 else if (strcasecmp(optarg, "exitfailure") == 0)
6516 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6518 warnx("invalid service operation \"%s\"",
6521 goto scsisanitize_bailout;
6525 passes = strtol(optarg, NULL, 0);
6526 if (passes < 1 || passes > 31) {
6527 warnx("invalid passes value %d", passes);
6529 goto scsisanitize_bailout;
6560 warnx("an action is required");
6562 goto scsisanitize_bailout;
6563 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6564 struct scsi_sanitize_parameter_list *pl;
6568 if (pattern == NULL) {
6569 warnx("overwrite action requires -P argument");
6571 goto scsisanitize_bailout;
6573 fd = open(pattern, O_RDONLY);
6575 warn("cannot open pattern file %s", pattern);
6577 goto scsisanitize_bailout;
6579 if (fstat(fd, &sb) < 0) {
6580 warn("cannot stat pattern file %s", pattern);
6582 goto scsisanitize_bailout;
6585 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6586 warnx("pattern file size exceeds maximum value %d",
6587 SSZPL_MAX_PATTERN_LENGTH);
6589 goto scsisanitize_bailout;
6591 dxfer_len = sizeof(*pl) + sz;
6592 data_ptr = calloc(1, dxfer_len);
6593 if (data_ptr == NULL) {
6594 warnx("cannot allocate parameter list buffer");
6596 goto scsisanitize_bailout;
6599 amt = read(fd, data_ptr + sizeof(*pl), sz);
6601 warn("cannot read pattern file");
6603 goto scsisanitize_bailout;
6604 } else if (amt != sz) {
6605 warnx("short pattern file read");
6607 goto scsisanitize_bailout;
6610 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6616 pl->byte1 |= SSZPL_INVERT;
6617 scsi_ulto2b(sz, pl->length);
6623 else if (invert != 0)
6625 else if (pattern != NULL)
6630 warnx("%s argument only valid with overwrite "
6633 goto scsisanitize_bailout;
6638 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6639 "following device:\n");
6641 error = scsidoinquiry(device, argc, argv, combinedopt,
6642 task_attr, retry_count, timeout);
6645 warnx("scsisanitize: error sending inquiry");
6646 goto scsisanitize_bailout;
6651 if (!get_confirmation()) {
6653 goto scsisanitize_bailout;
6658 use_timeout = timeout;
6661 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6662 use_timeout / 1000);
6666 * If the user hasn't disabled questions and didn't specify a
6667 * timeout on the command line, ask them if they want the current
6671 && (timeout == 0)) {
6673 int new_timeout = 0;
6675 fprintf(stdout, "Enter new timeout in seconds or press\n"
6676 "return to keep the current timeout [%d] ",
6677 use_timeout / 1000);
6679 if (fgets(str, sizeof(str), stdin) != NULL) {
6681 new_timeout = atoi(str);
6684 if (new_timeout != 0) {
6685 use_timeout = new_timeout * 1000;
6686 fprintf(stdout, "Using new timeout value %d\n",
6687 use_timeout / 1000);
6693 byte2 |= SSZ_UNRESTRICTED_EXIT;
6697 scsi_sanitize(&ccb->csio,
6698 /* retries */ retry_count,
6700 /* tag_action */ task_attr,
6703 /* data_ptr */ data_ptr,
6704 /* dxfer_len */ dxfer_len,
6705 /* sense_len */ SSD_FULL_SIZE,
6706 /* timeout */ use_timeout);
6708 /* Disable freezing the device queue */
6709 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6711 if (arglist & CAM_ARG_ERR_RECOVER)
6712 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6714 if (cam_send_ccb(device, ccb) < 0) {
6715 warn("error sending sanitize command");
6717 goto scsisanitize_bailout;
6720 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6721 struct scsi_sense_data *sense;
6722 int error_code, sense_key, asc, ascq;
6724 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6725 CAM_SCSI_STATUS_ERROR) {
6726 sense = &ccb->csio.sense_data;
6727 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6728 ccb->csio.sense_resid, &error_code, &sense_key,
6729 &asc, &ascq, /*show_errors*/ 1);
6731 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6732 asc == 0x20 && ascq == 0x00)
6733 warnx("sanitize is not supported by "
6736 warnx("error sanitizing this device");
6738 warnx("error sanitizing this device");
6740 if (arglist & CAM_ARG_VERBOSE) {
6741 cam_error_print(device, ccb, CAM_ESF_ALL,
6742 CAM_EPF_ALL, stderr);
6745 goto scsisanitize_bailout;
6749 * If we ran in non-immediate mode, we already checked for errors
6750 * above and printed out any necessary information. If we're in
6751 * immediate mode, we need to loop through and get status
6752 * information periodically.
6754 if (immediate == 0) {
6756 fprintf(stdout, "Sanitize Complete\n");
6758 goto scsisanitize_bailout;
6765 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6768 * There's really no need to do error recovery or
6769 * retries here, since we're just going to sit in a
6770 * loop and wait for the device to finish sanitizing.
6772 scsi_test_unit_ready(&ccb->csio,
6775 /* tag_action */ task_attr,
6776 /* sense_len */ SSD_FULL_SIZE,
6777 /* timeout */ 5000);
6779 /* Disable freezing the device queue */
6780 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6782 retval = cam_send_ccb(device, ccb);
6785 * If we get an error from the ioctl, bail out. SCSI
6786 * errors are expected.
6789 warn("error sending CAMIOCOMMAND ioctl");
6790 if (arglist & CAM_ARG_VERBOSE) {
6791 cam_error_print(device, ccb, CAM_ESF_ALL,
6792 CAM_EPF_ALL, stderr);
6795 goto scsisanitize_bailout;
6798 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6800 if ((status != CAM_REQ_CMP)
6801 && (status == CAM_SCSI_STATUS_ERROR)
6802 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6803 struct scsi_sense_data *sense;
6804 int error_code, sense_key, asc, ascq;
6806 sense = &ccb->csio.sense_data;
6807 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6808 ccb->csio.sense_resid, &error_code, &sense_key,
6809 &asc, &ascq, /*show_errors*/ 1);
6812 * According to the SCSI-3 spec, a drive that is in the
6813 * middle of a sanitize should return NOT READY with an
6814 * ASC of "logical unit not ready, sanitize in
6815 * progress". The sense key specific bytes will then
6816 * be a progress indicator.
6818 if ((sense_key == SSD_KEY_NOT_READY)
6819 && (asc == 0x04) && (ascq == 0x1b)) {
6822 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6823 ccb->csio.sense_resid, sks) == 0)
6826 u_int64_t percentage;
6828 val = scsi_2btoul(&sks[1]);
6829 percentage = 10000 * val;
6832 "\rSanitizing: %ju.%02u %% "
6834 (uintmax_t)(percentage /
6836 (unsigned)((percentage /
6840 } else if ((quiet == 0)
6841 && (++num_warnings <= 1)) {
6842 warnx("Unexpected SCSI Sense Key "
6843 "Specific value returned "
6844 "during sanitize:");
6845 scsi_sense_print(device, &ccb->csio,
6847 warnx("Unable to print status "
6848 "information, but sanitze will "
6850 warnx("will exit when sanitize is "
6855 warnx("Unexpected SCSI error during sanitize");
6856 cam_error_print(device, ccb, CAM_ESF_ALL,
6857 CAM_EPF_ALL, stderr);
6859 goto scsisanitize_bailout;
6862 } else if (status != CAM_REQ_CMP) {
6863 warnx("Unexpected CAM status %#x", status);
6864 if (arglist & CAM_ARG_VERBOSE)
6865 cam_error_print(device, ccb, CAM_ESF_ALL,
6866 CAM_EPF_ALL, stderr);
6868 goto scsisanitize_bailout;
6870 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6873 fprintf(stdout, "\nSanitize Complete\n");
6875 scsisanitize_bailout:
6878 if (data_ptr != NULL)
6886 scsireportluns(struct cam_device *device, int argc, char **argv,
6887 char *combinedopt, int task_attr, int retry_count, int timeout)
6890 int c, countonly, lunsonly;
6891 struct scsi_report_luns_data *lundata;
6893 uint8_t report_type;
6894 uint32_t list_len, i, j;
6899 report_type = RPL_REPORT_DEFAULT;
6900 ccb = cam_getccb(device);
6903 warnx("%s: error allocating ccb", __func__);
6907 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6912 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6921 if (strcasecmp(optarg, "default") == 0)
6922 report_type = RPL_REPORT_DEFAULT;
6923 else if (strcasecmp(optarg, "wellknown") == 0)
6924 report_type = RPL_REPORT_WELLKNOWN;
6925 else if (strcasecmp(optarg, "all") == 0)
6926 report_type = RPL_REPORT_ALL;
6928 warnx("%s: invalid report type \"%s\"",
6939 if ((countonly != 0)
6940 && (lunsonly != 0)) {
6941 warnx("%s: you can only specify one of -c or -l", __func__);
6946 * According to SPC-4, the allocation length must be at least 16
6947 * bytes -- enough for the header and one LUN.
6949 alloc_len = sizeof(*lundata) + 8;
6953 lundata = malloc(alloc_len);
6955 if (lundata == NULL) {
6956 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6961 scsi_report_luns(&ccb->csio,
6962 /*retries*/ retry_count,
6964 /*tag_action*/ task_attr,
6965 /*select_report*/ report_type,
6966 /*rpl_buf*/ lundata,
6967 /*alloc_len*/ alloc_len,
6968 /*sense_len*/ SSD_FULL_SIZE,
6969 /*timeout*/ timeout ? timeout : 5000);
6971 /* Disable freezing the device queue */
6972 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6974 if (arglist & CAM_ARG_ERR_RECOVER)
6975 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6977 if (cam_send_ccb(device, ccb) < 0) {
6978 warn("error sending REPORT LUNS command");
6980 if (arglist & CAM_ARG_VERBOSE)
6981 cam_error_print(device, ccb, CAM_ESF_ALL,
6982 CAM_EPF_ALL, stderr);
6988 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6989 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6995 list_len = scsi_4btoul(lundata->length);
6998 * If we need to list the LUNs, and our allocation
6999 * length was too short, reallocate and retry.
7001 if ((countonly == 0)
7002 && (list_len > (alloc_len - sizeof(*lundata)))) {
7003 alloc_len = list_len + sizeof(*lundata);
7009 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7010 ((list_len / 8) > 1) ? "s" : "");
7015 for (i = 0; i < (list_len / 8); i++) {
7019 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7021 fprintf(stdout, ",");
7022 switch (lundata->luns[i].lundata[j] &
7023 RPL_LUNDATA_ATYP_MASK) {
7024 case RPL_LUNDATA_ATYP_PERIPH:
7025 if ((lundata->luns[i].lundata[j] &
7026 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7027 fprintf(stdout, "%d:",
7028 lundata->luns[i].lundata[j] &
7029 RPL_LUNDATA_PERIPH_BUS_MASK);
7031 && ((lundata->luns[i].lundata[j+2] &
7032 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7035 fprintf(stdout, "%d",
7036 lundata->luns[i].lundata[j+1]);
7038 case RPL_LUNDATA_ATYP_FLAT: {
7040 tmplun[0] = lundata->luns[i].lundata[j] &
7041 RPL_LUNDATA_FLAT_LUN_MASK;
7042 tmplun[1] = lundata->luns[i].lundata[j+1];
7044 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7048 case RPL_LUNDATA_ATYP_LUN:
7049 fprintf(stdout, "%d:%d:%d",
7050 (lundata->luns[i].lundata[j+1] &
7051 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7052 lundata->luns[i].lundata[j] &
7053 RPL_LUNDATA_LUN_TARG_MASK,
7054 lundata->luns[i].lundata[j+1] &
7055 RPL_LUNDATA_LUN_LUN_MASK);
7057 case RPL_LUNDATA_ATYP_EXTLUN: {
7058 int field_len_code, eam_code;
7060 eam_code = lundata->luns[i].lundata[j] &
7061 RPL_LUNDATA_EXT_EAM_MASK;
7062 field_len_code = (lundata->luns[i].lundata[j] &
7063 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7065 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7066 && (field_len_code == 0x00)) {
7067 fprintf(stdout, "%d",
7068 lundata->luns[i].lundata[j+1]);
7069 } else if ((eam_code ==
7070 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7071 && (field_len_code == 0x03)) {
7075 * This format takes up all 8 bytes.
7076 * If we aren't starting at offset 0,
7080 fprintf(stdout, "Invalid "
7083 "specified format", j);
7087 bzero(tmp_lun, sizeof(tmp_lun));
7088 bcopy(&lundata->luns[i].lundata[j+1],
7089 &tmp_lun[1], sizeof(tmp_lun) - 1);
7090 fprintf(stdout, "%#jx",
7091 (intmax_t)scsi_8btou64(tmp_lun));
7094 fprintf(stderr, "Unknown Extended LUN"
7095 "Address method %#x, length "
7096 "code %#x", eam_code,
7103 fprintf(stderr, "Unknown LUN address method "
7104 "%#x\n", lundata->luns[i].lundata[0] &
7105 RPL_LUNDATA_ATYP_MASK);
7109 * For the flat addressing method, there are no
7110 * other levels after it.
7115 fprintf(stdout, "\n");
7128 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7129 char *combinedopt, int task_attr, int retry_count, int timeout)
7132 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7133 struct scsi_read_capacity_data rcap;
7134 struct scsi_read_capacity_data_long rcaplong;
7149 ccb = cam_getccb(device);
7152 warnx("%s: error allocating ccb", __func__);
7156 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7158 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7188 if ((blocksizeonly != 0)
7189 && (numblocks != 0)) {
7190 warnx("%s: you can only specify one of -b or -N", __func__);
7195 if ((blocksizeonly != 0)
7196 && (sizeonly != 0)) {
7197 warnx("%s: you can only specify one of -b or -s", __func__);
7204 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7210 && (blocksizeonly != 0)) {
7211 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7219 scsi_read_capacity(&ccb->csio,
7220 /*retries*/ retry_count,
7222 /*tag_action*/ task_attr,
7225 /*timeout*/ timeout ? timeout : 5000);
7227 /* Disable freezing the device queue */
7228 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7230 if (arglist & CAM_ARG_ERR_RECOVER)
7231 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7233 if (cam_send_ccb(device, ccb) < 0) {
7234 warn("error sending READ CAPACITY command");
7236 if (arglist & CAM_ARG_VERBOSE)
7237 cam_error_print(device, ccb, CAM_ESF_ALL,
7238 CAM_EPF_ALL, stderr);
7244 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7245 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7250 maxsector = scsi_4btoul(rcap.addr);
7251 block_len = scsi_4btoul(rcap.length);
7254 * A last block of 2^32-1 means that the true capacity is over 2TB,
7255 * and we need to issue the long READ CAPACITY to get the real
7256 * capacity. Otherwise, we're all set.
7258 if (maxsector != 0xffffffff)
7262 scsi_read_capacity_16(&ccb->csio,
7263 /*retries*/ retry_count,
7265 /*tag_action*/ task_attr,
7269 /*rcap_buf*/ (uint8_t *)&rcaplong,
7270 /*rcap_buf_len*/ sizeof(rcaplong),
7271 /*sense_len*/ SSD_FULL_SIZE,
7272 /*timeout*/ timeout ? timeout : 5000);
7274 /* Disable freezing the device queue */
7275 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7277 if (arglist & CAM_ARG_ERR_RECOVER)
7278 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7280 if (cam_send_ccb(device, ccb) < 0) {
7281 warn("error sending READ CAPACITY (16) command");
7283 if (arglist & CAM_ARG_VERBOSE)
7284 cam_error_print(device, ccb, CAM_ESF_ALL,
7285 CAM_EPF_ALL, stderr);
7291 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7292 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7297 maxsector = scsi_8btou64(rcaplong.addr);
7298 block_len = scsi_4btoul(rcaplong.length);
7301 if (blocksizeonly == 0) {
7303 * Humanize implies !quiet, and also implies numblocks.
7305 if (humanize != 0) {
7310 tmpbytes = (maxsector + 1) * block_len;
7311 ret = humanize_number(tmpstr, sizeof(tmpstr),
7312 tmpbytes, "", HN_AUTOSCALE,
7315 HN_DIVISOR_1000 : 0));
7317 warnx("%s: humanize_number failed!", __func__);
7321 fprintf(stdout, "Device Size: %s%s", tmpstr,
7322 (sizeonly == 0) ? ", " : "\n");
7323 } else if (numblocks != 0) {
7324 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7325 "Blocks: " : "", (uintmax_t)maxsector + 1,
7326 (sizeonly == 0) ? ", " : "\n");
7328 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7329 "Last Block: " : "", (uintmax_t)maxsector,
7330 (sizeonly == 0) ? ", " : "\n");
7334 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7335 "Block Length: " : "", block_len, (quiet == 0) ?
7344 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7345 int retry_count, int timeout)
7349 uint8_t *smp_request = NULL, *smp_response = NULL;
7350 int request_size = 0, response_size = 0;
7351 int fd_request = 0, fd_response = 0;
7352 char *datastr = NULL;
7353 struct get_hook hook;
7358 * Note that at the moment we don't support sending SMP CCBs to
7359 * devices that aren't probed by CAM.
7361 ccb = cam_getccb(device);
7363 warnx("%s: error allocating CCB", __func__);
7367 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7369 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7372 arglist |= CAM_ARG_CMD_IN;
7373 response_size = strtol(optarg, NULL, 0);
7374 if (response_size <= 0) {
7375 warnx("invalid number of response bytes %d",
7378 goto smpcmd_bailout;
7380 hook.argc = argc - optind;
7381 hook.argv = argv + optind;
7384 datastr = cget(&hook, NULL);
7386 * If the user supplied "-" instead of a format, he
7387 * wants the data to be written to stdout.
7389 if ((datastr != NULL)
7390 && (datastr[0] == '-'))
7393 smp_response = (u_int8_t *)malloc(response_size);
7394 if (smp_response == NULL) {
7395 warn("can't malloc memory for SMP response");
7397 goto smpcmd_bailout;
7401 arglist |= CAM_ARG_CMD_OUT;
7402 request_size = strtol(optarg, NULL, 0);
7403 if (request_size <= 0) {
7404 warnx("invalid number of request bytes %d",
7407 goto smpcmd_bailout;
7409 hook.argc = argc - optind;
7410 hook.argv = argv + optind;
7412 datastr = cget(&hook, NULL);
7413 smp_request = (u_int8_t *)malloc(request_size);
7414 if (smp_request == NULL) {
7415 warn("can't malloc memory for SMP request");
7417 goto smpcmd_bailout;
7419 bzero(smp_request, request_size);
7421 * If the user supplied "-" instead of a format, he
7422 * wants the data to be read from stdin.
7424 if ((datastr != NULL)
7425 && (datastr[0] == '-'))
7428 buff_encode_visit(smp_request, request_size,
7439 * If fd_data is set, and we're writing to the device, we need to
7440 * read the data the user wants written from stdin.
7442 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7444 int amt_to_read = request_size;
7445 u_int8_t *buf_ptr = smp_request;
7447 for (amt_read = 0; amt_to_read > 0;
7448 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7449 if (amt_read == -1) {
7450 warn("error reading data from stdin");
7452 goto smpcmd_bailout;
7454 amt_to_read -= amt_read;
7455 buf_ptr += amt_read;
7459 if (((arglist & CAM_ARG_CMD_IN) == 0)
7460 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7461 warnx("%s: need both the request (-r) and response (-R) "
7462 "arguments", __func__);
7464 goto smpcmd_bailout;
7467 flags |= CAM_DEV_QFRZDIS;
7469 cam_fill_smpio(&ccb->smpio,
7470 /*retries*/ retry_count,
7473 /*smp_request*/ smp_request,
7474 /*smp_request_len*/ request_size,
7475 /*smp_response*/ smp_response,
7476 /*smp_response_len*/ response_size,
7477 /*timeout*/ timeout ? timeout : 5000);
7479 ccb->smpio.flags = SMP_FLAG_NONE;
7481 if (((retval = cam_send_ccb(device, ccb)) < 0)
7482 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7483 const char warnstr[] = "error sending command";
7490 if (arglist & CAM_ARG_VERBOSE) {
7491 cam_error_print(device, ccb, CAM_ESF_ALL,
7492 CAM_EPF_ALL, stderr);
7496 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7497 && (response_size > 0)) {
7498 if (fd_response == 0) {
7499 buff_decode_visit(smp_response, response_size,
7500 datastr, arg_put, NULL);
7501 fprintf(stdout, "\n");
7503 ssize_t amt_written;
7504 int amt_to_write = response_size;
7505 u_int8_t *buf_ptr = smp_response;
7507 for (amt_written = 0; (amt_to_write > 0) &&
7508 (amt_written = write(STDOUT_FILENO, buf_ptr,
7509 amt_to_write)) > 0;){
7510 amt_to_write -= amt_written;
7511 buf_ptr += amt_written;
7513 if (amt_written == -1) {
7514 warn("error writing data to stdout");
7516 goto smpcmd_bailout;
7517 } else if ((amt_written == 0)
7518 && (amt_to_write > 0)) {
7519 warnx("only wrote %u bytes out of %u",
7520 response_size - amt_to_write,
7529 if (smp_request != NULL)
7532 if (smp_response != NULL)
7539 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7540 int retry_count, int timeout)
7544 int32_t mmc_opcode = 0, mmc_arg = 0;
7545 int32_t mmc_flags = -1;
7548 int is_bw_4 = 0, is_bw_1 = 0;
7549 int is_highspeed = 0, is_stdspeed = 0;
7550 int is_info_request = 0;
7552 uint8_t mmc_data_byte = 0;
7554 /* For IO_RW_EXTENDED command */
7555 uint8_t *mmc_data = NULL;
7556 struct mmc_data mmc_d;
7557 int mmc_data_len = 0;
7560 * Note that at the moment we don't support sending SMP CCBs to
7561 * devices that aren't probed by CAM.
7563 ccb = cam_getccb(device);
7565 warnx("%s: error allocating CCB", __func__);
7569 bzero(&(&ccb->ccb_h)[1],
7570 sizeof(union ccb) - sizeof(struct ccb_hdr));
7572 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7581 if (!strcmp(optarg, "high"))
7587 is_info_request = 1;
7590 mmc_opcode = strtol(optarg, NULL, 0);
7591 if (mmc_opcode < 0) {
7592 warnx("invalid MMC opcode %d",
7595 goto mmccmd_bailout;
7599 mmc_arg = strtol(optarg, NULL, 0);
7601 warnx("invalid MMC arg %d",
7604 goto mmccmd_bailout;
7608 mmc_flags = strtol(optarg, NULL, 0);
7609 if (mmc_flags < 0) {
7610 warnx("invalid MMC flags %d",
7613 goto mmccmd_bailout;
7617 mmc_data_len = strtol(optarg, NULL, 0);
7618 if (mmc_data_len <= 0) {
7619 warnx("invalid MMC data len %d",
7622 goto mmccmd_bailout;
7629 mmc_data_byte = strtol(optarg, NULL, 0);
7635 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7637 /* If flags are left default, supply the right flags */
7639 switch (mmc_opcode) {
7640 case MMC_GO_IDLE_STATE:
7641 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7643 case IO_SEND_OP_COND:
7644 mmc_flags = MMC_RSP_R4;
7646 case SD_SEND_RELATIVE_ADDR:
7647 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7649 case MMC_SELECT_CARD:
7650 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7651 mmc_arg = mmc_arg << 16;
7653 case SD_IO_RW_DIRECT:
7654 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7655 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7657 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7659 case SD_IO_RW_EXTENDED:
7660 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7661 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7662 int len_arg = mmc_data_len;
7663 if (mmc_data_len == 512)
7667 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7669 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7672 mmc_flags = MMC_RSP_R1;
7676 // Switch bus width instead of sending IO command
7677 if (is_bw_4 || is_bw_1) {
7678 struct ccb_trans_settings_mmc *cts;
7679 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7680 ccb->ccb_h.flags = 0;
7681 cts = &ccb->cts.proto_specific.mmc;
7682 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7683 cts->ios_valid = MMC_BW;
7684 if (((retval = cam_send_ccb(device, ccb)) < 0)
7685 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7686 warn("Error sending command");
7688 printf("Parameters set OK\n");
7694 // Switch bus speed instead of sending IO command
7695 if (is_stdspeed || is_highspeed) {
7696 struct ccb_trans_settings_mmc *cts;
7697 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7698 ccb->ccb_h.flags = 0;
7699 cts = &ccb->cts.proto_specific.mmc;
7700 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
7701 cts->ios_valid = MMC_BT;
7702 if (((retval = cam_send_ccb(device, ccb)) < 0)
7703 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7704 warn("Error sending command");
7706 printf("Speed set OK (HS: %d)\n", is_highspeed);
7712 // Get information about controller and its settings
7713 if (is_info_request) {
7714 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
7715 ccb->ccb_h.flags = 0;
7716 struct ccb_trans_settings_mmc *cts;
7717 cts = &ccb->cts.proto_specific.mmc;
7718 if (((retval = cam_send_ccb(device, ccb)) < 0)
7719 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7720 warn("Error sending command");
7723 printf("Host controller information\n");
7724 printf("Host OCR: 0x%x\n", cts->host_ocr);
7725 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
7726 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
7727 printf("Supported bus width: ");
7728 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
7730 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
7732 printf("\nCurrent settings:\n");
7733 printf("Bus width: ");
7734 switch (cts->ios.bus_width) {
7745 printf("Freq: %d.%03d MHz%s\n",
7746 cts->ios.clock / 1000000,
7747 (cts->ios.clock / 1000) % 1000,
7748 cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : "");
7752 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
7754 if (mmc_data_len > 0) {
7755 flags |= CAM_DIR_IN;
7756 mmc_data = malloc(mmc_data_len);
7757 memset(mmc_data, 0, mmc_data_len);
7758 memset(&mmc_d, 0, sizeof(mmc_d));
7759 mmc_d.len = mmc_data_len;
7760 mmc_d.data = mmc_data;
7761 mmc_d.flags = MMC_DATA_READ;
7762 } else flags |= CAM_DIR_NONE;
7764 cam_fill_mmcio(&ccb->mmcio,
7765 /*retries*/ retry_count,
7768 /*mmc_opcode*/ mmc_opcode,
7769 /*mmc_arg*/ mmc_arg,
7770 /*mmc_flags*/ mmc_flags,
7771 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
7772 /*timeout*/ timeout ? timeout : 5000);
7774 if (((retval = cam_send_ccb(device, ccb)) < 0)
7775 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7776 const char warnstr[] = "error sending command";
7783 if (arglist & CAM_ARG_VERBOSE) {
7784 cam_error_print(device, ccb, CAM_ESF_ALL,
7785 CAM_EPF_ALL, stderr);
7789 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
7790 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
7791 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
7792 ccb->mmcio.cmd.resp[1],
7793 ccb->mmcio.cmd.resp[2],
7794 ccb->mmcio.cmd.resp[3]);
7796 switch (mmc_opcode) {
7797 case SD_IO_RW_DIRECT:
7798 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
7799 SD_R5_DATA(ccb->mmcio.cmd.resp),
7800 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
7802 case SD_IO_RW_EXTENDED:
7803 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
7804 hexdump(mmc_data, mmc_data_len, NULL, 0);
7806 case SD_SEND_RELATIVE_ADDR:
7807 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
7810 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
7817 if (mmc_data_len > 0 && mmc_data != NULL)
7824 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7825 char *combinedopt, int retry_count, int timeout)
7828 struct smp_report_general_request *request = NULL;
7829 struct smp_report_general_response *response = NULL;
7830 struct sbuf *sb = NULL;
7832 int c, long_response = 0;
7836 * Note that at the moment we don't support sending SMP CCBs to
7837 * devices that aren't probed by CAM.
7839 ccb = cam_getccb(device);
7841 warnx("%s: error allocating CCB", __func__);
7845 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7847 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7856 request = malloc(sizeof(*request));
7857 if (request == NULL) {
7858 warn("%s: unable to allocate %zd bytes", __func__,
7864 response = malloc(sizeof(*response));
7865 if (response == NULL) {
7866 warn("%s: unable to allocate %zd bytes", __func__,
7873 smp_report_general(&ccb->smpio,
7877 /*request_len*/ sizeof(*request),
7878 (uint8_t *)response,
7879 /*response_len*/ sizeof(*response),
7880 /*long_response*/ long_response,
7883 if (((retval = cam_send_ccb(device, ccb)) < 0)
7884 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7885 const char warnstr[] = "error sending command";
7892 if (arglist & CAM_ARG_VERBOSE) {
7893 cam_error_print(device, ccb, CAM_ESF_ALL,
7894 CAM_EPF_ALL, stderr);
7901 * If the device supports the long response bit, try again and see
7902 * if we can get all of the data.
7904 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7905 && (long_response == 0)) {
7906 ccb->ccb_h.status = CAM_REQ_INPROG;
7907 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7913 * XXX KDM detect and decode SMP errors here.
7915 sb = sbuf_new_auto();
7917 warnx("%s: error allocating sbuf", __func__);
7921 smp_report_general_sbuf(response, sizeof(*response), sb);
7923 if (sbuf_finish(sb) != 0) {
7924 warnx("%s: sbuf_finish", __func__);
7928 printf("%s", sbuf_data(sb));
7934 if (request != NULL)
7937 if (response != NULL)
7946 static struct camcontrol_opts phy_ops[] = {
7947 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7948 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7949 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7950 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7951 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7952 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7953 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7954 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7955 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7960 smpphycontrol(struct cam_device *device, int argc, char **argv,
7961 char *combinedopt, int retry_count, int timeout)
7964 struct smp_phy_control_request *request = NULL;
7965 struct smp_phy_control_response *response = NULL;
7966 int long_response = 0;
7969 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7971 uint64_t attached_dev_name = 0;
7972 int dev_name_set = 0;
7973 uint32_t min_plr = 0, max_plr = 0;
7974 uint32_t pp_timeout_val = 0;
7975 int slumber_partial = 0;
7976 int set_pp_timeout_val = 0;
7980 * Note that at the moment we don't support sending SMP CCBs to
7981 * devices that aren't probed by CAM.
7983 ccb = cam_getccb(device);
7985 warnx("%s: error allocating CCB", __func__);
7989 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7991 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7999 if (strcasecmp(optarg, "enable") == 0)
8001 else if (strcasecmp(optarg, "disable") == 0)
8004 warnx("%s: Invalid argument %s", __func__,
8011 slumber_partial |= enable <<
8012 SMP_PC_SAS_SLUMBER_SHIFT;
8015 slumber_partial |= enable <<
8016 SMP_PC_SAS_PARTIAL_SHIFT;
8019 slumber_partial |= enable <<
8020 SMP_PC_SATA_SLUMBER_SHIFT;
8023 slumber_partial |= enable <<
8024 SMP_PC_SATA_PARTIAL_SHIFT;
8027 warnx("%s: programmer error", __func__);
8030 break; /*NOTREACHED*/
8035 attached_dev_name = (uintmax_t)strtoumax(optarg,
8044 * We don't do extensive checking here, so this
8045 * will continue to work when new speeds come out.
8047 min_plr = strtoul(optarg, NULL, 0);
8049 || (min_plr > 0xf)) {
8050 warnx("%s: invalid link rate %x",
8058 * We don't do extensive checking here, so this
8059 * will continue to work when new speeds come out.
8061 max_plr = strtoul(optarg, NULL, 0);
8063 || (max_plr > 0xf)) {
8064 warnx("%s: invalid link rate %x",
8071 camcontrol_optret optreturn;
8072 cam_argmask argnums;
8075 if (phy_op_set != 0) {
8076 warnx("%s: only one phy operation argument "
8077 "(-o) allowed", __func__);
8085 * Allow the user to specify the phy operation
8086 * numerically, as well as with a name. This will
8087 * future-proof it a bit, so options that are added
8088 * in future specs can be used.
8090 if (isdigit(optarg[0])) {
8091 phy_operation = strtoul(optarg, NULL, 0);
8092 if ((phy_operation == 0)
8093 || (phy_operation > 0xff)) {
8094 warnx("%s: invalid phy operation %#x",
8095 __func__, phy_operation);
8101 optreturn = getoption(phy_ops, optarg, &phy_operation,
8104 if (optreturn == CC_OR_AMBIGUOUS) {
8105 warnx("%s: ambiguous option %s", __func__,
8110 } else if (optreturn == CC_OR_NOT_FOUND) {
8111 warnx("%s: option %s not found", __func__,
8123 pp_timeout_val = strtoul(optarg, NULL, 0);
8124 if (pp_timeout_val > 15) {
8125 warnx("%s: invalid partial pathway timeout "
8126 "value %u, need a value less than 16",
8127 __func__, pp_timeout_val);
8131 set_pp_timeout_val = 1;
8139 warnx("%s: a PHY (-p phy) argument is required",__func__);
8144 if (((dev_name_set != 0)
8145 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8146 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8147 && (dev_name_set == 0))) {
8148 warnx("%s: -d name and -o setdevname arguments both "
8149 "required to set device name", __func__);
8154 request = malloc(sizeof(*request));
8155 if (request == NULL) {
8156 warn("%s: unable to allocate %zd bytes", __func__,
8162 response = malloc(sizeof(*response));
8163 if (response == NULL) {
8164 warn("%s: unable to allocate %zd bytes", __func__,
8170 smp_phy_control(&ccb->smpio,
8175 (uint8_t *)response,
8178 /*expected_exp_change_count*/ 0,
8181 (set_pp_timeout_val != 0) ? 1 : 0,
8189 if (((retval = cam_send_ccb(device, ccb)) < 0)
8190 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8191 const char warnstr[] = "error sending command";
8198 if (arglist & CAM_ARG_VERBOSE) {
8200 * Use CAM_EPF_NORMAL so we only get one line of
8201 * SMP command decoding.
8203 cam_error_print(device, ccb, CAM_ESF_ALL,
8204 CAM_EPF_NORMAL, stderr);
8210 /* XXX KDM print out something here for success? */
8215 if (request != NULL)
8218 if (response != NULL)
8225 smpmaninfo(struct cam_device *device, int argc, char **argv,
8226 char *combinedopt, int retry_count, int timeout)
8229 struct smp_report_manuf_info_request request;
8230 struct smp_report_manuf_info_response response;
8231 struct sbuf *sb = NULL;
8232 int long_response = 0;
8237 * Note that at the moment we don't support sending SMP CCBs to
8238 * devices that aren't probed by CAM.
8240 ccb = cam_getccb(device);
8242 warnx("%s: error allocating CCB", __func__);
8246 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8248 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8257 bzero(&request, sizeof(request));
8258 bzero(&response, sizeof(response));
8260 smp_report_manuf_info(&ccb->smpio,
8265 (uint8_t *)&response,
8270 if (((retval = cam_send_ccb(device, ccb)) < 0)
8271 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8272 const char warnstr[] = "error sending command";
8279 if (arglist & CAM_ARG_VERBOSE) {
8280 cam_error_print(device, ccb, CAM_ESF_ALL,
8281 CAM_EPF_ALL, stderr);
8287 sb = sbuf_new_auto();
8289 warnx("%s: error allocating sbuf", __func__);
8293 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8295 if (sbuf_finish(sb) != 0) {
8296 warnx("%s: sbuf_finish", __func__);
8300 printf("%s", sbuf_data(sb));
8314 getdevid(struct cam_devitem *item)
8317 union ccb *ccb = NULL;
8319 struct cam_device *dev;
8321 dev = cam_open_btl(item->dev_match.path_id,
8322 item->dev_match.target_id,
8323 item->dev_match.target_lun, O_RDWR, NULL);
8326 warnx("%s", cam_errbuf);
8331 item->device_id_len = 0;
8333 ccb = cam_getccb(dev);
8335 warnx("%s: error allocating CCB", __func__);
8340 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8343 * On the first try, we just probe for the size of the data, and
8344 * then allocate that much memory and try again.
8347 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8348 ccb->ccb_h.flags = CAM_DIR_IN;
8349 ccb->cdai.flags = CDAI_FLAG_NONE;
8350 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8351 ccb->cdai.bufsiz = item->device_id_len;
8352 if (item->device_id_len != 0)
8353 ccb->cdai.buf = (uint8_t *)item->device_id;
8355 if (cam_send_ccb(dev, ccb) < 0) {
8356 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8361 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8362 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8367 if (item->device_id_len == 0) {
8369 * This is our first time through. Allocate the buffer,
8370 * and then go back to get the data.
8372 if (ccb->cdai.provsiz == 0) {
8373 warnx("%s: invalid .provsiz field returned with "
8374 "XPT_GDEV_ADVINFO CCB", __func__);
8378 item->device_id_len = ccb->cdai.provsiz;
8379 item->device_id = malloc(item->device_id_len);
8380 if (item->device_id == NULL) {
8381 warn("%s: unable to allocate %d bytes", __func__,
8382 item->device_id_len);
8386 ccb->ccb_h.status = CAM_REQ_INPROG;
8392 cam_close_device(dev);
8401 * XXX KDM merge this code with getdevtree()?
8404 buildbusdevlist(struct cam_devlist *devlist)
8407 int bufsize, fd = -1;
8408 struct dev_match_pattern *patterns;
8409 struct cam_devitem *item = NULL;
8410 int skip_device = 0;
8413 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8414 warn("couldn't open %s", XPT_DEVICE);
8418 bzero(&ccb, sizeof(union ccb));
8420 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8421 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8422 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8424 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8425 bufsize = sizeof(struct dev_match_result) * 100;
8426 ccb.cdm.match_buf_len = bufsize;
8427 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8428 if (ccb.cdm.matches == NULL) {
8429 warnx("can't malloc memory for matches");
8433 ccb.cdm.num_matches = 0;
8434 ccb.cdm.num_patterns = 2;
8435 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8436 ccb.cdm.num_patterns;
8438 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8439 if (patterns == NULL) {
8440 warnx("can't malloc memory for patterns");
8445 ccb.cdm.patterns = patterns;
8446 bzero(patterns, ccb.cdm.pattern_buf_len);
8448 patterns[0].type = DEV_MATCH_DEVICE;
8449 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8450 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8451 patterns[1].type = DEV_MATCH_PERIPH;
8452 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8453 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8456 * We do the ioctl multiple times if necessary, in case there are
8457 * more than 100 nodes in the EDT.
8462 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8463 warn("error sending CAMIOCOMMAND ioctl");
8468 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8469 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8470 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8471 warnx("got CAM error %#x, CDM error %d\n",
8472 ccb.ccb_h.status, ccb.cdm.status);
8477 for (i = 0; i < ccb.cdm.num_matches; i++) {
8478 switch (ccb.cdm.matches[i].type) {
8479 case DEV_MATCH_DEVICE: {
8480 struct device_match_result *dev_result;
8483 &ccb.cdm.matches[i].result.device_result;
8485 if (dev_result->flags &
8486 DEV_RESULT_UNCONFIGURED) {
8492 item = malloc(sizeof(*item));
8494 warn("%s: unable to allocate %zd bytes",
8495 __func__, sizeof(*item));
8499 bzero(item, sizeof(*item));
8500 bcopy(dev_result, &item->dev_match,
8501 sizeof(*dev_result));
8502 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8505 if (getdevid(item) != 0) {
8511 case DEV_MATCH_PERIPH: {
8512 struct periph_match_result *periph_result;
8515 &ccb.cdm.matches[i].result.periph_result;
8517 if (skip_device != 0)
8519 item->num_periphs++;
8520 item->periph_matches = realloc(
8521 item->periph_matches,
8523 sizeof(struct periph_match_result));
8524 if (item->periph_matches == NULL) {
8525 warn("%s: error allocating periph "
8530 bcopy(periph_result, &item->periph_matches[
8531 item->num_periphs - 1],
8532 sizeof(*periph_result));
8536 fprintf(stderr, "%s: unexpected match "
8537 "type %d\n", __func__,
8538 ccb.cdm.matches[i].type);
8541 break; /*NOTREACHED*/
8544 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8545 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8553 free(ccb.cdm.matches);
8556 freebusdevlist(devlist);
8562 freebusdevlist(struct cam_devlist *devlist)
8564 struct cam_devitem *item, *item2;
8566 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8567 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8569 free(item->device_id);
8570 free(item->periph_matches);
8575 static struct cam_devitem *
8576 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8578 struct cam_devitem *item;
8580 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8581 struct scsi_vpd_id_descriptor *idd;
8584 * XXX KDM look for LUN IDs as well?
8586 idd = scsi_get_devid(item->device_id,
8587 item->device_id_len,
8588 scsi_devid_is_sas_target);
8592 if (scsi_8btou64(idd->identifier) == sasaddr)
8600 smpphylist(struct cam_device *device, int argc, char **argv,
8601 char *combinedopt, int retry_count, int timeout)
8603 struct smp_report_general_request *rgrequest = NULL;
8604 struct smp_report_general_response *rgresponse = NULL;
8605 struct smp_discover_request *disrequest = NULL;
8606 struct smp_discover_response *disresponse = NULL;
8607 struct cam_devlist devlist;
8609 int long_response = 0;
8616 * Note that at the moment we don't support sending SMP CCBs to
8617 * devices that aren't probed by CAM.
8619 ccb = cam_getccb(device);
8621 warnx("%s: error allocating CCB", __func__);
8625 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8626 STAILQ_INIT(&devlist.dev_queue);
8628 rgrequest = malloc(sizeof(*rgrequest));
8629 if (rgrequest == NULL) {
8630 warn("%s: unable to allocate %zd bytes", __func__,
8631 sizeof(*rgrequest));
8636 rgresponse = malloc(sizeof(*rgresponse));
8637 if (rgresponse == NULL) {
8638 warn("%s: unable to allocate %zd bytes", __func__,
8639 sizeof(*rgresponse));
8644 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8657 smp_report_general(&ccb->smpio,
8661 /*request_len*/ sizeof(*rgrequest),
8662 (uint8_t *)rgresponse,
8663 /*response_len*/ sizeof(*rgresponse),
8664 /*long_response*/ long_response,
8667 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8669 if (((retval = cam_send_ccb(device, ccb)) < 0)
8670 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8671 const char warnstr[] = "error sending command";
8678 if (arglist & CAM_ARG_VERBOSE) {
8679 cam_error_print(device, ccb, CAM_ESF_ALL,
8680 CAM_EPF_ALL, stderr);
8686 num_phys = rgresponse->num_phys;
8688 if (num_phys == 0) {
8690 fprintf(stdout, "%s: No Phys reported\n", __func__);
8695 devlist.path_id = device->path_id;
8697 retval = buildbusdevlist(&devlist);
8702 fprintf(stdout, "%d PHYs:\n", num_phys);
8703 fprintf(stdout, "PHY Attached SAS Address\n");
8706 disrequest = malloc(sizeof(*disrequest));
8707 if (disrequest == NULL) {
8708 warn("%s: unable to allocate %zd bytes", __func__,
8709 sizeof(*disrequest));
8714 disresponse = malloc(sizeof(*disresponse));
8715 if (disresponse == NULL) {
8716 warn("%s: unable to allocate %zd bytes", __func__,
8717 sizeof(*disresponse));
8722 for (i = 0; i < num_phys; i++) {
8723 struct cam_devitem *item;
8724 struct device_match_result *dev_match;
8725 char vendor[16], product[48], revision[16];
8729 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8731 ccb->ccb_h.status = CAM_REQ_INPROG;
8732 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8734 smp_discover(&ccb->smpio,
8738 sizeof(*disrequest),
8739 (uint8_t *)disresponse,
8740 sizeof(*disresponse),
8742 /*ignore_zone_group*/ 0,
8746 if (((retval = cam_send_ccb(device, ccb)) < 0)
8747 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
8748 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
8749 const char warnstr[] = "error sending command";
8756 if (arglist & CAM_ARG_VERBOSE) {
8757 cam_error_print(device, ccb, CAM_ESF_ALL,
8758 CAM_EPF_ALL, stderr);
8764 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
8766 fprintf(stdout, "%3d <vacant>\n", i);
8770 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
8773 item = findsasdevice(&devlist,
8774 scsi_8btou64(disresponse->attached_sas_address));
8778 || (item != NULL)) {
8779 fprintf(stdout, "%3d 0x%016jx", i,
8780 (uintmax_t)scsi_8btou64(
8781 disresponse->attached_sas_address));
8783 fprintf(stdout, "\n");
8786 } else if (quiet != 0)
8789 dev_match = &item->dev_match;
8791 if (dev_match->protocol == PROTO_SCSI) {
8792 cam_strvis(vendor, dev_match->inq_data.vendor,
8793 sizeof(dev_match->inq_data.vendor),
8795 cam_strvis(product, dev_match->inq_data.product,
8796 sizeof(dev_match->inq_data.product),
8798 cam_strvis(revision, dev_match->inq_data.revision,
8799 sizeof(dev_match->inq_data.revision),
8801 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8803 } else if ((dev_match->protocol == PROTO_ATA)
8804 || (dev_match->protocol == PROTO_SATAPM)) {
8805 cam_strvis(product, dev_match->ident_data.model,
8806 sizeof(dev_match->ident_data.model),
8808 cam_strvis(revision, dev_match->ident_data.revision,
8809 sizeof(dev_match->ident_data.revision),
8811 sprintf(tmpstr, "<%s %s>", product, revision);
8813 sprintf(tmpstr, "<>");
8815 fprintf(stdout, " %-33s ", tmpstr);
8818 * If we have 0 periphs, that's a bug...
8820 if (item->num_periphs == 0) {
8821 fprintf(stdout, "\n");
8825 fprintf(stdout, "(");
8826 for (j = 0; j < item->num_periphs; j++) {
8828 fprintf(stdout, ",");
8830 fprintf(stdout, "%s%d",
8831 item->periph_matches[j].periph_name,
8832 item->periph_matches[j].unit_number);
8835 fprintf(stdout, ")\n");
8849 freebusdevlist(&devlist);
8855 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
8857 struct ata_res *res;
8859 res = &ccb->ataio.res;
8860 if (res->status & ATA_STATUS_ERROR) {
8861 if (arglist & CAM_ARG_VERBOSE) {
8862 cam_error_print(device, ccb, CAM_ESF_ALL,
8863 CAM_EPF_ALL, stderr);
8864 printf("error = 0x%02x, sector_count = 0x%04x, "
8865 "device = 0x%02x, status = 0x%02x\n",
8866 res->error, res->sector_count,
8867 res->device, res->status);
8873 if (arglist & CAM_ARG_VERBOSE) {
8874 fprintf(stdout, "%s%d: Raw native check power data:\n",
8875 device->device_name, device->dev_unit_num);
8876 /* res is 4 byte aligned */
8877 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
8879 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
8880 "status = 0x%02x\n", res->error, res->sector_count,
8881 res->device, res->status);
8884 printf("%s%d: ", device->device_name, device->dev_unit_num);
8885 switch (res->sector_count) {
8887 printf("Standby mode\n");
8890 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
8893 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
8896 printf("Idle mode\n");
8899 printf("Active or Idle mode\n");
8902 printf("Unknown mode 0x%02x\n", res->sector_count);
8910 atapm(struct cam_device *device, int argc, char **argv,
8911 char *combinedopt, int retry_count, int timeout)
8917 u_int8_t ata_flags = 0;
8920 ccb = cam_getccb(device);
8923 warnx("%s: error allocating ccb", __func__);
8927 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8936 if (strcmp(argv[1], "idle") == 0) {
8938 cmd = ATA_IDLE_IMMEDIATE;
8941 } else if (strcmp(argv[1], "standby") == 0) {
8943 cmd = ATA_STANDBY_IMMEDIATE;
8945 cmd = ATA_STANDBY_CMD;
8946 } else if (strcmp(argv[1], "powermode") == 0) {
8947 cmd = ATA_CHECK_POWER_MODE;
8948 ata_flags = AP_FLAG_CHK_COND;
8957 else if (t <= (240 * 5))
8959 else if (t <= (252 * 5))
8960 /* special encoding for 21 minutes */
8962 else if (t <= (11 * 30 * 60))
8963 sc = (t - 1) / (30 * 60) + 241;
8967 retval = ata_do_cmd(device,
8969 /*retries*/retry_count,
8970 /*flags*/CAM_DIR_NONE,
8971 /*protocol*/AP_PROTO_NON_DATA,
8972 /*ata_flags*/ata_flags,
8973 /*tag_action*/MSG_SIMPLE_Q_TAG,
8980 /*timeout*/timeout ? timeout : 30 * 1000,
8985 if (retval || cmd != ATA_CHECK_POWER_MODE)
8988 return (atapm_proc_resp(device, ccb));
8992 ataaxm(struct cam_device *device, int argc, char **argv,
8993 char *combinedopt, int retry_count, int timeout)
9001 ccb = cam_getccb(device);
9004 warnx("%s: error allocating ccb", __func__);
9008 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9018 if (strcmp(argv[1], "apm") == 0) {
9034 retval = ata_do_28bit_cmd(device,
9036 /*retries*/retry_count,
9037 /*flags*/CAM_DIR_NONE,
9038 /*protocol*/AP_PROTO_NON_DATA,
9039 /*tag_action*/MSG_SIMPLE_Q_TAG,
9040 /*command*/ATA_SETFEATURES,
9046 /*timeout*/timeout ? timeout : 30 * 1000,
9054 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9055 int show_sa_errors, int sa_set, int service_action,
9056 int timeout_desc, int task_attr, int retry_count, int timeout,
9057 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9059 union ccb *ccb = NULL;
9060 uint8_t *buf = NULL;
9061 uint32_t alloc_len = 0, num_opcodes;
9062 uint32_t valid_len = 0;
9063 uint32_t avail_len = 0;
9064 struct scsi_report_supported_opcodes_all *all_hdr;
9065 struct scsi_report_supported_opcodes_one *one;
9070 * Make it clear that we haven't yet allocated or filled anything.
9075 ccb = cam_getccb(device);
9077 warnx("couldn't allocate CCB");
9082 /* cam_getccb cleans up the header, caller has to zero the payload */
9083 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9085 if (opcode_set != 0) {
9086 options |= RSO_OPTIONS_OC;
9088 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9091 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9092 sizeof(struct scsi_report_supported_opcodes_descr));
9095 if (timeout_desc != 0) {
9096 options |= RSO_RCTD;
9097 alloc_len += num_opcodes *
9098 sizeof(struct scsi_report_supported_opcodes_timeout);
9102 options |= RSO_OPTIONS_OC_SA;
9103 if (show_sa_errors != 0)
9104 options &= ~RSO_OPTIONS_OC;
9113 buf = malloc(alloc_len);
9115 warn("Unable to allocate %u bytes", alloc_len);
9119 bzero(buf, alloc_len);
9121 scsi_report_supported_opcodes(&ccb->csio,
9122 /*retries*/ retry_count,
9124 /*tag_action*/ task_attr,
9125 /*options*/ options,
9126 /*req_opcode*/ opcode,
9127 /*req_service_action*/ service_action,
9129 /*dxfer_len*/ alloc_len,
9130 /*sense_len*/ SSD_FULL_SIZE,
9131 /*timeout*/ timeout ? timeout : 10000);
9133 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9135 if (retry_count != 0)
9136 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9138 if (cam_send_ccb(device, ccb) < 0) {
9139 perror("error sending REPORT SUPPORTED OPERATION CODES");
9144 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9145 if (verbosemode != 0)
9146 cam_error_print(device, ccb, CAM_ESF_ALL,
9147 CAM_EPF_ALL, stderr);
9152 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9154 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9155 && (valid_len >= sizeof(*all_hdr))) {
9156 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9157 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9158 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9159 && (valid_len >= sizeof(*one))) {
9160 uint32_t cdb_length;
9162 one = (struct scsi_report_supported_opcodes_one *)buf;
9163 cdb_length = scsi_2btoul(one->cdb_length);
9164 avail_len = sizeof(*one) + cdb_length;
9165 if (one->support & RSO_ONE_CTDP) {
9166 struct scsi_report_supported_opcodes_timeout *td;
9168 td = (struct scsi_report_supported_opcodes_timeout *)
9170 if (valid_len >= (avail_len + sizeof(td->length))) {
9171 avail_len += scsi_2btoul(td->length) +
9174 avail_len += sizeof(*td);
9180 * avail_len could be zero if we didn't get enough data back from
9181 * thet target to determine
9183 if ((avail_len != 0)
9184 && (avail_len > valid_len)) {
9185 alloc_len = avail_len;
9189 *fill_len = valid_len;
9201 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9202 int req_sa, uint8_t *buf, uint32_t valid_len)
9204 struct scsi_report_supported_opcodes_one *one;
9205 struct scsi_report_supported_opcodes_timeout *td;
9206 uint32_t cdb_len = 0, td_len = 0;
9207 const char *op_desc = NULL;
9211 one = (struct scsi_report_supported_opcodes_one *)buf;
9214 * If we don't have the full single opcode descriptor, no point in
9217 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9219 warnx("Only %u bytes returned, not enough to verify support",
9225 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9227 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9230 printf(", SA 0x%x", req_sa);
9233 switch (one->support & RSO_ONE_SUP_MASK) {
9234 case RSO_ONE_SUP_UNAVAIL:
9235 printf("No command support information currently available\n");
9237 case RSO_ONE_SUP_NOT_SUP:
9238 printf("Command not supported\n");
9241 break; /*NOTREACHED*/
9242 case RSO_ONE_SUP_AVAIL:
9243 printf("Command is supported, complies with a SCSI standard\n");
9245 case RSO_ONE_SUP_VENDOR:
9246 printf("Command is supported, vendor-specific "
9247 "implementation\n");
9250 printf("Unknown command support flags 0x%#x\n",
9251 one->support & RSO_ONE_SUP_MASK);
9256 * If we don't have the CDB length, it isn't exactly an error, the
9257 * command probably isn't supported.
9259 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9263 cdb_len = scsi_2btoul(one->cdb_length);
9266 * If our valid data doesn't include the full reported length,
9267 * return. The caller should have detected this and adjusted his
9268 * allocation length to get all of the available data.
9270 if (valid_len < sizeof(*one) + cdb_len) {
9276 * If all we have is the opcode, there is no point in printing out
9284 printf("CDB usage bitmap:");
9285 for (i = 0; i < cdb_len; i++) {
9286 printf(" %02x", one->cdb_usage[i]);
9291 * If we don't have a timeout descriptor, we're done.
9293 if ((one->support & RSO_ONE_CTDP) == 0)
9297 * If we don't have enough valid length to include the timeout
9298 * descriptor length, we're done.
9300 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9303 td = (struct scsi_report_supported_opcodes_timeout *)
9304 &buf[sizeof(*one) + cdb_len];
9305 td_len = scsi_2btoul(td->length);
9306 td_len += sizeof(td->length);
9309 * If we don't have the full timeout descriptor, we're done.
9311 if (td_len < sizeof(*td))
9315 * If we don't have enough valid length to contain the full timeout
9316 * descriptor, we're done.
9318 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9321 printf("Timeout information:\n");
9322 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9323 printf("Nominal timeout: %u seconds\n",
9324 scsi_4btoul(td->nominal_time));
9325 printf("Recommended timeout: %u seconds\n",
9326 scsi_4btoul(td->recommended_time));
9333 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9336 struct scsi_report_supported_opcodes_all *hdr;
9337 struct scsi_report_supported_opcodes_descr *desc;
9338 uint32_t avail_len = 0, used_len = 0;
9342 if (valid_len < sizeof(*hdr)) {
9343 warnx("%s: not enough returned data (%u bytes) opcode list",
9344 __func__, valid_len);
9348 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9349 avail_len = scsi_4btoul(hdr->length);
9350 avail_len += sizeof(hdr->length);
9352 * Take the lesser of the amount of data the drive claims is
9353 * available, and the amount of data the HBA says was returned.
9355 avail_len = MIN(avail_len, valid_len);
9357 used_len = sizeof(hdr->length);
9359 printf("%-6s %4s %8s ",
9360 "Opcode", "SA", "CDB len" );
9363 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9364 printf(" Description\n");
9366 while ((avail_len - used_len) > sizeof(*desc)) {
9367 struct scsi_report_supported_opcodes_timeout *td;
9369 const char *op_desc = NULL;
9371 cur_ptr = &buf[used_len];
9372 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9374 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9375 if (op_desc == NULL)
9376 op_desc = "UNKNOWN";
9378 printf("0x%02x %#4x %8u ", desc->opcode,
9379 scsi_2btoul(desc->service_action),
9380 scsi_2btoul(desc->cdb_length));
9382 used_len += sizeof(*desc);
9384 if ((desc->flags & RSO_CTDP) == 0) {
9385 printf(" %s\n", op_desc);
9390 * If we don't have enough space to fit a timeout
9391 * descriptor, then we're done.
9393 if (avail_len - used_len < sizeof(*td)) {
9394 used_len = avail_len;
9395 printf(" %s\n", op_desc);
9398 cur_ptr = &buf[used_len];
9399 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9400 td_len = scsi_2btoul(td->length);
9401 td_len += sizeof(td->length);
9405 * If the given timeout descriptor length is less than what
9406 * we understand, skip it.
9408 if (td_len < sizeof(*td)) {
9409 printf(" %s\n", op_desc);
9413 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9414 scsi_4btoul(td->nominal_time),
9415 scsi_4btoul(td->recommended_time), op_desc);
9422 scsiopcodes(struct cam_device *device, int argc, char **argv,
9423 char *combinedopt, int task_attr, int retry_count, int timeout,
9427 uint32_t opcode = 0, service_action = 0;
9428 int td_set = 0, opcode_set = 0, sa_set = 0;
9429 int show_sa_errors = 1;
9430 uint32_t valid_len = 0;
9431 uint8_t *buf = NULL;
9435 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9441 opcode = strtoul(optarg, &endptr, 0);
9442 if (*endptr != '\0') {
9443 warnx("Invalid opcode \"%s\", must be a number",
9448 if (opcode > 0xff) {
9449 warnx("Invalid opcode 0x%#x, must be between"
9450 "0 and 0xff inclusive", opcode);
9457 service_action = strtoul(optarg, &endptr, 0);
9458 if (*endptr != '\0') {
9459 warnx("Invalid service action \"%s\", must "
9460 "be a number", optarg);
9464 if (service_action > 0xffff) {
9465 warnx("Invalid service action 0x%#x, must "
9466 "be between 0 and 0xffff inclusive",
9481 && (opcode_set == 0)) {
9482 warnx("You must specify an opcode with -o if a service "
9487 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9488 sa_set, service_action, td_set, task_attr,
9489 retry_count, timeout, verbosemode, &valid_len,
9494 if ((opcode_set != 0)
9496 retval = scsiprintoneopcode(device, opcode, sa_set,
9497 service_action, buf, valid_len);
9499 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9510 scsireprobe(struct cam_device *device)
9515 ccb = cam_getccb(device);
9518 warnx("%s: error allocating ccb", __func__);
9522 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9524 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9526 if (cam_send_ccb(device, ccb) < 0) {
9527 warn("error sending XPT_REPROBE_LUN CCB");
9532 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9533 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9545 usage(int printlong)
9548 fprintf(printlong ? stdout : stderr,
9549 "usage: camcontrol <command> [device id][generic args][command args]\n"
9550 " camcontrol devlist [-b] [-v]\n"
9551 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9552 " camcontrol tur [dev_id][generic args]\n"
9553 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9554 " camcontrol identify [dev_id][generic args] [-v]\n"
9555 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9556 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9558 " camcontrol start [dev_id][generic args]\n"
9559 " camcontrol stop [dev_id][generic args]\n"
9560 " camcontrol load [dev_id][generic args]\n"
9561 " camcontrol eject [dev_id][generic args]\n"
9562 " camcontrol reprobe [dev_id][generic args]\n"
9563 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9564 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9565 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9566 " [-q][-s][-S offset][-X]\n"
9567 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9568 " [-P pagectl][-e | -b][-d]\n"
9569 " camcontrol cmd [dev_id][generic args]\n"
9570 " <-a cmd [args] | -c cmd [args]>\n"
9571 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9572 " camcontrol smpcmd [dev_id][generic args]\n"
9573 " <-r len fmt [args]> <-R len fmt [args]>\n"
9574 " camcontrol smprg [dev_id][generic args][-l]\n"
9575 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9576 " [-o operation][-d name][-m rate][-M rate]\n"
9577 " [-T pp_timeout][-a enable|disable]\n"
9578 " [-A enable|disable][-s enable|disable]\n"
9579 " [-S enable|disable]\n"
9580 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9581 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9582 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9583 " <all|bus[:target[:lun]]|off>\n"
9584 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9585 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9586 " [-D <enable|disable>][-M mode][-O offset]\n"
9587 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9588 " [-U][-W bus_width]\n"
9589 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9590 " camcontrol sanitize [dev_id][generic args]\n"
9591 " [-a overwrite|block|crypto|exitfailure]\n"
9592 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9594 " camcontrol idle [dev_id][generic args][-t time]\n"
9595 " camcontrol standby [dev_id][generic args][-t time]\n"
9596 " camcontrol sleep [dev_id][generic args]\n"
9597 " camcontrol powermode [dev_id][generic args]\n"
9598 " camcontrol apm [dev_id][generic args][-l level]\n"
9599 " camcontrol aam [dev_id][generic args][-l level]\n"
9600 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9602 " camcontrol security [dev_id][generic args]\n"
9603 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9604 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9605 " [-U <user|master>] [-y]\n"
9606 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9607 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9608 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9609 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9610 " [-s scope][-S][-T type][-U]\n"
9611 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9612 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9613 " [-p part][-s start][-T type][-V vol]\n"
9614 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9616 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9617 " [-o rep_opts] [-P print_opts]\n"
9618 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9619 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9620 " [-S power_src] [-T timer]\n"
9621 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9622 " <-s <-f format -T time | -U >>\n"
9624 " camcontrol help\n");
9628 "Specify one of the following options:\n"
9629 "devlist list all CAM devices\n"
9630 "periphlist list all CAM peripheral drivers attached to a device\n"
9631 "tur send a test unit ready to the named device\n"
9632 "inquiry send a SCSI inquiry command to the named device\n"
9633 "identify send a ATA identify command to the named device\n"
9634 "reportluns send a SCSI report luns command to the device\n"
9635 "readcap send a SCSI read capacity command to the device\n"
9636 "start send a Start Unit command to the device\n"
9637 "stop send a Stop Unit command to the device\n"
9638 "load send a Start Unit command to the device with the load bit set\n"
9639 "eject send a Stop Unit command to the device with the eject bit set\n"
9640 "reprobe update capacity information of the given device\n"
9641 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9642 "reset reset all buses, the given bus, bus:target:lun or device\n"
9643 "defects read the defect list of the specified device\n"
9644 "modepage display or edit (-e) the given mode page\n"
9645 "cmd send the given SCSI command, may need -i or -o as well\n"
9646 "smpcmd send the given SMP command, requires -o and -i\n"
9647 "smprg send the SMP Report General command\n"
9648 "smppc send the SMP PHY Control command, requires -p\n"
9649 "smpphylist display phys attached to a SAS expander\n"
9650 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9651 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9652 "tags report or set the number of transaction slots for a device\n"
9653 "negotiate report or set device negotiation parameters\n"
9654 "format send the SCSI FORMAT UNIT command to the named device\n"
9655 "sanitize send the SCSI SANITIZE command to the named device\n"
9656 "idle send the ATA IDLE command to the named device\n"
9657 "standby send the ATA STANDBY command to the named device\n"
9658 "sleep send the ATA SLEEP command to the named device\n"
9659 "powermode send the ATA CHECK POWER MODE command to the named device\n"
9660 "fwdownload program firmware of the named device with the given image\n"
9661 "security report or send ATA security commands to the named device\n"
9662 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9663 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9664 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9665 "zone manage Zoned Block (Shingled) devices\n"
9666 "epc send ATA Extended Power Conditions commands\n"
9667 "timestamp report or set the device's timestamp\n"
9668 "help this message\n"
9669 "Device Identifiers:\n"
9670 "bus:target specify the bus and target, lun defaults to 0\n"
9671 "bus:target:lun specify the bus, target and lun\n"
9672 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
9673 "Generic arguments:\n"
9674 "-v be verbose, print out sense information\n"
9675 "-t timeout command timeout in seconds, overrides default timeout\n"
9676 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
9677 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
9678 "-E have the kernel attempt to perform SCSI error recovery\n"
9679 "-C count specify the SCSI command retry count (needs -E to work)\n"
9680 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
9681 "modepage arguments:\n"
9682 "-l list all available mode pages\n"
9683 "-m page specify the mode page to view or edit\n"
9684 "-e edit the specified mode page\n"
9685 "-b force view to binary mode\n"
9686 "-d disable block descriptors for mode sense\n"
9687 "-P pgctl page control field 0-3\n"
9688 "defects arguments:\n"
9689 "-f format specify defect list format (block, bfi or phys)\n"
9690 "-G get the grown defect list\n"
9691 "-P get the permanent defect list\n"
9692 "inquiry arguments:\n"
9693 "-D get the standard inquiry data\n"
9694 "-S get the serial number\n"
9695 "-R get the transfer rate, etc.\n"
9696 "reportluns arguments:\n"
9697 "-c only report a count of available LUNs\n"
9698 "-l only print out luns, and not a count\n"
9699 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
9700 "readcap arguments\n"
9701 "-b only report the blocksize\n"
9702 "-h human readable device size, base 2\n"
9703 "-H human readable device size, base 10\n"
9704 "-N print the number of blocks instead of last block\n"
9705 "-q quiet, print numbers only\n"
9706 "-s only report the last block/device size\n"
9708 "-c cdb [args] specify the SCSI CDB\n"
9709 "-i len fmt specify input data and input data format\n"
9710 "-o len fmt [args] specify output data and output data fmt\n"
9711 "smpcmd arguments:\n"
9712 "-r len fmt [args] specify the SMP command to be sent\n"
9713 "-R len fmt [args] specify SMP response format\n"
9714 "smprg arguments:\n"
9715 "-l specify the long response format\n"
9716 "smppc arguments:\n"
9717 "-p phy specify the PHY to operate on\n"
9718 "-l specify the long request/response format\n"
9719 "-o operation specify the phy control operation\n"
9720 "-d name set the attached device name\n"
9721 "-m rate set the minimum physical link rate\n"
9722 "-M rate set the maximum physical link rate\n"
9723 "-T pp_timeout set the partial pathway timeout value\n"
9724 "-a enable|disable enable or disable SATA slumber\n"
9725 "-A enable|disable enable or disable SATA partial phy power\n"
9726 "-s enable|disable enable or disable SAS slumber\n"
9727 "-S enable|disable enable or disable SAS partial phy power\n"
9728 "smpphylist arguments:\n"
9729 "-l specify the long response format\n"
9730 "-q only print phys with attached devices\n"
9731 "smpmaninfo arguments:\n"
9732 "-l specify the long response format\n"
9733 "debug arguments:\n"
9734 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
9735 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
9736 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
9737 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
9739 "-N tags specify the number of tags to use for this device\n"
9740 "-q be quiet, don't report the number of tags\n"
9741 "-v report a number of tag-related parameters\n"
9742 "negotiate arguments:\n"
9743 "-a send a test unit ready after negotiation\n"
9744 "-c report/set current negotiation settings\n"
9745 "-D <arg> \"enable\" or \"disable\" disconnection\n"
9746 "-M mode set ATA mode\n"
9747 "-O offset set command delay offset\n"
9748 "-q be quiet, don't report anything\n"
9749 "-R syncrate synchronization rate in MHz\n"
9750 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
9751 "-U report/set user negotiation settings\n"
9752 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
9753 "-v also print a Path Inquiry CCB for the controller\n"
9754 "format arguments:\n"
9755 "-q be quiet, don't print status messages\n"
9756 "-r run in report only mode\n"
9757 "-w don't send immediate format command\n"
9758 "-y don't ask any questions\n"
9759 "sanitize arguments:\n"
9760 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
9761 "-c passes overwrite passes to perform (1 to 31)\n"
9762 "-I invert overwrite pattern after each pass\n"
9763 "-P pattern path to overwrite pattern file\n"
9764 "-q be quiet, don't print status messages\n"
9765 "-r run in report only mode\n"
9766 "-U run operation in unrestricted completion exit mode\n"
9767 "-w don't send immediate sanitize command\n"
9768 "-y don't ask any questions\n"
9769 "idle/standby arguments:\n"
9770 "-t <arg> number of seconds before respective state.\n"
9771 "fwdownload arguments:\n"
9772 "-f fw_image path to firmware image file\n"
9773 "-q don't print informational messages, only errors\n"
9774 "-s run in simulation mode\n"
9775 "-v print info for every firmware segment sent to device\n"
9776 "-y don't ask any questions\n"
9777 "security arguments:\n"
9778 "-d pwd disable security using the given password for the selected\n"
9780 "-e pwd erase the device using the given pwd for the selected user\n"
9781 "-f freeze the security configuration of the specified device\n"
9782 "-h pwd enhanced erase the device using the given pwd for the\n"
9784 "-k pwd unlock the device using the given pwd for the selected\n"
9786 "-l <high|maximum> specifies which security level to set: high or maximum\n"
9787 "-q be quiet, do not print any status messages\n"
9788 "-s pwd password the device (enable security) using the given\n"
9789 " pwd for the selected user\n"
9790 "-T timeout overrides the timeout (seconds) used for erase operation\n"
9791 "-U <user|master> specifies which user to set: user or master\n"
9792 "-y don't ask any questions\n"
9794 "-f freeze the HPA configuration of the device\n"
9795 "-l lock the HPA configuration of the device\n"
9796 "-P make the HPA max sectors persist\n"
9797 "-p pwd Set the HPA configuration password required for unlock\n"
9799 "-q be quiet, do not print any status messages\n"
9800 "-s sectors configures the maximum user accessible sectors of the\n"
9802 "-U pwd unlock the HPA configuration of the device\n"
9803 "-y don't ask any questions\n"
9804 "persist arguments:\n"
9805 "-i action specify read_keys, read_reservation, report_cap, or\n"
9806 " read_full_status\n"
9807 "-o action specify register, register_ignore, reserve, release,\n"
9808 " clear, preempt, preempt_abort, register_move, replace_lost\n"
9809 "-a set the All Target Ports (ALL_TG_PT) bit\n"
9810 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
9811 "-k key specify the Reservation Key\n"
9812 "-K sa_key specify the Service Action Reservation Key\n"
9813 "-p set the Activate Persist Through Power Loss bit\n"
9814 "-R rtp specify the Relative Target Port\n"
9815 "-s scope specify the scope: lun, extent, element or a number\n"
9816 "-S specify Transport ID for register, requires -I\n"
9817 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
9818 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
9819 "-U unregister the current initiator for register_move\n"
9820 "attrib arguments:\n"
9821 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
9823 "-w attr specify an attribute to write, one -w argument per attr\n"
9824 "-a attr_num only display this attribute number\n"
9825 "-c get cached attributes\n"
9826 "-e elem_addr request attributes for the given element in a changer\n"
9827 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
9828 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
9829 " field_none, field_desc, field_num, field_size, field_rw\n"
9830 "-p partition request attributes for the given partition\n"
9831 "-s start_attr request attributes starting at the given number\n"
9832 "-T elem_type specify the element type (used with -e)\n"
9833 "-V logical_vol specify the logical volume ID\n"
9834 "opcodes arguments:\n"
9835 "-o opcode specify the individual opcode to list\n"
9836 "-s service_action specify the service action for the opcode\n"
9837 "-N do not return SCSI error for unsupported SA\n"
9838 "-T request nominal and recommended timeout values\n"
9840 "-c cmd required: rz, open, close, finish, or rwp\n"
9841 "-a apply the action to all zones\n"
9842 "-l LBA specify the zone starting LBA\n"
9843 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
9844 " closed, full, ro, offline, reset, nonseq, nonwp\n"
9845 "-P print_opt report zones printing: normal, summary, script\n"
9847 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
9848 " source, status, list\n"
9849 "-d disable power mode (timer, state)\n"
9850 "-D delayed entry (goto)\n"
9851 "-e enable power mode (timer, state)\n"
9852 "-H hold power mode (goto)\n"
9853 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
9855 "-P only display power mode (status)\n"
9856 "-r rst_src restore settings from: default, saved (restore)\n"
9857 "-s save mode (timer, state, restore)\n"
9858 "-S power_src set power source: battery, nonbattery (source)\n"
9859 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
9860 "timestamp arguments:\n"
9861 "-r report the timestamp of the device\n"
9862 "-f format report the timestamp of the device with the given\n"
9863 " strftime(3) format string\n"
9864 "-m report the timestamp of the device as milliseconds since\n"
9865 " January 1st, 1970\n"
9866 "-U report the time with UTC instead of the local time zone\n"
9867 "-s set the timestamp of the device\n"
9868 "-f format the format of the time string passed into strptime(3)\n"
9869 "-T time the time value passed into strptime(3)\n"
9870 "-U set the timestamp of the device to UTC time\n"
9875 main(int argc, char **argv)
9878 char *device = NULL;
9880 struct cam_device *cam_dev = NULL;
9881 int timeout = 0, retry_count = 1;
9882 camcontrol_optret optreturn;
9884 const char *mainopt = "C:En:Q:t:u:v";
9885 const char *subopt = NULL;
9886 char combinedopt[256];
9887 int error = 0, optstart = 2;
9888 int task_attr = MSG_SIMPLE_Q_TAG;
9894 cmdlist = CAM_CMD_NONE;
9895 arglist = CAM_ARG_NONE;
9903 * Get the base option.
9905 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
9907 if (optreturn == CC_OR_AMBIGUOUS) {
9908 warnx("ambiguous option %s", argv[1]);
9911 } else if (optreturn == CC_OR_NOT_FOUND) {
9912 warnx("option %s not found", argv[1]);
9918 * Ahh, getopt(3) is a pain.
9920 * This is a gross hack. There really aren't many other good
9921 * options (excuse the pun) for parsing options in a situation like
9922 * this. getopt is kinda braindead, so you end up having to run
9923 * through the options twice, and give each invocation of getopt
9924 * the option string for the other invocation.
9926 * You would think that you could just have two groups of options.
9927 * The first group would get parsed by the first invocation of
9928 * getopt, and the second group would get parsed by the second
9929 * invocation of getopt. It doesn't quite work out that way. When
9930 * the first invocation of getopt finishes, it leaves optind pointing
9931 * to the argument _after_ the first argument in the second group.
9932 * So when the second invocation of getopt comes around, it doesn't
9933 * recognize the first argument it gets and then bails out.
9935 * A nice alternative would be to have a flag for getopt that says
9936 * "just keep parsing arguments even when you encounter an unknown
9937 * argument", but there isn't one. So there's no real clean way to
9938 * easily parse two sets of arguments without having one invocation
9939 * of getopt know about the other.
9941 * Without this hack, the first invocation of getopt would work as
9942 * long as the generic arguments are first, but the second invocation
9943 * (in the subfunction) would fail in one of two ways. In the case
9944 * where you don't set optreset, it would fail because optind may be
9945 * pointing to the argument after the one it should be pointing at.
9946 * In the case where you do set optreset, and reset optind, it would
9947 * fail because getopt would run into the first set of options, which
9948 * it doesn't understand.
9950 * All of this would "sort of" work if you could somehow figure out
9951 * whether optind had been incremented one option too far. The
9952 * mechanics of that, however, are more daunting than just giving
9953 * both invocations all of the expect options for either invocation.
9955 * Needless to say, I wouldn't mind if someone invented a better
9956 * (non-GPL!) command line parsing interface than getopt. I
9957 * wouldn't mind if someone added more knobs to getopt to make it
9958 * work better. Who knows, I may talk myself into doing it someday,
9959 * if the standards weenies let me. As it is, it just leads to
9960 * hackery like this and causes people to avoid it in some cases.
9962 * KDM, September 8th, 1998
9965 sprintf(combinedopt, "%s%s", mainopt, subopt);
9967 sprintf(combinedopt, "%s", mainopt);
9970 * For these options we do not parse optional device arguments and
9971 * we do not open a passthrough device.
9973 if ((cmdlist == CAM_CMD_RESCAN)
9974 || (cmdlist == CAM_CMD_RESET)
9975 || (cmdlist == CAM_CMD_DEVTREE)
9976 || (cmdlist == CAM_CMD_USAGE)
9977 || (cmdlist == CAM_CMD_DEBUG))
9981 && (argc > 2 && argv[2][0] != '-')) {
9985 if (isdigit(argv[2][0])) {
9986 /* device specified as bus:target[:lun] */
9987 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9989 errx(1, "numeric device specification must "
9990 "be either bus:target, or "
9992 /* default to 0 if lun was not specified */
9993 if ((arglist & CAM_ARG_LUN) == 0) {
9995 arglist |= CAM_ARG_LUN;
9999 if (cam_get_device(argv[2], name, sizeof name, &unit)
10001 errx(1, "%s", cam_errbuf);
10002 device = strdup(name);
10003 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10008 * Start getopt processing at argv[2/3], since we've already
10009 * accepted argv[1..2] as the command name, and as a possible
10015 * Now we run through the argument list looking for generic
10016 * options, and ignoring options that possibly belong to
10019 while ((c = getopt(argc, argv, combinedopt))!= -1){
10022 retry_count = strtol(optarg, NULL, 0);
10023 if (retry_count < 0)
10024 errx(1, "retry count %d is < 0",
10026 arglist |= CAM_ARG_RETRIES;
10029 arglist |= CAM_ARG_ERR_RECOVER;
10032 arglist |= CAM_ARG_DEVICE;
10034 while (isspace(*tstr) && (*tstr != '\0'))
10036 device = (char *)strdup(tstr);
10040 int table_entry = 0;
10043 while (isspace(*tstr) && (*tstr != '\0'))
10045 if (isdigit(*tstr)) {
10046 task_attr = strtol(tstr, &endptr, 0);
10047 if (*endptr != '\0') {
10048 errx(1, "Invalid queue option "
10053 scsi_nv_status status;
10055 table_size = sizeof(task_attrs) /
10056 sizeof(task_attrs[0]);
10057 status = scsi_get_nv(task_attrs,
10058 table_size, tstr, &table_entry,
10059 SCSI_NV_FLAG_IG_CASE);
10060 if (status == SCSI_NV_FOUND)
10061 task_attr = task_attrs[
10062 table_entry].value;
10064 errx(1, "%s option %s",
10065 (status == SCSI_NV_AMBIGUOUS)?
10066 "ambiguous" : "invalid",
10073 timeout = strtol(optarg, NULL, 0);
10075 errx(1, "invalid timeout %d", timeout);
10076 /* Convert the timeout from seconds to ms */
10078 arglist |= CAM_ARG_TIMEOUT;
10081 arglist |= CAM_ARG_UNIT;
10082 unit = strtol(optarg, NULL, 0);
10085 arglist |= CAM_ARG_VERBOSE;
10093 * For most commands we'll want to open the passthrough device
10094 * associated with the specified device. In the case of the rescan
10095 * commands, we don't use a passthrough device at all, just the
10096 * transport layer device.
10098 if (devopen == 1) {
10099 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10100 && (((arglist & CAM_ARG_DEVICE) == 0)
10101 || ((arglist & CAM_ARG_UNIT) == 0))) {
10102 errx(1, "subcommand \"%s\" requires a valid device "
10103 "identifier", argv[1]);
10106 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10107 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10108 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10110 errx(1,"%s", cam_errbuf);
10114 * Reset optind to 2, and reset getopt, so these routines can parse
10115 * the arguments again.
10121 case CAM_CMD_DEVLIST:
10122 error = getdevlist(cam_dev);
10125 error = atahpa(cam_dev, retry_count, timeout,
10126 argc, argv, combinedopt);
10128 case CAM_CMD_DEVTREE:
10129 error = getdevtree(argc, argv, combinedopt);
10132 error = testunitready(cam_dev, task_attr, retry_count,
10135 case CAM_CMD_INQUIRY:
10136 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10137 task_attr, retry_count, timeout);
10139 case CAM_CMD_IDENTIFY:
10140 error = identify(cam_dev, retry_count, timeout);
10142 case CAM_CMD_STARTSTOP:
10143 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10144 arglist & CAM_ARG_EJECT, task_attr,
10145 retry_count, timeout);
10147 case CAM_CMD_RESCAN:
10148 error = dorescan_or_reset(argc, argv, 1);
10150 case CAM_CMD_RESET:
10151 error = dorescan_or_reset(argc, argv, 0);
10153 case CAM_CMD_READ_DEFECTS:
10154 error = readdefects(cam_dev, argc, argv, combinedopt,
10155 task_attr, retry_count, timeout);
10157 case CAM_CMD_MODE_PAGE:
10158 modepage(cam_dev, argc, argv, combinedopt,
10159 task_attr, retry_count, timeout);
10161 case CAM_CMD_SCSI_CMD:
10162 error = scsicmd(cam_dev, argc, argv, combinedopt,
10163 task_attr, retry_count, timeout);
10165 case CAM_CMD_MMCSD_CMD:
10166 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10167 retry_count, timeout);
10169 case CAM_CMD_SMP_CMD:
10170 error = smpcmd(cam_dev, argc, argv, combinedopt,
10171 retry_count, timeout);
10173 case CAM_CMD_SMP_RG:
10174 error = smpreportgeneral(cam_dev, argc, argv,
10175 combinedopt, retry_count,
10178 case CAM_CMD_SMP_PC:
10179 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10180 retry_count, timeout);
10182 case CAM_CMD_SMP_PHYLIST:
10183 error = smpphylist(cam_dev, argc, argv, combinedopt,
10184 retry_count, timeout);
10186 case CAM_CMD_SMP_MANINFO:
10187 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10188 retry_count, timeout);
10190 case CAM_CMD_DEBUG:
10191 error = camdebug(argc, argv, combinedopt);
10194 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10197 error = ratecontrol(cam_dev, task_attr, retry_count,
10198 timeout, argc, argv, combinedopt);
10200 case CAM_CMD_FORMAT:
10201 error = scsiformat(cam_dev, argc, argv,
10202 combinedopt, task_attr, retry_count,
10205 case CAM_CMD_REPORTLUNS:
10206 error = scsireportluns(cam_dev, argc, argv,
10207 combinedopt, task_attr,
10208 retry_count, timeout);
10210 case CAM_CMD_READCAP:
10211 error = scsireadcapacity(cam_dev, argc, argv,
10212 combinedopt, task_attr,
10213 retry_count, timeout);
10216 case CAM_CMD_STANDBY:
10217 case CAM_CMD_SLEEP:
10218 case CAM_CMD_POWER_MODE:
10219 error = atapm(cam_dev, argc, argv,
10220 combinedopt, retry_count, timeout);
10224 error = ataaxm(cam_dev, argc, argv,
10225 combinedopt, retry_count, timeout);
10227 case CAM_CMD_SECURITY:
10228 error = atasecurity(cam_dev, retry_count, timeout,
10229 argc, argv, combinedopt);
10231 case CAM_CMD_DOWNLOAD_FW:
10232 error = fwdownload(cam_dev, argc, argv, combinedopt,
10233 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10236 case CAM_CMD_SANITIZE:
10237 error = scsisanitize(cam_dev, argc, argv,
10238 combinedopt, task_attr,
10239 retry_count, timeout);
10241 case CAM_CMD_PERSIST:
10242 error = scsipersist(cam_dev, argc, argv, combinedopt,
10243 task_attr, retry_count, timeout,
10244 arglist & CAM_ARG_VERBOSE,
10245 arglist & CAM_ARG_ERR_RECOVER);
10247 case CAM_CMD_ATTRIB:
10248 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10249 task_attr, retry_count, timeout,
10250 arglist & CAM_ARG_VERBOSE,
10251 arglist & CAM_ARG_ERR_RECOVER);
10253 case CAM_CMD_OPCODES:
10254 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10255 task_attr, retry_count, timeout,
10256 arglist & CAM_ARG_VERBOSE);
10258 case CAM_CMD_REPROBE:
10259 error = scsireprobe(cam_dev);
10262 error = zone(cam_dev, argc, argv, combinedopt,
10263 task_attr, retry_count, timeout,
10264 arglist & CAM_ARG_VERBOSE);
10267 error = epc(cam_dev, argc, argv, combinedopt,
10268 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10270 case CAM_CMD_TIMESTAMP:
10271 error = timestamp(cam_dev, argc, argv, combinedopt,
10272 task_attr, retry_count, timeout,
10273 arglist & CAM_ARG_VERBOSE);
10275 case CAM_CMD_USAGE:
10284 if (cam_dev != NULL)
10285 cam_close_device(cam_dev);