2 * Copyright (c) 1997-2007 Kenneth D. Merry
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/ioctl.h>
33 #include <sys/stdint.h>
34 #include <sys/types.h>
36 #include <sys/endian.h>
55 #include <cam/cam_debug.h>
56 #include <cam/cam_ccb.h>
57 #include <cam/scsi/scsi_all.h>
58 #include <cam/scsi/scsi_da.h>
59 #include <cam/scsi/scsi_pass.h>
60 #include <cam/scsi/scsi_message.h>
61 #include <cam/scsi/smp_all.h>
62 #include <cam/ata/ata_all.h>
63 #include <cam/mmc/mmc_all.h>
65 #include "camcontrol.h"
66 #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
114 CAM_ARG_NONE = 0x00000000,
115 CAM_ARG_VERBOSE = 0x00000001,
116 CAM_ARG_DEVICE = 0x00000002,
117 CAM_ARG_BUS = 0x00000004,
118 CAM_ARG_TARGET = 0x00000008,
119 CAM_ARG_LUN = 0x00000010,
120 CAM_ARG_EJECT = 0x00000020,
121 CAM_ARG_UNIT = 0x00000040,
122 CAM_ARG_FORMAT_BLOCK = 0x00000080,
123 CAM_ARG_FORMAT_BFI = 0x00000100,
124 CAM_ARG_FORMAT_PHYS = 0x00000200,
125 CAM_ARG_PLIST = 0x00000400,
126 CAM_ARG_GLIST = 0x00000800,
127 CAM_ARG_GET_SERIAL = 0x00001000,
128 CAM_ARG_GET_STDINQ = 0x00002000,
129 CAM_ARG_GET_XFERRATE = 0x00004000,
130 CAM_ARG_INQ_MASK = 0x00007000,
131 CAM_ARG_TIMEOUT = 0x00020000,
132 CAM_ARG_CMD_IN = 0x00040000,
133 CAM_ARG_CMD_OUT = 0x00080000,
134 CAM_ARG_ERR_RECOVER = 0x00200000,
135 CAM_ARG_RETRIES = 0x00400000,
136 CAM_ARG_START_UNIT = 0x00800000,
137 CAM_ARG_DEBUG_INFO = 0x01000000,
138 CAM_ARG_DEBUG_TRACE = 0x02000000,
139 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
140 CAM_ARG_DEBUG_CDB = 0x08000000,
141 CAM_ARG_DEBUG_XPT = 0x10000000,
142 CAM_ARG_DEBUG_PERIPH = 0x20000000,
143 CAM_ARG_DEBUG_PROBE = 0x40000000,
146 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";
194 static struct camcontrol_opts option_table[] = {
196 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
197 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
198 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
199 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
200 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
201 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
202 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
203 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
204 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
205 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
206 #endif /* MINIMALISTIC */
207 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
208 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
210 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
211 {"mmcsdcmd", CAM_CMD_MMCSD_CMD, CAM_ARG_NONE, "c:a:f:Wb:l:41S:I"},
212 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
213 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
214 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
215 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
216 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
217 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
218 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
219 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
220 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
221 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
222 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
223 #endif /* MINIMALISTIC */
224 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
226 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
227 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
228 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
229 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
230 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
231 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
232 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
233 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
234 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
235 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
236 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
237 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
238 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
239 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
240 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
241 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
242 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
243 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
244 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
245 {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
246 {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
247 {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
248 #endif /* MINIMALISTIC */
249 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
250 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
251 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
256 struct device_match_result dev_match;
258 struct periph_match_result *periph_matches;
259 struct scsi_vpd_device_id *device_id;
261 STAILQ_ENTRY(cam_devitem) links;
265 STAILQ_HEAD(, cam_devitem) dev_queue;
269 static cam_cmdmask cmdlist;
270 static cam_argmask arglist;
272 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
273 uint32_t *cmdnum, cam_argmask *argnum,
274 const char **subopt);
276 static int getdevlist(struct cam_device *device);
277 #endif /* MINIMALISTIC */
278 static int getdevtree(int argc, char **argv, char *combinedopt);
279 static int print_dev_scsi(struct device_match_result *dev_result, char *tmpstr);
280 static int print_dev_ata(struct device_match_result *dev_result, char *tmpstr);
281 static int print_dev_semb(struct device_match_result *dev_result, char *tmpstr);
282 static int print_dev_mmcsd(struct device_match_result *dev_result,
284 static int print_dev_nvme(struct device_match_result *dev_result, char *tmpstr);
286 static int testunitready(struct cam_device *device, int task_attr,
287 int retry_count, int timeout, int quiet);
288 static int scsistart(struct cam_device *device, int startstop, int loadeject,
289 int task_attr, int retry_count, int timeout);
290 static int scsiinquiry(struct cam_device *device, int task_attr,
291 int retry_count, int timeout);
292 static int scsiserial(struct cam_device *device, int task_attr,
293 int retry_count, int timeout);
294 #endif /* MINIMALISTIC */
295 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
296 lun_id_t *lun, cam_argmask *arglst);
297 static int dorescan_or_reset(int argc, char **argv, int rescan);
298 static int rescan_or_reset_bus(path_id_t bus, int rescan);
299 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
300 lun_id_t lun, int scan);
302 static int readdefects(struct cam_device *device, int argc, char **argv,
303 char *combinedopt, int task_attr, int retry_count,
305 static void modepage(struct cam_device *device, int argc, char **argv,
306 char *combinedopt, int task_attr, int retry_count,
308 static int scsicmd(struct cam_device *device, int argc, char **argv,
309 char *combinedopt, int task_attr, int retry_count,
311 static int smpcmd(struct cam_device *device, int argc, char **argv,
312 char *combinedopt, int retry_count, int timeout);
313 static int mmcsdcmd(struct cam_device *device, int argc, char **argv,
314 char *combinedopt, int retry_count, int timeout);
315 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
316 char *combinedopt, int retry_count, int timeout);
317 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
318 char *combinedopt, int retry_count, int timeout);
319 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
320 char *combinedopt, int retry_count, int timeout);
321 static int getdevid(struct cam_devitem *item);
322 static int buildbusdevlist(struct cam_devlist *devlist);
323 static void freebusdevlist(struct cam_devlist *devlist);
324 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
326 static int smpphylist(struct cam_device *device, int argc, char **argv,
327 char *combinedopt, int retry_count, int timeout);
328 static int tagcontrol(struct cam_device *device, int argc, char **argv,
330 static void cts_print(struct cam_device *device,
331 struct ccb_trans_settings *cts);
332 static void cpi_print(struct ccb_pathinq *cpi);
333 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
334 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
335 static int get_print_cts(struct cam_device *device, int user_settings,
336 int quiet, struct ccb_trans_settings *cts);
337 static int ratecontrol(struct cam_device *device, int task_attr,
338 int retry_count, int timeout, int argc, char **argv,
340 static int scsiformat(struct cam_device *device, int argc, char **argv,
341 char *combinedopt, int task_attr, int retry_count,
343 static int scsisanitize(struct cam_device *device, int argc, char **argv,
344 char *combinedopt, int task_attr, int retry_count,
346 static int scsireportluns(struct cam_device *device, int argc, char **argv,
347 char *combinedopt, int task_attr, int retry_count,
349 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
350 char *combinedopt, int task_attr, int retry_count,
352 static int atapm(struct cam_device *device, int argc, char **argv,
353 char *combinedopt, int retry_count, int timeout);
354 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
355 int argc, char **argv, char *combinedopt);
356 static int atahpa(struct cam_device *device, int retry_count, int timeout,
357 int argc, char **argv, char *combinedopt);
358 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
359 int sa_set, int req_sa, uint8_t *buf,
361 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
363 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
364 char *combinedopt, int task_attr, int retry_count,
365 int timeout, int verbose);
366 static int scsireprobe(struct cam_device *device);
368 #endif /* MINIMALISTIC */
370 #define min(a,b) (((a)<(b))?(a):(b))
373 #define max(a,b) (((a)>(b))?(a):(b))
377 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
378 cam_argmask *argnum, const char **subopt)
380 struct camcontrol_opts *opts;
383 for (opts = table; (opts != NULL) && (opts->optname != NULL);
385 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
386 *cmdnum = opts->cmdnum;
387 *argnum = opts->argnum;
388 *subopt = opts->subopt;
389 if (++num_matches > 1)
390 return (CC_OR_AMBIGUOUS);
395 return (CC_OR_FOUND);
397 return (CC_OR_NOT_FOUND);
402 getdevlist(struct cam_device *device)
408 ccb = cam_getccb(device);
410 ccb->ccb_h.func_code = XPT_GDEVLIST;
411 ccb->ccb_h.flags = CAM_DIR_NONE;
412 ccb->ccb_h.retry_count = 1;
414 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
415 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
416 if (cam_send_ccb(device, ccb) < 0) {
417 perror("error getting device list");
424 switch (ccb->cgdl.status) {
425 case CAM_GDEVLIST_MORE_DEVS:
426 strcpy(status, "MORE");
428 case CAM_GDEVLIST_LAST_DEVICE:
429 strcpy(status, "LAST");
431 case CAM_GDEVLIST_LIST_CHANGED:
432 strcpy(status, "CHANGED");
434 case CAM_GDEVLIST_ERROR:
435 strcpy(status, "ERROR");
440 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
441 ccb->cgdl.periph_name,
442 ccb->cgdl.unit_number,
443 ccb->cgdl.generation,
448 * If the list has changed, we need to start over from the
451 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
459 #endif /* MINIMALISTIC */
462 getdevtree(int argc, char **argv, char *combinedopt)
473 while ((c = getopt(argc, argv, combinedopt)) != -1) {
476 if ((arglist & CAM_ARG_VERBOSE) == 0)
484 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
485 warn("couldn't open %s", XPT_DEVICE);
489 bzero(&ccb, sizeof(union ccb));
491 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
492 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
493 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
495 ccb.ccb_h.func_code = XPT_DEV_MATCH;
496 bufsize = sizeof(struct dev_match_result) * 100;
497 ccb.cdm.match_buf_len = bufsize;
498 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
499 if (ccb.cdm.matches == NULL) {
500 warnx("can't malloc memory for matches");
504 ccb.cdm.num_matches = 0;
507 * We fetch all nodes, since we display most of them in the default
508 * case, and all in the verbose case.
510 ccb.cdm.num_patterns = 0;
511 ccb.cdm.pattern_buf_len = 0;
514 * We do the ioctl multiple times if necessary, in case there are
515 * more than 100 nodes in the EDT.
518 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
519 warn("error sending CAMIOCOMMAND ioctl");
524 if ((ccb.ccb_h.status != CAM_REQ_CMP)
525 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
526 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
527 warnx("got CAM error %#x, CDM error %d\n",
528 ccb.ccb_h.status, ccb.cdm.status);
533 for (i = 0; i < ccb.cdm.num_matches; i++) {
534 switch (ccb.cdm.matches[i].type) {
535 case DEV_MATCH_BUS: {
536 struct bus_match_result *bus_result;
539 * Only print the bus information if the
540 * user turns on the verbose flag.
542 if ((busonly == 0) &&
543 (arglist & CAM_ARG_VERBOSE) == 0)
547 &ccb.cdm.matches[i].result.bus_result;
550 fprintf(stdout, ")\n");
554 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
556 bus_result->dev_name,
557 bus_result->unit_number,
559 (busonly ? "" : ":"));
562 case DEV_MATCH_DEVICE: {
563 struct device_match_result *dev_result;
570 &ccb.cdm.matches[i].result.device_result;
572 if ((dev_result->flags
573 & DEV_RESULT_UNCONFIGURED)
574 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
580 if (dev_result->protocol == PROTO_SCSI) {
581 if (print_dev_scsi(dev_result,
586 } else if (dev_result->protocol == PROTO_ATA ||
587 dev_result->protocol == PROTO_SATAPM) {
588 if (print_dev_ata(dev_result,
593 } else if (dev_result->protocol == PROTO_MMCSD){
594 if (print_dev_mmcsd(dev_result,
599 } else if (dev_result->protocol == PROTO_SEMB) {
600 if (print_dev_semb(dev_result,
605 } else if (dev_result->protocol == PROTO_NVME) {
606 if (print_dev_nvme(dev_result,
612 sprintf(tmpstr, "<>");
615 fprintf(stdout, ")\n");
619 fprintf(stdout, "%-33s at scbus%d "
620 "target %d lun %jx (",
623 dev_result->target_id,
624 (uintmax_t)dev_result->target_lun);
630 case DEV_MATCH_PERIPH: {
631 struct periph_match_result *periph_result;
634 &ccb.cdm.matches[i].result.periph_result;
636 if (busonly || skip_device != 0)
640 fprintf(stdout, ",");
642 fprintf(stdout, "%s%d",
643 periph_result->periph_name,
644 periph_result->unit_number);
650 fprintf(stdout, "unknown match type\n");
655 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
656 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
659 fprintf(stdout, ")\n");
667 print_dev_scsi(struct device_match_result *dev_result, char *tmpstr)
669 char vendor[16], product[48], revision[16];
671 cam_strvis(vendor, dev_result->inq_data.vendor,
672 sizeof(dev_result->inq_data.vendor), sizeof(vendor));
673 cam_strvis(product, dev_result->inq_data.product,
674 sizeof(dev_result->inq_data.product), sizeof(product));
675 cam_strvis(revision, dev_result->inq_data.revision,
676 sizeof(dev_result->inq_data.revision), sizeof(revision));
677 sprintf(tmpstr, "<%s %s %s>", vendor, product, revision);
683 print_dev_ata(struct device_match_result *dev_result, char *tmpstr)
685 char product[48], revision[16];
687 cam_strvis(product, dev_result->ident_data.model,
688 sizeof(dev_result->ident_data.model), sizeof(product));
689 cam_strvis(revision, dev_result->ident_data.revision,
690 sizeof(dev_result->ident_data.revision), sizeof(revision));
691 sprintf(tmpstr, "<%s %s>", product, revision);
697 print_dev_semb(struct device_match_result *dev_result, char *tmpstr)
699 struct sep_identify_data *sid;
700 char vendor[16], product[48], revision[16], fw[5];
702 sid = (struct sep_identify_data *)&dev_result->ident_data;
703 cam_strvis(vendor, sid->vendor_id,
704 sizeof(sid->vendor_id), sizeof(vendor));
705 cam_strvis(product, sid->product_id,
706 sizeof(sid->product_id), sizeof(product));
707 cam_strvis(revision, sid->product_rev,
708 sizeof(sid->product_rev), sizeof(revision));
709 cam_strvis(fw, sid->firmware_rev,
710 sizeof(sid->firmware_rev), sizeof(fw));
711 sprintf(tmpstr, "<%s %s %s %s>", vendor, product, revision, fw);
717 print_dev_mmcsd(struct device_match_result *dev_result, char *tmpstr)
720 struct ccb_dev_advinfo *advi;
721 struct cam_device *dev;
722 struct mmc_params mmc_ident_data;
724 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
725 dev_result->target_lun, O_RDWR, NULL);
727 warnx("%s", cam_errbuf);
731 ccb = cam_getccb(dev);
733 warnx("couldn't allocate CCB");
734 cam_close_device(dev);
739 advi->ccb_h.flags = CAM_DIR_IN;
740 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
741 advi->flags = CDAI_FLAG_NONE;
742 advi->buftype = CDAI_TYPE_MMC_PARAMS;
743 advi->bufsiz = sizeof(struct mmc_params);
744 advi->buf = (uint8_t *)&mmc_ident_data;
746 if (cam_send_ccb(dev, ccb) < 0) {
747 warn("error sending CAMIOCOMMAND ioctl");
749 cam_close_device(dev);
753 if (strlen(mmc_ident_data.model) > 0) {
754 sprintf(tmpstr, "<%s>", mmc_ident_data.model);
756 sprintf(tmpstr, "<%s card>",
757 mmc_ident_data.card_features &
758 CARD_FEATURE_SDIO ? "SDIO" : "unknown");
762 cam_close_device(dev);
767 nvme_get_cdata(struct cam_device *dev, struct nvme_controller_data *cdata)
770 struct ccb_dev_advinfo *advi;
772 ccb = cam_getccb(dev);
774 warnx("couldn't allocate CCB");
775 cam_close_device(dev);
780 advi->ccb_h.flags = CAM_DIR_IN;
781 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
782 advi->flags = CDAI_FLAG_NONE;
783 advi->buftype = CDAI_TYPE_NVME_CNTRL;
784 advi->bufsiz = sizeof(struct nvme_controller_data);
785 advi->buf = (uint8_t *)cdata;
787 if (cam_send_ccb(dev, ccb) < 0) {
788 warn("error sending CAMIOCOMMAND ioctl");
790 cam_close_device(dev);
793 if (advi->ccb_h.status != CAM_REQ_CMP) {
794 warnx("got CAM error %#x", advi->ccb_h.status);
796 cam_close_device(dev);
804 print_dev_nvme(struct device_match_result *dev_result, char *tmpstr)
806 struct cam_device *dev;
807 struct nvme_controller_data cdata;
808 char vendor[64], product[64];
810 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
811 dev_result->target_lun, O_RDWR, NULL);
813 warnx("%s", cam_errbuf);
817 if (nvme_get_cdata(dev, &cdata))
820 cam_strvis(vendor, cdata.mn, sizeof(cdata.mn), sizeof(vendor));
821 cam_strvis(product, cdata.fr, sizeof(cdata.fr), sizeof(product));
822 sprintf(tmpstr, "<%s %s>", vendor, product);
824 cam_close_device(dev);
830 testunitready(struct cam_device *device, int task_attr, int retry_count,
831 int timeout, int quiet)
836 ccb = cam_getccb(device);
838 scsi_test_unit_ready(&ccb->csio,
839 /* retries */ retry_count,
841 /* tag_action */ task_attr,
842 /* sense_len */ SSD_FULL_SIZE,
843 /* timeout */ timeout ? timeout : 5000);
845 /* Disable freezing the device queue */
846 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
848 if (arglist & CAM_ARG_ERR_RECOVER)
849 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
851 if (cam_send_ccb(device, ccb) < 0) {
853 perror("error sending test unit ready");
855 if (arglist & CAM_ARG_VERBOSE) {
856 cam_error_print(device, ccb, CAM_ESF_ALL,
857 CAM_EPF_ALL, stderr);
864 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
866 fprintf(stdout, "Unit is ready\n");
869 fprintf(stdout, "Unit is not ready\n");
872 if (arglist & CAM_ARG_VERBOSE) {
873 cam_error_print(device, ccb, CAM_ESF_ALL,
874 CAM_EPF_ALL, stderr);
884 scsistart(struct cam_device *device, int startstop, int loadeject,
885 int task_attr, int retry_count, int timeout)
890 ccb = cam_getccb(device);
893 * If we're stopping, send an ordered tag so the drive in question
894 * will finish any previously queued writes before stopping. If
895 * the device isn't capable of tagged queueing, or if tagged
896 * queueing is turned off, the tag action is a no-op. We override
897 * the default simple tag, although this also has the effect of
898 * overriding the user's wishes if he wanted to specify a simple
902 && (task_attr == MSG_SIMPLE_Q_TAG))
903 task_attr = MSG_ORDERED_Q_TAG;
905 scsi_start_stop(&ccb->csio,
906 /* retries */ retry_count,
908 /* tag_action */ task_attr,
909 /* start/stop */ startstop,
910 /* load_eject */ loadeject,
912 /* sense_len */ SSD_FULL_SIZE,
913 /* timeout */ timeout ? timeout : 120000);
915 /* Disable freezing the device queue */
916 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
918 if (arglist & CAM_ARG_ERR_RECOVER)
919 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
921 if (cam_send_ccb(device, ccb) < 0) {
922 perror("error sending start unit");
924 if (arglist & CAM_ARG_VERBOSE) {
925 cam_error_print(device, ccb, CAM_ESF_ALL,
926 CAM_EPF_ALL, stderr);
933 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
935 fprintf(stdout, "Unit started successfully");
937 fprintf(stdout,", Media loaded\n");
939 fprintf(stdout,"\n");
941 fprintf(stdout, "Unit stopped successfully");
943 fprintf(stdout, ", Media ejected\n");
945 fprintf(stdout, "\n");
951 "Error received from start unit command\n");
954 "Error received from stop unit command\n");
956 if (arglist & CAM_ARG_VERBOSE) {
957 cam_error_print(device, ccb, CAM_ESF_ALL,
958 CAM_EPF_ALL, stderr);
968 scsidoinquiry(struct cam_device *device, int argc, char **argv,
969 char *combinedopt, int task_attr, int retry_count, int timeout)
974 while ((c = getopt(argc, argv, combinedopt)) != -1) {
977 arglist |= CAM_ARG_GET_STDINQ;
980 arglist |= CAM_ARG_GET_XFERRATE;
983 arglist |= CAM_ARG_GET_SERIAL;
991 * If the user didn't specify any inquiry options, he wants all of
994 if ((arglist & CAM_ARG_INQ_MASK) == 0)
995 arglist |= CAM_ARG_INQ_MASK;
997 if (arglist & CAM_ARG_GET_STDINQ)
998 error = scsiinquiry(device, task_attr, retry_count, timeout);
1003 if (arglist & CAM_ARG_GET_SERIAL)
1004 scsiserial(device, task_attr, retry_count, timeout);
1006 if (arglist & CAM_ARG_GET_XFERRATE)
1007 error = camxferrate(device);
1013 scsiinquiry(struct cam_device *device, int task_attr, int retry_count,
1017 struct scsi_inquiry_data *inq_buf;
1020 ccb = cam_getccb(device);
1023 warnx("couldn't allocate CCB");
1027 /* cam_getccb cleans up the header, caller has to zero the payload */
1028 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1030 inq_buf = (struct scsi_inquiry_data *)malloc(
1031 sizeof(struct scsi_inquiry_data));
1033 if (inq_buf == NULL) {
1035 warnx("can't malloc memory for inquiry\n");
1038 bzero(inq_buf, sizeof(*inq_buf));
1041 * Note that although the size of the inquiry buffer is the full
1042 * 256 bytes specified in the SCSI spec, we only tell the device
1043 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
1044 * two reasons for this:
1046 * - The SCSI spec says that when a length field is only 1 byte,
1047 * a value of 0 will be interpreted as 256. Therefore
1048 * scsi_inquiry() will convert an inq_len (which is passed in as
1049 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
1050 * to 0. Evidently, very few devices meet the spec in that
1051 * regard. Some devices, like many Seagate disks, take the 0 as
1052 * 0, and don't return any data. One Pioneer DVD-R drive
1053 * returns more data than the command asked for.
1055 * So, since there are numerous devices that just don't work
1056 * right with the full inquiry size, we don't send the full size.
1058 * - The second reason not to use the full inquiry data length is
1059 * that we don't need it here. The only reason we issue a
1060 * standard inquiry is to get the vendor name, device name,
1061 * and revision so scsi_print_inquiry() can print them.
1063 * If, at some point in the future, more inquiry data is needed for
1064 * some reason, this code should use a procedure similar to the
1065 * probe code. i.e., issue a short inquiry, and determine from
1066 * the additional length passed back from the device how much
1067 * inquiry data the device supports. Once the amount the device
1068 * supports is determined, issue an inquiry for that amount and no
1073 scsi_inquiry(&ccb->csio,
1074 /* retries */ retry_count,
1076 /* tag_action */ task_attr,
1077 /* inq_buf */ (u_int8_t *)inq_buf,
1078 /* inq_len */ SHORT_INQUIRY_LENGTH,
1081 /* sense_len */ SSD_FULL_SIZE,
1082 /* timeout */ timeout ? timeout : 5000);
1084 /* Disable freezing the device queue */
1085 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1087 if (arglist & CAM_ARG_ERR_RECOVER)
1088 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1090 if (cam_send_ccb(device, ccb) < 0) {
1091 perror("error sending SCSI inquiry");
1093 if (arglist & CAM_ARG_VERBOSE) {
1094 cam_error_print(device, ccb, CAM_ESF_ALL,
1095 CAM_EPF_ALL, stderr);
1102 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1105 if (arglist & CAM_ARG_VERBOSE) {
1106 cam_error_print(device, ccb, CAM_ESF_ALL,
1107 CAM_EPF_ALL, stderr);
1118 fprintf(stdout, "%s%d: ", device->device_name,
1119 device->dev_unit_num);
1120 scsi_print_inquiry(inq_buf);
1128 scsiserial(struct cam_device *device, int task_attr, int retry_count,
1132 struct scsi_vpd_unit_serial_number *serial_buf;
1133 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
1136 ccb = cam_getccb(device);
1139 warnx("couldn't allocate CCB");
1143 /* cam_getccb cleans up the header, caller has to zero the payload */
1144 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1146 serial_buf = (struct scsi_vpd_unit_serial_number *)
1147 malloc(sizeof(*serial_buf));
1149 if (serial_buf == NULL) {
1151 warnx("can't malloc memory for serial number");
1155 scsi_inquiry(&ccb->csio,
1156 /*retries*/ retry_count,
1158 /* tag_action */ task_attr,
1159 /* inq_buf */ (u_int8_t *)serial_buf,
1160 /* inq_len */ sizeof(*serial_buf),
1162 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
1163 /* sense_len */ SSD_FULL_SIZE,
1164 /* timeout */ timeout ? timeout : 5000);
1166 /* Disable freezing the device queue */
1167 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1169 if (arglist & CAM_ARG_ERR_RECOVER)
1170 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1172 if (cam_send_ccb(device, ccb) < 0) {
1173 warn("error getting serial number");
1175 if (arglist & CAM_ARG_VERBOSE) {
1176 cam_error_print(device, ccb, CAM_ESF_ALL,
1177 CAM_EPF_ALL, stderr);
1185 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1188 if (arglist & CAM_ARG_VERBOSE) {
1189 cam_error_print(device, ccb, CAM_ESF_ALL,
1190 CAM_EPF_ALL, stderr);
1201 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1202 serial_num[serial_buf->length] = '\0';
1204 if ((arglist & CAM_ARG_GET_STDINQ)
1205 || (arglist & CAM_ARG_GET_XFERRATE))
1206 fprintf(stdout, "%s%d: Serial Number ",
1207 device->device_name, device->dev_unit_num);
1209 fprintf(stdout, "%.60s\n", serial_num);
1217 camxferrate(struct cam_device *device)
1219 struct ccb_pathinq cpi;
1221 u_int32_t speed = 0;
1226 if ((retval = get_cpi(device, &cpi)) != 0)
1229 ccb = cam_getccb(device);
1232 warnx("couldn't allocate CCB");
1236 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
1238 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1239 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1241 if (((retval = cam_send_ccb(device, ccb)) < 0)
1242 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1243 const char error_string[] = "error getting transfer settings";
1248 warnx(error_string);
1250 if (arglist & CAM_ARG_VERBOSE)
1251 cam_error_print(device, ccb, CAM_ESF_ALL,
1252 CAM_EPF_ALL, stderr);
1256 goto xferrate_bailout;
1260 speed = cpi.base_transfer_speed;
1262 if (ccb->cts.transport == XPORT_SPI) {
1263 struct ccb_trans_settings_spi *spi =
1264 &ccb->cts.xport_specific.spi;
1266 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1267 freq = scsi_calc_syncsrate(spi->sync_period);
1270 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1271 speed *= (0x01 << spi->bus_width);
1273 } else if (ccb->cts.transport == XPORT_FC) {
1274 struct ccb_trans_settings_fc *fc =
1275 &ccb->cts.xport_specific.fc;
1277 if (fc->valid & CTS_FC_VALID_SPEED)
1278 speed = fc->bitrate;
1279 } else if (ccb->cts.transport == XPORT_SAS) {
1280 struct ccb_trans_settings_sas *sas =
1281 &ccb->cts.xport_specific.sas;
1283 if (sas->valid & CTS_SAS_VALID_SPEED)
1284 speed = sas->bitrate;
1285 } else if (ccb->cts.transport == XPORT_ATA) {
1286 struct ccb_trans_settings_pata *pata =
1287 &ccb->cts.xport_specific.ata;
1289 if (pata->valid & CTS_ATA_VALID_MODE)
1290 speed = ata_mode2speed(pata->mode);
1291 } else if (ccb->cts.transport == XPORT_SATA) {
1292 struct ccb_trans_settings_sata *sata =
1293 &ccb->cts.xport_specific.sata;
1295 if (sata->valid & CTS_SATA_VALID_REVISION)
1296 speed = ata_revision2speed(sata->revision);
1301 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1302 device->device_name, device->dev_unit_num,
1305 fprintf(stdout, "%s%d: %dKB/s transfers",
1306 device->device_name, device->dev_unit_num,
1310 if (ccb->cts.transport == XPORT_SPI) {
1311 struct ccb_trans_settings_spi *spi =
1312 &ccb->cts.xport_specific.spi;
1314 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1315 && (spi->sync_offset != 0))
1316 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1317 freq % 1000, spi->sync_offset);
1319 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1320 && (spi->bus_width > 0)) {
1321 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1322 && (spi->sync_offset != 0)) {
1323 fprintf(stdout, ", ");
1325 fprintf(stdout, " (");
1327 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1328 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1329 && (spi->sync_offset != 0)) {
1330 fprintf(stdout, ")");
1332 } else if (ccb->cts.transport == XPORT_ATA) {
1333 struct ccb_trans_settings_pata *pata =
1334 &ccb->cts.xport_specific.ata;
1337 if (pata->valid & CTS_ATA_VALID_MODE)
1338 printf("%s, ", ata_mode2string(pata->mode));
1339 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1340 printf("ATAPI %dbytes, ", pata->atapi);
1341 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1342 printf("PIO %dbytes", pata->bytecount);
1344 } else if (ccb->cts.transport == XPORT_SATA) {
1345 struct ccb_trans_settings_sata *sata =
1346 &ccb->cts.xport_specific.sata;
1349 if (sata->valid & CTS_SATA_VALID_REVISION)
1350 printf("SATA %d.x, ", sata->revision);
1353 if (sata->valid & CTS_SATA_VALID_MODE)
1354 printf("%s, ", ata_mode2string(sata->mode));
1355 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1356 printf("ATAPI %dbytes, ", sata->atapi);
1357 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1358 printf("PIO %dbytes", sata->bytecount);
1362 if (ccb->cts.protocol == PROTO_SCSI) {
1363 struct ccb_trans_settings_scsi *scsi =
1364 &ccb->cts.proto_specific.scsi;
1365 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1366 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1367 fprintf(stdout, ", Command Queueing Enabled");
1372 fprintf(stdout, "\n");
1382 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1384 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1385 ((u_int32_t)parm->lba_size_2 << 16);
1387 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1388 ((u_int64_t)parm->lba_size48_2 << 16) |
1389 ((u_int64_t)parm->lba_size48_3 << 32) |
1390 ((u_int64_t)parm->lba_size48_4 << 48);
1394 "Support Enabled Value\n");
1397 printf("Host Protected Area (HPA) ");
1398 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1399 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1400 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1403 printf("HPA - Security ");
1404 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1414 atasata(struct ata_params *parm)
1418 if (parm->satacapabilities != 0xffff &&
1419 parm->satacapabilities != 0x0000)
1426 atacapprint(struct ata_params *parm)
1428 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1429 ((u_int32_t)parm->lba_size_2 << 16);
1431 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1432 ((u_int64_t)parm->lba_size48_2 << 16) |
1433 ((u_int64_t)parm->lba_size48_3 << 32) |
1434 ((u_int64_t)parm->lba_size48_4 << 48);
1437 printf("protocol ");
1438 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1439 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1440 if (parm->satacapabilities & ATA_SATA_GEN3)
1441 printf(" SATA 3.x\n");
1442 else if (parm->satacapabilities & ATA_SATA_GEN2)
1443 printf(" SATA 2.x\n");
1444 else if (parm->satacapabilities & ATA_SATA_GEN1)
1445 printf(" SATA 1.x\n");
1451 printf("device model %.40s\n", parm->model);
1452 printf("firmware revision %.8s\n", parm->revision);
1453 printf("serial number %.20s\n", parm->serial);
1454 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1455 printf("WWN %04x%04x%04x%04x\n",
1456 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1458 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1459 printf("media serial number %.30s\n",
1460 parm->media_serial);
1463 printf("cylinders %d\n", parm->cylinders);
1464 printf("heads %d\n", parm->heads);
1465 printf("sectors/track %d\n", parm->sectors);
1466 printf("sector size logical %u, physical %lu, offset %lu\n",
1467 ata_logical_sector_size(parm),
1468 (unsigned long)ata_physical_sector_size(parm),
1469 (unsigned long)ata_logical_sector_offset(parm));
1471 if (parm->config == ATA_PROTO_CFA ||
1472 (parm->support.command2 & ATA_SUPPORT_CFA))
1473 printf("CFA supported\n");
1475 printf("LBA%ssupported ",
1476 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1478 printf("%d sectors\n", lbasize);
1482 printf("LBA48%ssupported ",
1483 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1485 printf("%ju sectors\n", (uintmax_t)lbasize48);
1489 printf("PIO supported PIO");
1490 switch (ata_max_pmode(parm)) {
1506 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1507 printf(" w/o IORDY");
1510 printf("DMA%ssupported ",
1511 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1512 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1513 if (parm->mwdmamodes & 0xff) {
1515 if (parm->mwdmamodes & 0x04)
1517 else if (parm->mwdmamodes & 0x02)
1519 else if (parm->mwdmamodes & 0x01)
1523 if ((parm->atavalid & ATA_FLAG_88) &&
1524 (parm->udmamodes & 0xff)) {
1526 if (parm->udmamodes & 0x40)
1528 else if (parm->udmamodes & 0x20)
1530 else if (parm->udmamodes & 0x10)
1532 else if (parm->udmamodes & 0x08)
1534 else if (parm->udmamodes & 0x04)
1536 else if (parm->udmamodes & 0x02)
1538 else if (parm->udmamodes & 0x01)
1545 if (parm->media_rotation_rate == 1) {
1546 printf("media RPM non-rotating\n");
1547 } else if (parm->media_rotation_rate >= 0x0401 &&
1548 parm->media_rotation_rate <= 0xFFFE) {
1549 printf("media RPM %d\n",
1550 parm->media_rotation_rate);
1553 printf("Zoned-Device Commands ");
1554 switch (parm->support3 & ATA_SUPPORT_ZONE_MASK) {
1555 case ATA_SUPPORT_ZONE_DEV_MANAGED:
1556 printf("device managed\n");
1558 case ATA_SUPPORT_ZONE_HOST_AWARE:
1559 printf("host aware\n");
1566 "Support Enabled Value Vendor\n");
1567 printf("read ahead %s %s\n",
1568 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1569 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1570 printf("write cache %s %s\n",
1571 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1572 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1573 printf("flush cache %s %s\n",
1574 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1575 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1576 printf("overlap %s\n",
1577 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1578 printf("Tagged Command Queuing (TCQ) %s %s",
1579 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1580 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1581 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1582 printf(" %d tags\n",
1583 ATA_QUEUE_LEN(parm->queue) + 1);
1586 printf("Native Command Queuing (NCQ) ");
1587 if (parm->satacapabilities != 0xffff &&
1588 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1589 printf("yes %d tags\n",
1590 ATA_QUEUE_LEN(parm->queue) + 1);
1594 printf("NCQ Queue Management %s\n", atasata(parm) &&
1595 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1597 printf("NCQ Streaming %s\n", atasata(parm) &&
1598 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1600 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1601 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1604 printf("SMART %s %s\n",
1605 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1606 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1607 printf("microcode download %s %s\n",
1608 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1609 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1610 printf("security %s %s\n",
1611 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1612 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1613 printf("power management %s %s\n",
1614 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1615 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1616 printf("advanced power management %s %s",
1617 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1618 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1619 if (parm->support.command2 & ATA_SUPPORT_APM) {
1620 printf(" %d/0x%02X\n",
1621 parm->apm_value & 0xff, parm->apm_value & 0xff);
1624 printf("automatic acoustic management %s %s",
1625 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1626 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1627 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1628 printf(" %d/0x%02X %d/0x%02X\n",
1629 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1630 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1631 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1632 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1635 printf("media status notification %s %s\n",
1636 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1637 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1638 printf("power-up in Standby %s %s\n",
1639 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1640 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1641 printf("write-read-verify %s %s",
1642 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1643 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1644 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1645 printf(" %d/0x%x\n",
1646 parm->wrv_mode, parm->wrv_mode);
1649 printf("unload %s %s\n",
1650 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1651 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1652 printf("general purpose logging %s %s\n",
1653 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1654 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1655 printf("free-fall %s %s\n",
1656 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1657 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1658 printf("Data Set Management (DSM/TRIM) ");
1659 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1661 printf("DSM - max 512byte blocks ");
1662 if (parm->max_dsm_blocks == 0x00)
1663 printf("yes not specified\n");
1666 parm->max_dsm_blocks);
1668 printf("DSM - deterministic read ");
1669 if (parm->support3 & ATA_SUPPORT_DRAT) {
1670 if (parm->support3 & ATA_SUPPORT_RZAT)
1671 printf("yes zeroed\n");
1673 printf("yes any value\n");
1683 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1685 struct ata_pass_16 *ata_pass_16;
1686 struct ata_cmd ata_cmd;
1688 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1689 ata_cmd.command = ata_pass_16->command;
1690 ata_cmd.control = ata_pass_16->control;
1691 ata_cmd.features = ata_pass_16->features;
1693 if (arglist & CAM_ARG_VERBOSE) {
1694 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1695 ata_op_string(&ata_cmd),
1696 ccb->csio.ccb_h.timeout);
1699 /* Disable freezing the device queue */
1700 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1702 if (arglist & CAM_ARG_ERR_RECOVER)
1703 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1705 if (cam_send_ccb(device, ccb) < 0) {
1706 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1707 warn("error sending ATA %s via pass_16",
1708 ata_op_string(&ata_cmd));
1711 if (arglist & CAM_ARG_VERBOSE) {
1712 cam_error_print(device, ccb, CAM_ESF_ALL,
1713 CAM_EPF_ALL, stderr);
1719 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1720 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1721 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1722 warnx("ATA %s via pass_16 failed",
1723 ata_op_string(&ata_cmd));
1725 if (arglist & CAM_ARG_VERBOSE) {
1726 cam_error_print(device, ccb, CAM_ESF_ALL,
1727 CAM_EPF_ALL, stderr);
1738 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1740 if (arglist & CAM_ARG_VERBOSE) {
1741 warnx("sending ATA %s with timeout of %u msecs",
1742 ata_op_string(&(ccb->ataio.cmd)),
1743 ccb->ataio.ccb_h.timeout);
1746 /* Disable freezing the device queue */
1747 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1749 if (arglist & CAM_ARG_ERR_RECOVER)
1750 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1752 if (cam_send_ccb(device, ccb) < 0) {
1753 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1754 warn("error sending ATA %s",
1755 ata_op_string(&(ccb->ataio.cmd)));
1758 if (arglist & CAM_ARG_VERBOSE) {
1759 cam_error_print(device, ccb, CAM_ESF_ALL,
1760 CAM_EPF_ALL, stderr);
1766 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1767 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1768 warnx("ATA %s failed: %d",
1769 ata_op_string(&(ccb->ataio.cmd)), quiet);
1772 if (arglist & CAM_ARG_VERBOSE) {
1773 cam_error_print(device, ccb, CAM_ESF_ALL,
1774 CAM_EPF_ALL, stderr);
1784 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1785 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1786 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1787 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1788 u_int16_t dxfer_len, int timeout, int quiet)
1790 if (data_ptr != NULL) {
1791 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1792 AP_FLAG_TLEN_SECT_CNT;
1793 if (flags & CAM_DIR_OUT)
1794 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1796 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1798 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1801 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1803 scsi_ata_pass_16(&ccb->csio,
1817 /*sense_len*/SSD_FULL_SIZE,
1820 return scsi_cam_pass_16_send(device, ccb, quiet);
1824 ata_try_pass_16(struct cam_device *device)
1826 struct ccb_pathinq cpi;
1828 if (get_cpi(device, &cpi) != 0) {
1829 warnx("couldn't get CPI");
1833 if (cpi.protocol == PROTO_SCSI) {
1834 /* possibly compatible with pass_16 */
1838 /* likely not compatible with pass_16 */
1843 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1844 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1845 u_int8_t command, u_int8_t features, u_int32_t lba,
1846 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1847 int timeout, int quiet)
1851 switch (ata_try_pass_16(device)) {
1855 /* Try using SCSI Passthrough */
1856 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1857 0, tag_action, command, features, lba,
1858 sector_count, data_ptr, dxfer_len,
1862 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1863 cam_fill_ataio(&ccb->ataio,
1872 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1873 return ata_cam_send(device, ccb, quiet);
1877 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1878 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1879 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1880 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1881 u_int16_t dxfer_len, int timeout, int force48bit)
1885 retval = ata_try_pass_16(device);
1892 /* Try using SCSI Passthrough */
1893 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1894 ata_flags, tag_action, command, features,
1895 lba, sector_count, data_ptr, dxfer_len,
1898 if (ata_flags & AP_FLAG_CHK_COND) {
1899 /* Decode ata_res from sense data */
1900 struct ata_res_pass16 *res_pass16;
1901 struct ata_res *res;
1905 /* sense_data is 4 byte aligned */
1906 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1907 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1908 ptr[i] = le16toh(ptr[i]);
1910 /* sense_data is 4 byte aligned */
1911 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1912 &ccb->csio.sense_data;
1913 res = &ccb->ataio.res;
1914 res->flags = res_pass16->flags;
1915 res->status = res_pass16->status;
1916 res->error = res_pass16->error;
1917 res->lba_low = res_pass16->lba_low;
1918 res->lba_mid = res_pass16->lba_mid;
1919 res->lba_high = res_pass16->lba_high;
1920 res->device = res_pass16->device;
1921 res->lba_low_exp = res_pass16->lba_low_exp;
1922 res->lba_mid_exp = res_pass16->lba_mid_exp;
1923 res->lba_high_exp = res_pass16->lba_high_exp;
1924 res->sector_count = res_pass16->sector_count;
1925 res->sector_count_exp = res_pass16->sector_count_exp;
1931 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1932 cam_fill_ataio(&ccb->ataio,
1941 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1942 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1944 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1946 if (ata_flags & AP_FLAG_CHK_COND)
1947 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1949 return ata_cam_send(device, ccb, 0);
1953 dump_data(uint16_t *ptr, uint32_t len)
1957 for (i = 0; i < len / 2; i++) {
1959 printf(" %3d: ", i);
1960 printf("%04hx ", ptr[i]);
1969 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1970 int is48bit, u_int64_t *hpasize)
1972 struct ata_res *res;
1974 res = &ccb->ataio.res;
1975 if (res->status & ATA_STATUS_ERROR) {
1976 if (arglist & CAM_ARG_VERBOSE) {
1977 cam_error_print(device, ccb, CAM_ESF_ALL,
1978 CAM_EPF_ALL, stderr);
1979 printf("error = 0x%02x, sector_count = 0x%04x, "
1980 "device = 0x%02x, status = 0x%02x\n",
1981 res->error, res->sector_count,
1982 res->device, res->status);
1985 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1986 warnx("Max address has already been set since "
1987 "last power-on or hardware reset");
1993 if (arglist & CAM_ARG_VERBOSE) {
1994 fprintf(stdout, "%s%d: Raw native max data:\n",
1995 device->device_name, device->dev_unit_num);
1996 /* res is 4 byte aligned */
1997 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1999 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
2000 "status = 0x%02x\n", res->error, res->sector_count,
2001 res->device, res->status);
2004 if (hpasize != NULL) {
2006 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
2007 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
2008 ((res->lba_high << 16) | (res->lba_mid << 8) |
2011 *hpasize = (((res->device & 0x0f) << 24) |
2012 (res->lba_high << 16) | (res->lba_mid << 8) |
2021 ata_read_native_max(struct cam_device *device, int retry_count,
2022 u_int32_t timeout, union ccb *ccb,
2023 struct ata_params *parm, u_int64_t *hpasize)
2029 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
2030 protocol = AP_PROTO_NON_DATA;
2033 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
2034 protocol |= AP_EXTEND;
2036 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
2039 error = ata_do_cmd(device,
2042 /*flags*/CAM_DIR_NONE,
2043 /*protocol*/protocol,
2044 /*ata_flags*/AP_FLAG_CHK_COND,
2045 /*tag_action*/MSG_SIMPLE_Q_TAG,
2052 timeout ? timeout : 1000,
2058 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
2062 atahpa_set_max(struct cam_device *device, int retry_count,
2063 u_int32_t timeout, union ccb *ccb,
2064 int is48bit, u_int64_t maxsize, int persist)
2070 protocol = AP_PROTO_NON_DATA;
2073 cmd = ATA_SET_MAX_ADDRESS48;
2074 protocol |= AP_EXTEND;
2076 cmd = ATA_SET_MAX_ADDRESS;
2079 /* lba's are zero indexed so the max lba is requested max - 1 */
2083 error = ata_do_cmd(device,
2086 /*flags*/CAM_DIR_NONE,
2087 /*protocol*/protocol,
2088 /*ata_flags*/AP_FLAG_CHK_COND,
2089 /*tag_action*/MSG_SIMPLE_Q_TAG,
2091 /*features*/ATA_HPA_FEAT_MAX_ADDR,
2093 /*sector_count*/persist,
2096 timeout ? timeout : 1000,
2102 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2106 atahpa_password(struct cam_device *device, int retry_count,
2107 u_int32_t timeout, union ccb *ccb,
2108 int is48bit, struct ata_set_max_pwd *pwd)
2114 protocol = AP_PROTO_PIO_OUT;
2115 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2117 error = ata_do_cmd(device,
2120 /*flags*/CAM_DIR_OUT,
2121 /*protocol*/protocol,
2122 /*ata_flags*/AP_FLAG_CHK_COND,
2123 /*tag_action*/MSG_SIMPLE_Q_TAG,
2125 /*features*/ATA_HPA_FEAT_SET_PWD,
2128 /*data_ptr*/(u_int8_t*)pwd,
2129 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2130 timeout ? timeout : 1000,
2136 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2140 atahpa_lock(struct cam_device *device, int retry_count,
2141 u_int32_t timeout, union ccb *ccb, int is48bit)
2147 protocol = AP_PROTO_NON_DATA;
2148 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2150 error = ata_do_cmd(device,
2153 /*flags*/CAM_DIR_NONE,
2154 /*protocol*/protocol,
2155 /*ata_flags*/AP_FLAG_CHK_COND,
2156 /*tag_action*/MSG_SIMPLE_Q_TAG,
2158 /*features*/ATA_HPA_FEAT_LOCK,
2163 timeout ? timeout : 1000,
2169 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2173 atahpa_unlock(struct cam_device *device, int retry_count,
2174 u_int32_t timeout, union ccb *ccb,
2175 int is48bit, struct ata_set_max_pwd *pwd)
2181 protocol = AP_PROTO_PIO_OUT;
2182 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2184 error = ata_do_cmd(device,
2187 /*flags*/CAM_DIR_OUT,
2188 /*protocol*/protocol,
2189 /*ata_flags*/AP_FLAG_CHK_COND,
2190 /*tag_action*/MSG_SIMPLE_Q_TAG,
2192 /*features*/ATA_HPA_FEAT_UNLOCK,
2195 /*data_ptr*/(u_int8_t*)pwd,
2196 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2197 timeout ? timeout : 1000,
2203 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2207 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2208 u_int32_t timeout, union ccb *ccb, int is48bit)
2214 protocol = AP_PROTO_NON_DATA;
2215 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2217 error = ata_do_cmd(device,
2220 /*flags*/CAM_DIR_NONE,
2221 /*protocol*/protocol,
2222 /*ata_flags*/AP_FLAG_CHK_COND,
2223 /*tag_action*/MSG_SIMPLE_Q_TAG,
2225 /*features*/ATA_HPA_FEAT_FREEZE,
2230 timeout ? timeout : 1000,
2236 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2241 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2242 union ccb *ccb, struct ata_params** ident_bufp)
2244 struct ata_params *ident_buf;
2245 struct ccb_pathinq cpi;
2246 struct ccb_getdev cgd;
2249 u_int8_t command, retry_command;
2251 if (get_cpi(device, &cpi) != 0) {
2252 warnx("couldn't get CPI");
2256 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2257 if (cpi.protocol == PROTO_ATA) {
2258 if (get_cgd(device, &cgd) != 0) {
2259 warnx("couldn't get CGD");
2263 command = (cgd.protocol == PROTO_ATA) ?
2264 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2267 /* We don't know which for sure so try both */
2268 command = ATA_ATA_IDENTIFY;
2269 retry_command = ATA_ATAPI_IDENTIFY;
2272 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2274 warnx("can't calloc memory for identify\n");
2278 error = ata_do_28bit_cmd(device,
2280 /*retries*/retry_count,
2281 /*flags*/CAM_DIR_IN,
2282 /*protocol*/AP_PROTO_PIO_IN,
2283 /*tag_action*/MSG_SIMPLE_Q_TAG,
2287 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2288 /*data_ptr*/(u_int8_t *)ptr,
2289 /*dxfer_len*/sizeof(struct ata_params),
2290 /*timeout*/timeout ? timeout : 30 * 1000,
2294 if (retry_command == 0) {
2298 error = ata_do_28bit_cmd(device,
2300 /*retries*/retry_count,
2301 /*flags*/CAM_DIR_IN,
2302 /*protocol*/AP_PROTO_PIO_IN,
2303 /*tag_action*/MSG_SIMPLE_Q_TAG,
2304 /*command*/retry_command,
2307 /*sector_count*/(u_int8_t)
2308 sizeof(struct ata_params),
2309 /*data_ptr*/(u_int8_t *)ptr,
2310 /*dxfer_len*/sizeof(struct ata_params),
2311 /*timeout*/timeout ? timeout : 30 * 1000,
2321 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2322 ptr[i] = le16toh(ptr[i]);
2327 if (arglist & CAM_ARG_VERBOSE) {
2328 fprintf(stdout, "%s%d: Raw identify data:\n",
2329 device->device_name, device->dev_unit_num);
2330 dump_data(ptr, sizeof(struct ata_params));
2333 /* check for invalid (all zero) response */
2335 warnx("Invalid identify response detected");
2340 ident_buf = (struct ata_params *)ptr;
2341 if (strncmp(ident_buf->model, "FX", 2) &&
2342 strncmp(ident_buf->model, "NEC", 3) &&
2343 strncmp(ident_buf->model, "Pioneer", 7) &&
2344 strncmp(ident_buf->model, "SHARP", 5)) {
2345 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2346 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2347 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2348 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2350 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2351 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2352 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2353 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2354 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2355 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2356 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2357 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2358 sizeof(ident_buf->media_serial));
2360 *ident_bufp = ident_buf;
2367 ataidentify(struct cam_device *device, int retry_count, int timeout)
2370 struct ata_params *ident_buf;
2373 if ((ccb = cam_getccb(device)) == NULL) {
2374 warnx("couldn't allocate CCB");
2378 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2383 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2384 if (ata_read_native_max(device, retry_count, timeout, ccb,
2385 ident_buf, &hpasize) != 0) {
2393 printf("%s%d: ", device->device_name, device->dev_unit_num);
2394 ata_print_ident(ident_buf);
2395 camxferrate(device);
2396 atacapprint(ident_buf);
2397 atahpa_print(ident_buf, hpasize, 0);
2406 nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused)
2408 struct nvme_controller_data cdata;
2410 if (nvme_get_cdata(device, &cdata))
2412 nvme_print_controller(&cdata);
2418 identify(struct cam_device *device, int retry_count, int timeout)
2420 struct ccb_pathinq cpi;
2422 if (get_cpi(device, &cpi) != 0) {
2423 warnx("couldn't get CPI");
2427 if (cpi.protocol == PROTO_NVME) {
2428 return (nvmeidentify(device, retry_count, timeout));
2430 return (ataidentify(device, retry_count, timeout));
2432 #endif /* MINIMALISTIC */
2435 #ifndef MINIMALISTIC
2437 ATA_SECURITY_ACTION_PRINT,
2438 ATA_SECURITY_ACTION_FREEZE,
2439 ATA_SECURITY_ACTION_UNLOCK,
2440 ATA_SECURITY_ACTION_DISABLE,
2441 ATA_SECURITY_ACTION_ERASE,
2442 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2443 ATA_SECURITY_ACTION_SET_PASSWORD
2447 atasecurity_print_time(u_int16_t tw)
2451 printf("unspecified");
2453 printf("> 508 min");
2455 printf("%i min", 2 * tw);
2459 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2463 return 2 * 3600 * 1000; /* default: two hours */
2464 else if (timeout > 255)
2465 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2467 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2472 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2476 bzero(&cmd, sizeof(cmd));
2477 cmd.command = command;
2478 printf("Issuing %s", ata_op_string(&cmd));
2481 char pass[sizeof(pwd->password)+1];
2483 /* pwd->password may not be null terminated */
2484 pass[sizeof(pwd->password)] = '\0';
2485 strncpy(pass, pwd->password, sizeof(pwd->password));
2486 printf(" password='%s', user='%s'",
2488 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2491 if (command == ATA_SECURITY_SET_PASSWORD) {
2492 printf(", mode='%s'",
2493 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2494 "maximum" : "high");
2502 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2503 int retry_count, u_int32_t timeout, int quiet)
2507 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2509 return ata_do_28bit_cmd(device,
2512 /*flags*/CAM_DIR_NONE,
2513 /*protocol*/AP_PROTO_NON_DATA,
2514 /*tag_action*/MSG_SIMPLE_Q_TAG,
2515 /*command*/ATA_SECURITY_FREEZE_LOCK,
2526 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2527 int retry_count, u_int32_t timeout,
2528 struct ata_security_password *pwd, int quiet)
2532 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2534 return ata_do_28bit_cmd(device,
2537 /*flags*/CAM_DIR_OUT,
2538 /*protocol*/AP_PROTO_PIO_OUT,
2539 /*tag_action*/MSG_SIMPLE_Q_TAG,
2540 /*command*/ATA_SECURITY_UNLOCK,
2544 /*data_ptr*/(u_int8_t *)pwd,
2545 /*dxfer_len*/sizeof(*pwd),
2551 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2552 int retry_count, u_int32_t timeout,
2553 struct ata_security_password *pwd, int quiet)
2557 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2558 return ata_do_28bit_cmd(device,
2561 /*flags*/CAM_DIR_OUT,
2562 /*protocol*/AP_PROTO_PIO_OUT,
2563 /*tag_action*/MSG_SIMPLE_Q_TAG,
2564 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2568 /*data_ptr*/(u_int8_t *)pwd,
2569 /*dxfer_len*/sizeof(*pwd),
2576 atasecurity_erase_confirm(struct cam_device *device,
2577 struct ata_params* ident_buf)
2580 printf("\nYou are about to ERASE ALL DATA from the following"
2581 " device:\n%s%d,%s%d: ", device->device_name,
2582 device->dev_unit_num, device->given_dev_name,
2583 device->given_unit_number);
2584 ata_print_ident(ident_buf);
2588 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2590 if (fgets(str, sizeof(str), stdin) != NULL) {
2591 if (strncasecmp(str, "yes", 3) == 0) {
2593 } else if (strncasecmp(str, "no", 2) == 0) {
2596 printf("Please answer \"yes\" or "
2607 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2608 int retry_count, u_int32_t timeout,
2609 u_int32_t erase_timeout,
2610 struct ata_security_password *pwd, int quiet)
2615 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2617 error = ata_do_28bit_cmd(device,
2620 /*flags*/CAM_DIR_NONE,
2621 /*protocol*/AP_PROTO_NON_DATA,
2622 /*tag_action*/MSG_SIMPLE_Q_TAG,
2623 /*command*/ATA_SECURITY_ERASE_PREPARE,
2636 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2638 error = ata_do_28bit_cmd(device,
2641 /*flags*/CAM_DIR_OUT,
2642 /*protocol*/AP_PROTO_PIO_OUT,
2643 /*tag_action*/MSG_SIMPLE_Q_TAG,
2644 /*command*/ATA_SECURITY_ERASE_UNIT,
2648 /*data_ptr*/(u_int8_t *)pwd,
2649 /*dxfer_len*/sizeof(*pwd),
2650 /*timeout*/erase_timeout,
2653 if (error == 0 && quiet == 0)
2654 printf("\nErase Complete\n");
2660 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2661 int retry_count, u_int32_t timeout,
2662 struct ata_security_password *pwd, int quiet)
2666 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2668 return ata_do_28bit_cmd(device,
2671 /*flags*/CAM_DIR_OUT,
2672 /*protocol*/AP_PROTO_PIO_OUT,
2673 /*tag_action*/MSG_SIMPLE_Q_TAG,
2674 /*command*/ATA_SECURITY_SET_PASSWORD,
2678 /*data_ptr*/(u_int8_t *)pwd,
2679 /*dxfer_len*/sizeof(*pwd),
2685 atasecurity_print(struct ata_params *parm)
2688 printf("\nSecurity Option Value\n");
2689 if (arglist & CAM_ARG_VERBOSE) {
2690 printf("status %04x\n",
2691 parm->security_status);
2693 printf("supported %s\n",
2694 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2695 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2697 printf("enabled %s\n",
2698 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2699 printf("drive locked %s\n",
2700 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2701 printf("security config frozen %s\n",
2702 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2703 printf("count expired %s\n",
2704 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2705 printf("security level %s\n",
2706 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2707 printf("enhanced erase supported %s\n",
2708 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2709 printf("erase time ");
2710 atasecurity_print_time(parm->erase_time);
2712 printf("enhanced erase time ");
2713 atasecurity_print_time(parm->enhanced_erase_time);
2715 printf("master password rev %04x%s\n",
2716 parm->master_passwd_revision,
2717 parm->master_passwd_revision == 0x0000 ||
2718 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2722 * Validates and copies the password in optarg to the passed buffer.
2723 * If the password in optarg is the same length as the buffer then
2724 * the data will still be copied but no null termination will occur.
2727 ata_getpwd(u_int8_t *passwd, int max, char opt)
2731 len = strlen(optarg);
2733 warnx("-%c password is too long", opt);
2735 } else if (len == 0) {
2736 warnx("-%c password is missing", opt);
2738 } else if (optarg[0] == '-'){
2739 warnx("-%c password starts with '-' (generic arg?)", opt);
2741 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2742 warnx("-%c password conflicts with existing password from -%c",
2747 /* Callers pass in a buffer which does NOT need to be terminated */
2748 strncpy(passwd, optarg, max);
2755 ATA_HPA_ACTION_PRINT,
2756 ATA_HPA_ACTION_SET_MAX,
2757 ATA_HPA_ACTION_SET_PWD,
2758 ATA_HPA_ACTION_LOCK,
2759 ATA_HPA_ACTION_UNLOCK,
2760 ATA_HPA_ACTION_FREEZE_LOCK
2764 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2765 u_int64_t maxsize, int persist)
2767 printf("\nYou are about to configure HPA to limit the user accessible\n"
2768 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2769 persist ? "persistently" : "temporarily",
2770 device->device_name, device->dev_unit_num,
2771 device->given_dev_name, device->given_unit_number);
2772 ata_print_ident(ident_buf);
2776 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2778 if (NULL != fgets(str, sizeof(str), stdin)) {
2779 if (0 == strncasecmp(str, "yes", 3)) {
2781 } else if (0 == strncasecmp(str, "no", 2)) {
2784 printf("Please answer \"yes\" or "
2795 atahpa(struct cam_device *device, int retry_count, int timeout,
2796 int argc, char **argv, char *combinedopt)
2799 struct ata_params *ident_buf;
2800 struct ccb_getdev cgd;
2801 struct ata_set_max_pwd pwd;
2802 int error, confirm, quiet, c, action, actions, persist;
2803 int security, is48bit, pwdsize;
2804 u_int64_t hpasize, maxsize;
2813 memset(&pwd, 0, sizeof(pwd));
2815 /* default action is to print hpa information */
2816 action = ATA_HPA_ACTION_PRINT;
2817 pwdsize = sizeof(pwd.password);
2819 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2822 action = ATA_HPA_ACTION_SET_MAX;
2823 maxsize = strtoumax(optarg, NULL, 0);
2828 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2830 action = ATA_HPA_ACTION_SET_PWD;
2836 action = ATA_HPA_ACTION_LOCK;
2842 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2844 action = ATA_HPA_ACTION_UNLOCK;
2850 action = ATA_HPA_ACTION_FREEZE_LOCK;
2870 warnx("too many hpa actions specified");
2874 if (get_cgd(device, &cgd) != 0) {
2875 warnx("couldn't get CGD");
2879 ccb = cam_getccb(device);
2881 warnx("couldn't allocate CCB");
2885 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2892 printf("%s%d: ", device->device_name, device->dev_unit_num);
2893 ata_print_ident(ident_buf);
2894 camxferrate(device);
2897 if (action == ATA_HPA_ACTION_PRINT) {
2898 error = ata_read_native_max(device, retry_count, timeout, ccb,
2899 ident_buf, &hpasize);
2901 atahpa_print(ident_buf, hpasize, 1);
2908 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2909 warnx("HPA is not supported by this device");
2915 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2916 warnx("HPA Security is not supported by this device");
2922 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2925 * The ATA spec requires:
2926 * 1. Read native max addr is called directly before set max addr
2927 * 2. Read native max addr is NOT called before any other set max call
2930 case ATA_HPA_ACTION_SET_MAX:
2932 atahpa_set_confirm(device, ident_buf, maxsize,
2939 error = ata_read_native_max(device, retry_count, timeout,
2940 ccb, ident_buf, &hpasize);
2942 error = atahpa_set_max(device, retry_count, timeout,
2943 ccb, is48bit, maxsize, persist);
2945 /* redo identify to get new lba values */
2946 error = ata_do_identify(device, retry_count,
2949 atahpa_print(ident_buf, hpasize, 1);
2954 case ATA_HPA_ACTION_SET_PWD:
2955 error = atahpa_password(device, retry_count, timeout,
2956 ccb, is48bit, &pwd);
2958 printf("HPA password has been set\n");
2961 case ATA_HPA_ACTION_LOCK:
2962 error = atahpa_lock(device, retry_count, timeout,
2965 printf("HPA has been locked\n");
2968 case ATA_HPA_ACTION_UNLOCK:
2969 error = atahpa_unlock(device, retry_count, timeout,
2970 ccb, is48bit, &pwd);
2972 printf("HPA has been unlocked\n");
2975 case ATA_HPA_ACTION_FREEZE_LOCK:
2976 error = atahpa_freeze_lock(device, retry_count, timeout,
2979 printf("HPA has been frozen\n");
2983 errx(1, "Option currently not supported");
2993 atasecurity(struct cam_device *device, int retry_count, int timeout,
2994 int argc, char **argv, char *combinedopt)
2997 struct ata_params *ident_buf;
2998 int error, confirm, quiet, c, action, actions, setpwd;
2999 int security_enabled, erase_timeout, pwdsize;
3000 struct ata_security_password pwd;
3008 memset(&pwd, 0, sizeof(pwd));
3010 /* default action is to print security information */
3011 action = ATA_SECURITY_ACTION_PRINT;
3013 /* user is master by default as its safer that way */
3014 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3015 pwdsize = sizeof(pwd.password);
3017 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3020 action = ATA_SECURITY_ACTION_FREEZE;
3025 if (strcasecmp(optarg, "user") == 0) {
3026 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
3027 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
3028 } else if (strcasecmp(optarg, "master") == 0) {
3029 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3030 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
3032 warnx("-U argument '%s' is invalid (must be "
3033 "'user' or 'master')", optarg);
3039 if (strcasecmp(optarg, "high") == 0) {
3040 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3041 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3042 } else if (strcasecmp(optarg, "maximum") == 0) {
3043 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3044 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3046 warnx("-l argument '%s' is unknown (must be "
3047 "'high' or 'maximum')", optarg);
3053 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3055 action = ATA_SECURITY_ACTION_UNLOCK;
3060 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3062 action = ATA_SECURITY_ACTION_DISABLE;
3067 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3069 action = ATA_SECURITY_ACTION_ERASE;
3074 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3076 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3077 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3082 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3085 if (action == ATA_SECURITY_ACTION_PRINT)
3086 action = ATA_SECURITY_ACTION_SET_PASSWORD;
3088 * Don't increment action as this can be combined
3089 * with other actions.
3102 erase_timeout = atoi(optarg) * 1000;
3108 warnx("too many security actions specified");
3112 if ((ccb = cam_getccb(device)) == NULL) {
3113 warnx("couldn't allocate CCB");
3117 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3124 printf("%s%d: ", device->device_name, device->dev_unit_num);
3125 ata_print_ident(ident_buf);
3126 camxferrate(device);
3129 if (action == ATA_SECURITY_ACTION_PRINT) {
3130 atasecurity_print(ident_buf);
3136 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3137 warnx("Security not supported");
3143 /* default timeout 15 seconds the same as linux hdparm */
3144 timeout = timeout ? timeout : 15 * 1000;
3146 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3148 /* first set the password if requested */
3150 /* confirm we can erase before setting the password if erasing */
3152 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3153 action == ATA_SECURITY_ACTION_ERASE) &&
3154 atasecurity_erase_confirm(device, ident_buf) == 0) {
3160 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3161 pwd.revision = ident_buf->master_passwd_revision;
3162 if (pwd.revision != 0 && pwd.revision != 0xfff &&
3163 --pwd.revision == 0) {
3164 pwd.revision = 0xfffe;
3167 error = atasecurity_set_password(device, ccb, retry_count,
3168 timeout, &pwd, quiet);
3174 security_enabled = 1;
3178 case ATA_SECURITY_ACTION_FREEZE:
3179 error = atasecurity_freeze(device, ccb, retry_count,
3183 case ATA_SECURITY_ACTION_UNLOCK:
3184 if (security_enabled) {
3185 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3186 error = atasecurity_unlock(device, ccb,
3187 retry_count, timeout, &pwd, quiet);
3189 warnx("Can't unlock, drive is not locked");
3193 warnx("Can't unlock, security is disabled");
3198 case ATA_SECURITY_ACTION_DISABLE:
3199 if (security_enabled) {
3200 /* First unlock the drive if its locked */
3201 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3202 error = atasecurity_unlock(device, ccb,
3210 error = atasecurity_disable(device,
3218 warnx("Can't disable security (already disabled)");
3223 case ATA_SECURITY_ACTION_ERASE:
3224 if (security_enabled) {
3225 if (erase_timeout == 0) {
3226 erase_timeout = atasecurity_erase_timeout_msecs(
3227 ident_buf->erase_time);
3230 error = atasecurity_erase(device, ccb, retry_count,
3231 timeout, erase_timeout, &pwd, quiet);
3233 warnx("Can't secure erase (security is disabled)");
3238 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3239 if (security_enabled) {
3240 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3241 if (erase_timeout == 0) {
3243 atasecurity_erase_timeout_msecs(
3244 ident_buf->enhanced_erase_time);
3247 error = atasecurity_erase(device, ccb,
3248 retry_count, timeout,
3249 erase_timeout, &pwd,
3252 warnx("Enhanced erase is not supported");
3256 warnx("Can't secure erase (enhanced), "
3257 "(security is disabled)");
3268 #endif /* MINIMALISTIC */
3271 * Parse out a bus, or a bus, target and lun in the following
3277 * Returns the number of parsed components, or 0.
3280 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3281 cam_argmask *arglst)
3286 while (isspace(*tstr) && (*tstr != '\0'))
3289 tmpstr = (char *)strtok(tstr, ":");
3290 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3291 *bus = strtol(tmpstr, NULL, 0);
3292 *arglst |= CAM_ARG_BUS;
3294 tmpstr = (char *)strtok(NULL, ":");
3295 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3296 *target = strtol(tmpstr, NULL, 0);
3297 *arglst |= CAM_ARG_TARGET;
3299 tmpstr = (char *)strtok(NULL, ":");
3300 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3301 *lun = strtol(tmpstr, NULL, 0);
3302 *arglst |= CAM_ARG_LUN;
3312 dorescan_or_reset(int argc, char **argv, int rescan)
3314 static const char must[] =
3315 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3317 path_id_t bus = CAM_BUS_WILDCARD;
3318 target_id_t target = CAM_TARGET_WILDCARD;
3319 lun_id_t lun = CAM_LUN_WILDCARD;
3323 warnx(must, rescan? "rescan" : "reset");
3327 tstr = argv[optind];
3328 while (isspace(*tstr) && (*tstr != '\0'))
3330 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3331 arglist |= CAM_ARG_BUS;
3332 else if (isdigit(*tstr)) {
3333 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3334 if (rv != 1 && rv != 3) {
3335 warnx(must, rescan? "rescan" : "reset");
3345 * Note that resetting or rescanning a device used to
3346 * require a bus or bus:target:lun. This is because the
3347 * device in question may not exist and you're trying to
3348 * get the controller to rescan to find it. It may also be
3349 * because the device is hung / unresponsive, and opening
3350 * an unresponsive device is not desireable.
3352 * It can be more convenient to reference a device by
3353 * peripheral name and unit number, though, and it is
3354 * possible to get the bus:target:lun for devices that
3355 * currently exist in the EDT. So this can work for
3356 * devices that we want to reset, or devices that exist
3357 * that we want to rescan, but not devices that do not
3360 * So, we are careful here to look up the bus/target/lun
3361 * for the device the user wants to operate on, specified
3362 * by peripheral instance (e.g. da0, pass32) without
3363 * actually opening that device. The process is similar to
3364 * what cam_lookup_pass() does, except that we don't
3365 * actually open the passthrough driver instance in the end.
3368 if (cam_get_device(tstr, name, sizeof(name), &unit) == -1) {
3369 warnx("%s", cam_errbuf);
3374 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3375 warn("Unable to open %s", XPT_DEVICE);
3380 bzero(&ccb, sizeof(ccb));
3383 * The function code isn't strictly necessary for the
3384 * GETPASSTHRU ioctl.
3386 ccb.ccb_h.func_code = XPT_GDEVLIST;
3389 * These two are necessary for the GETPASSTHRU ioctl to
3392 strlcpy(ccb.cgdl.periph_name, name,
3393 sizeof(ccb.cgdl.periph_name));
3394 ccb.cgdl.unit_number = unit;
3397 * Attempt to get the passthrough device. This ioctl will
3398 * fail if the device name is null, if the device doesn't
3399 * exist, or if the passthrough driver isn't in the kernel.
3401 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3402 warn("Unable to find bus:target:lun for device %s%d",
3408 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3409 const struct cam_status_entry *entry;
3411 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3412 warnx("Unable to find bus:target_lun for device %s%d, "
3413 "CAM status: %s (%#x)", name, unit,
3414 entry ? entry->status_text : "Unknown",
3422 * The kernel fills in the bus/target/lun. We don't
3423 * need the passthrough device name and unit number since
3424 * we aren't going to open it.
3426 bus = ccb.ccb_h.path_id;
3427 target = ccb.ccb_h.target_id;
3428 lun = ccb.ccb_h.target_lun;
3430 arglist |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3435 if ((arglist & CAM_ARG_BUS)
3436 && (arglist & CAM_ARG_TARGET)
3437 && (arglist & CAM_ARG_LUN))
3438 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3440 error = rescan_or_reset_bus(bus, rescan);
3448 rescan_or_reset_bus(path_id_t bus, int rescan)
3450 union ccb *ccb = NULL, *matchccb = NULL;
3451 int fd = -1, retval;
3456 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3457 warnx("error opening transport layer device %s", XPT_DEVICE);
3458 warn("%s", XPT_DEVICE);
3462 ccb = malloc(sizeof(*ccb));
3464 warn("failed to allocate CCB");
3468 bzero(ccb, sizeof(*ccb));
3470 if (bus != CAM_BUS_WILDCARD) {
3471 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3472 ccb->ccb_h.path_id = bus;
3473 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3474 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3475 ccb->crcn.flags = CAM_FLAG_NONE;
3477 /* run this at a low priority */
3478 ccb->ccb_h.pinfo.priority = 5;
3480 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3481 warn("CAMIOCOMMAND ioctl failed");
3486 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3487 fprintf(stdout, "%s of bus %d was successful\n",
3488 rescan ? "Re-scan" : "Reset", bus);
3490 fprintf(stdout, "%s of bus %d returned error %#x\n",
3491 rescan ? "Re-scan" : "Reset", bus,
3492 ccb->ccb_h.status & CAM_STATUS_MASK);
3501 * The right way to handle this is to modify the xpt so that it can
3502 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3503 * that isn't implemented, so instead we enumerate the buses and
3504 * send the rescan or reset to those buses in the case where the
3505 * given bus is -1 (wildcard). We don't send a rescan or reset
3506 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3507 * no-op, sending a rescan to the xpt bus would result in a status of
3510 matchccb = malloc(sizeof(*matchccb));
3511 if (matchccb == NULL) {
3512 warn("failed to allocate CCB");
3516 bzero(matchccb, sizeof(*matchccb));
3517 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3518 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3519 bufsize = sizeof(struct dev_match_result) * 20;
3520 matchccb->cdm.match_buf_len = bufsize;
3521 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3522 if (matchccb->cdm.matches == NULL) {
3523 warnx("can't malloc memory for matches");
3527 matchccb->cdm.num_matches = 0;
3529 matchccb->cdm.num_patterns = 1;
3530 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3532 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3533 matchccb->cdm.pattern_buf_len);
3534 if (matchccb->cdm.patterns == NULL) {
3535 warnx("can't malloc memory for patterns");
3539 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3540 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3545 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3546 warn("CAMIOCOMMAND ioctl failed");
3551 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3552 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3553 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3554 warnx("got CAM error %#x, CDM error %d\n",
3555 matchccb->ccb_h.status, matchccb->cdm.status);
3560 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3561 struct bus_match_result *bus_result;
3563 /* This shouldn't happen. */
3564 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3567 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3570 * We don't want to rescan or reset the xpt bus.
3573 if (bus_result->path_id == CAM_XPT_PATH_ID)
3576 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3578 ccb->ccb_h.path_id = bus_result->path_id;
3579 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3580 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3581 ccb->crcn.flags = CAM_FLAG_NONE;
3583 /* run this at a low priority */
3584 ccb->ccb_h.pinfo.priority = 5;
3586 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3587 warn("CAMIOCOMMAND ioctl failed");
3592 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3593 fprintf(stdout, "%s of bus %d was successful\n",
3594 rescan? "Re-scan" : "Reset",
3595 bus_result->path_id);
3598 * Don't bail out just yet, maybe the other
3599 * rescan or reset commands will complete
3602 fprintf(stderr, "%s of bus %d returned error "
3603 "%#x\n", rescan? "Re-scan" : "Reset",
3604 bus_result->path_id,
3605 ccb->ccb_h.status & CAM_STATUS_MASK);
3609 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3610 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3617 if (matchccb != NULL) {
3618 free(matchccb->cdm.patterns);
3619 free(matchccb->cdm.matches);
3628 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3631 struct cam_device *device;
3636 if (bus == CAM_BUS_WILDCARD) {
3637 warnx("invalid bus number %d", bus);
3641 if (target == CAM_TARGET_WILDCARD) {
3642 warnx("invalid target number %d", target);
3646 if (lun == CAM_LUN_WILDCARD) {
3647 warnx("invalid lun number %jx", (uintmax_t)lun);
3653 bzero(&ccb, sizeof(union ccb));
3656 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3657 warnx("error opening transport layer device %s\n",
3659 warn("%s", XPT_DEVICE);
3663 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3664 if (device == NULL) {
3665 warnx("%s", cam_errbuf);
3670 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3671 ccb.ccb_h.path_id = bus;
3672 ccb.ccb_h.target_id = target;
3673 ccb.ccb_h.target_lun = lun;
3674 ccb.ccb_h.timeout = 5000;
3675 ccb.crcn.flags = CAM_FLAG_NONE;
3677 /* run this at a low priority */
3678 ccb.ccb_h.pinfo.priority = 5;
3681 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3682 warn("CAMIOCOMMAND ioctl failed");
3687 if (cam_send_ccb(device, &ccb) < 0) {
3688 warn("error sending XPT_RESET_DEV CCB");
3689 cam_close_device(device);
3697 cam_close_device(device);
3700 * An error code of CAM_BDR_SENT is normal for a BDR request.
3702 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3704 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3705 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3706 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3709 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3710 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3711 ccb.ccb_h.status & CAM_STATUS_MASK);
3716 #ifndef MINIMALISTIC
3718 static struct scsi_nv defect_list_type_map[] = {
3719 { "block", SRDD10_BLOCK_FORMAT },
3720 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3721 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3722 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3723 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3724 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3728 readdefects(struct cam_device *device, int argc, char **argv,
3729 char *combinedopt, int task_attr, int retry_count, int timeout)
3731 union ccb *ccb = NULL;
3732 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3733 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3734 size_t hdr_size = 0, entry_size = 0;
3737 u_int8_t *defect_list = NULL;
3738 u_int8_t list_format = 0;
3739 int list_type_set = 0;
3740 u_int32_t dlist_length = 0;
3741 u_int32_t returned_length = 0, valid_len = 0;
3742 u_int32_t num_returned = 0, num_valid = 0;
3743 u_int32_t max_possible_size = 0, hdr_max = 0;
3744 u_int32_t starting_offset = 0;
3745 u_int8_t returned_format, returned_type;
3747 int summary = 0, quiet = 0;
3749 int lists_specified = 0;
3750 int get_length = 1, first_pass = 1;
3753 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3757 scsi_nv_status status;
3760 status = scsi_get_nv(defect_list_type_map,
3761 sizeof(defect_list_type_map) /
3762 sizeof(defect_list_type_map[0]), optarg,
3763 &entry_num, SCSI_NV_FLAG_IG_CASE);
3765 if (status == SCSI_NV_FOUND) {
3766 list_format = defect_list_type_map[
3770 warnx("%s: %s %s option %s", __func__,
3771 (status == SCSI_NV_AMBIGUOUS) ?
3772 "ambiguous" : "invalid", "defect list type",
3775 goto defect_bailout;
3780 arglist |= CAM_ARG_GLIST;
3783 arglist |= CAM_ARG_PLIST;
3794 starting_offset = strtoul(optarg, &endptr, 0);
3795 if (*endptr != '\0') {
3797 warnx("invalid starting offset %s", optarg);
3798 goto defect_bailout;
3810 if (list_type_set == 0) {
3812 warnx("no defect list format specified");
3813 goto defect_bailout;
3816 if (arglist & CAM_ARG_PLIST) {
3817 list_format |= SRDD10_PLIST;
3821 if (arglist & CAM_ARG_GLIST) {
3822 list_format |= SRDD10_GLIST;
3827 * This implies a summary, and was the previous behavior.
3829 if (lists_specified == 0)
3832 ccb = cam_getccb(device);
3837 * We start off asking for just the header to determine how much
3838 * defect data is available. Some Hitachi drives return an error
3839 * if you ask for more data than the drive has. Once we know the
3840 * length, we retry the command with the returned length.
3842 if (use_12byte == 0)
3843 dlist_length = sizeof(*hdr10);
3845 dlist_length = sizeof(*hdr12);
3848 if (defect_list != NULL) {
3852 defect_list = malloc(dlist_length);
3853 if (defect_list == NULL) {
3854 warnx("can't malloc memory for defect list");
3856 goto defect_bailout;
3860 bzero(defect_list, dlist_length);
3863 * cam_getccb() zeros the CCB header only. So we need to zero the
3864 * payload portion of the ccb.
3866 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3868 scsi_read_defects(&ccb->csio,
3869 /*retries*/ retry_count,
3871 /*tag_action*/ task_attr,
3872 /*list_format*/ list_format,
3873 /*addr_desc_index*/ starting_offset,
3874 /*data_ptr*/ defect_list,
3875 /*dxfer_len*/ dlist_length,
3876 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3877 /*sense_len*/ SSD_FULL_SIZE,
3878 /*timeout*/ timeout ? timeout : 5000);
3880 /* Disable freezing the device queue */
3881 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3883 if (cam_send_ccb(device, ccb) < 0) {
3884 perror("error reading defect list");
3886 if (arglist & CAM_ARG_VERBOSE) {
3887 cam_error_print(device, ccb, CAM_ESF_ALL,
3888 CAM_EPF_ALL, stderr);
3892 goto defect_bailout;
3895 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3897 if (use_12byte == 0) {
3898 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3899 hdr_size = sizeof(*hdr10);
3900 hdr_max = SRDDH10_MAX_LENGTH;
3902 if (valid_len >= hdr_size) {
3903 returned_length = scsi_2btoul(hdr10->length);
3904 returned_format = hdr10->format;
3906 returned_length = 0;
3907 returned_format = 0;
3910 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3911 hdr_size = sizeof(*hdr12);
3912 hdr_max = SRDDH12_MAX_LENGTH;
3914 if (valid_len >= hdr_size) {
3915 returned_length = scsi_4btoul(hdr12->length);
3916 returned_format = hdr12->format;
3918 returned_length = 0;
3919 returned_format = 0;
3923 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3924 switch (returned_type) {
3925 case SRDD10_BLOCK_FORMAT:
3926 entry_size = sizeof(struct scsi_defect_desc_block);
3928 case SRDD10_LONG_BLOCK_FORMAT:
3929 entry_size = sizeof(struct scsi_defect_desc_long_block);
3931 case SRDD10_EXT_PHYS_FORMAT:
3932 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3933 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3935 case SRDD10_EXT_BFI_FORMAT:
3936 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3937 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3940 warnx("Unknown defect format 0x%x\n", returned_type);
3942 goto defect_bailout;
3946 max_possible_size = (hdr_max / entry_size) * entry_size;
3947 num_returned = returned_length / entry_size;
3948 num_valid = min(returned_length, valid_len - hdr_size);
3949 num_valid /= entry_size;
3951 if (get_length != 0) {
3954 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3955 CAM_SCSI_STATUS_ERROR) {
3956 struct scsi_sense_data *sense;
3957 int error_code, sense_key, asc, ascq;
3959 sense = &ccb->csio.sense_data;
3960 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3961 ccb->csio.sense_resid, &error_code, &sense_key,
3962 &asc, &ascq, /*show_errors*/ 1);
3965 * If the drive is reporting that it just doesn't
3966 * support the defect list format, go ahead and use
3967 * the length it reported. Otherwise, the length
3968 * may not be valid, so use the maximum.
3970 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3971 && (asc == 0x1c) && (ascq == 0x00)
3972 && (returned_length > 0)) {
3973 if ((use_12byte == 0)
3974 && (returned_length >= max_possible_size)) {
3979 dlist_length = returned_length + hdr_size;
3980 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3981 && (asc == 0x1f) && (ascq == 0x00)
3982 && (returned_length > 0)) {
3983 /* Partial defect list transfer */
3985 * Hitachi drives return this error
3986 * along with a partial defect list if they
3987 * have more defects than the 10 byte
3988 * command can support. Retry with the 12
3991 if (use_12byte == 0) {
3996 dlist_length = returned_length + hdr_size;
3997 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
3998 && (asc == 0x24) && (ascq == 0x00)) {
3999 /* Invalid field in CDB */
4001 * SBC-3 says that if the drive has more
4002 * defects than can be reported with the
4003 * 10 byte command, it should return this
4004 * error and no data. Retry with the 12
4007 if (use_12byte == 0) {
4012 dlist_length = returned_length + hdr_size;
4015 * If we got a SCSI error and no valid length,
4016 * just use the 10 byte maximum. The 12
4017 * byte maximum is too large.
4019 if (returned_length == 0)
4020 dlist_length = SRDD10_MAX_LENGTH;
4022 if ((use_12byte == 0)
4023 && (returned_length >=
4024 max_possible_size)) {
4029 dlist_length = returned_length +
4033 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4036 warnx("Error reading defect header");
4037 if (arglist & CAM_ARG_VERBOSE)
4038 cam_error_print(device, ccb, CAM_ESF_ALL,
4039 CAM_EPF_ALL, stderr);
4040 goto defect_bailout;
4042 if ((use_12byte == 0)
4043 && (returned_length >= max_possible_size)) {
4048 dlist_length = returned_length + hdr_size;
4051 fprintf(stdout, "%u", num_returned);
4053 fprintf(stdout, " defect%s",
4054 (num_returned != 1) ? "s" : "");
4056 fprintf(stdout, "\n");
4058 goto defect_bailout;
4062 * We always limit the list length to the 10-byte maximum
4063 * length (0xffff). The reason is that some controllers
4064 * can't handle larger I/Os, and we can transfer the entire
4065 * 10 byte list in one shot. For drives that support the 12
4066 * byte read defects command, we'll step through the list
4067 * by specifying a starting offset. For drives that don't
4068 * support the 12 byte command's starting offset, we'll
4069 * just display the first 64K.
4071 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4077 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4078 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4079 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4080 struct scsi_sense_data *sense;
4081 int error_code, sense_key, asc, ascq;
4083 sense = &ccb->csio.sense_data;
4084 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4085 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4086 &ascq, /*show_errors*/ 1);
4089 * According to the SCSI spec, if the disk doesn't support
4090 * the requested format, it will generally return a sense
4091 * key of RECOVERED ERROR, and an additional sense code
4092 * of "DEFECT LIST NOT FOUND". HGST drives also return
4093 * Primary/Grown defect list not found errors. So just
4094 * check for an ASC of 0x1c.
4096 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4098 const char *format_str;
4100 format_str = scsi_nv_to_str(defect_list_type_map,
4101 sizeof(defect_list_type_map) /
4102 sizeof(defect_list_type_map[0]),
4103 list_format & SRDD10_DLIST_FORMAT_MASK);
4104 warnx("requested defect format %s not available",
4105 format_str ? format_str : "unknown");
4107 format_str = scsi_nv_to_str(defect_list_type_map,
4108 sizeof(defect_list_type_map) /
4109 sizeof(defect_list_type_map[0]), returned_type);
4110 if (format_str != NULL) {
4111 warnx("Device returned %s format",
4115 warnx("Device returned unknown defect"
4116 " data format %#x", returned_type);
4117 goto defect_bailout;
4121 warnx("Error returned from read defect data command");
4122 if (arglist & CAM_ARG_VERBOSE)
4123 cam_error_print(device, ccb, CAM_ESF_ALL,
4124 CAM_EPF_ALL, stderr);
4125 goto defect_bailout;
4127 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4129 warnx("Error returned from read defect data command");
4130 if (arglist & CAM_ARG_VERBOSE)
4131 cam_error_print(device, ccb, CAM_ESF_ALL,
4132 CAM_EPF_ALL, stderr);
4133 goto defect_bailout;
4136 if (first_pass != 0) {
4137 fprintf(stderr, "Got %d defect", num_returned);
4139 if ((lists_specified == 0) || (num_returned == 0)) {
4140 fprintf(stderr, "s.\n");
4141 goto defect_bailout;
4142 } else if (num_returned == 1)
4143 fprintf(stderr, ":\n");
4145 fprintf(stderr, "s:\n");
4151 * XXX KDM I should probably clean up the printout format for the
4154 switch (returned_type) {
4155 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4156 case SRDD10_EXT_PHYS_FORMAT:
4158 struct scsi_defect_desc_phys_sector *dlist;
4160 dlist = (struct scsi_defect_desc_phys_sector *)
4161 (defect_list + hdr_size);
4163 for (i = 0; i < num_valid; i++) {
4166 sector = scsi_4btoul(dlist[i].sector);
4167 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4168 mads = (sector & SDD_EXT_PHYS_MADS) ?
4170 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4172 if (hex_format == 0)
4173 fprintf(stdout, "%d:%d:%d%s",
4174 scsi_3btoul(dlist[i].cylinder),
4176 scsi_4btoul(dlist[i].sector),
4177 mads ? " - " : "\n");
4179 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4180 scsi_3btoul(dlist[i].cylinder),
4182 scsi_4btoul(dlist[i].sector),
4183 mads ? " - " : "\n");
4186 if (num_valid < num_returned) {
4187 starting_offset += num_valid;
4192 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4193 case SRDD10_EXT_BFI_FORMAT:
4195 struct scsi_defect_desc_bytes_from_index *dlist;
4197 dlist = (struct scsi_defect_desc_bytes_from_index *)
4198 (defect_list + hdr_size);
4200 for (i = 0; i < num_valid; i++) {
4203 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4204 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4205 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4206 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4208 if (hex_format == 0)
4209 fprintf(stdout, "%d:%d:%d%s",
4210 scsi_3btoul(dlist[i].cylinder),
4212 scsi_4btoul(dlist[i].bytes_from_index),
4213 mads ? " - " : "\n");
4215 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4216 scsi_3btoul(dlist[i].cylinder),
4218 scsi_4btoul(dlist[i].bytes_from_index),
4219 mads ? " - " : "\n");
4223 if (num_valid < num_returned) {
4224 starting_offset += num_valid;
4229 case SRDDH10_BLOCK_FORMAT:
4231 struct scsi_defect_desc_block *dlist;
4233 dlist = (struct scsi_defect_desc_block *)
4234 (defect_list + hdr_size);
4236 for (i = 0; i < num_valid; i++) {
4237 if (hex_format == 0)
4238 fprintf(stdout, "%u\n",
4239 scsi_4btoul(dlist[i].address));
4241 fprintf(stdout, "0x%x\n",
4242 scsi_4btoul(dlist[i].address));
4245 if (num_valid < num_returned) {
4246 starting_offset += num_valid;
4252 case SRDD10_LONG_BLOCK_FORMAT:
4254 struct scsi_defect_desc_long_block *dlist;
4256 dlist = (struct scsi_defect_desc_long_block *)
4257 (defect_list + hdr_size);
4259 for (i = 0; i < num_valid; i++) {
4260 if (hex_format == 0)
4261 fprintf(stdout, "%ju\n",
4262 (uintmax_t)scsi_8btou64(
4265 fprintf(stdout, "0x%jx\n",
4266 (uintmax_t)scsi_8btou64(
4270 if (num_valid < num_returned) {
4271 starting_offset += num_valid;
4277 fprintf(stderr, "Unknown defect format 0x%x\n",
4284 if (defect_list != NULL)
4292 #endif /* MINIMALISTIC */
4296 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4300 ccb = cam_getccb(device);
4306 #ifndef MINIMALISTIC
4308 mode_sense(struct cam_device *device, int dbd, int pc, int page, int subpage,
4309 int task_attr, int retry_count, int timeout, u_int8_t *data,
4315 ccb = cam_getccb(device);
4318 errx(1, "mode_sense: couldn't allocate CCB");
4320 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4322 scsi_mode_sense_subpage(&ccb->csio,
4323 /* retries */ retry_count,
4325 /* tag_action */ task_attr,
4329 /* subpage */ subpage,
4330 /* param_buf */ data,
4331 /* param_len */ datalen,
4332 /* minimum_cmd_size */ 0,
4333 /* sense_len */ SSD_FULL_SIZE,
4334 /* timeout */ timeout ? timeout : 5000);
4336 if (arglist & CAM_ARG_ERR_RECOVER)
4337 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4339 /* Disable freezing the device queue */
4340 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4342 if (((retval = cam_send_ccb(device, ccb)) < 0)
4343 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4344 if (arglist & CAM_ARG_VERBOSE) {
4345 cam_error_print(device, ccb, CAM_ESF_ALL,
4346 CAM_EPF_ALL, stderr);
4349 cam_close_device(device);
4351 err(1, "error sending mode sense command");
4353 errx(1, "error sending mode sense command");
4360 mode_select(struct cam_device *device, int save_pages, int task_attr,
4361 int retry_count, int timeout, u_int8_t *data, int datalen)
4366 ccb = cam_getccb(device);
4369 errx(1, "mode_select: couldn't allocate CCB");
4371 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4373 scsi_mode_select(&ccb->csio,
4374 /* retries */ retry_count,
4376 /* tag_action */ task_attr,
4377 /* scsi_page_fmt */ 1,
4378 /* save_pages */ save_pages,
4379 /* param_buf */ data,
4380 /* param_len */ datalen,
4381 /* sense_len */ SSD_FULL_SIZE,
4382 /* timeout */ timeout ? timeout : 5000);
4384 if (arglist & CAM_ARG_ERR_RECOVER)
4385 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4387 /* Disable freezing the device queue */
4388 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4390 if (((retval = cam_send_ccb(device, ccb)) < 0)
4391 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4392 if (arglist & CAM_ARG_VERBOSE) {
4393 cam_error_print(device, ccb, CAM_ESF_ALL,
4394 CAM_EPF_ALL, stderr);
4397 cam_close_device(device);
4400 err(1, "error sending mode select command");
4402 errx(1, "error sending mode select command");
4410 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4411 int task_attr, int retry_count, int timeout)
4414 int c, page = -1, subpage = -1, pc = 0;
4415 int binary = 0, dbd = 0, edit = 0, list = 0;
4417 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4432 str_subpage = optarg;
4433 strsep(&str_subpage, ",");
4434 page = strtol(optarg, NULL, 0);
4436 subpage = strtol(str_subpage, NULL, 0);
4440 errx(1, "invalid mode page %d", page);
4442 errx(1, "invalid mode subpage %d", subpage);
4445 pc = strtol(optarg, NULL, 0);
4446 if ((pc < 0) || (pc > 3))
4447 errx(1, "invalid page control field %d", pc);
4454 if (page == -1 && list == 0)
4455 errx(1, "you must specify a mode page!");
4458 mode_list(device, dbd, pc, list > 1, task_attr, retry_count,
4461 mode_edit(device, dbd, pc, page, subpage, edit, binary,
4462 task_attr, retry_count, timeout);
4467 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4468 int task_attr, int retry_count, int timeout)
4471 u_int32_t flags = CAM_DIR_NONE;
4472 u_int8_t *data_ptr = NULL;
4474 u_int8_t atacmd[12];
4475 struct get_hook hook;
4476 int c, data_bytes = 0, valid_bytes;
4482 char *datastr = NULL, *tstr, *resstr = NULL;
4484 int fd_data = 0, fd_res = 0;
4487 ccb = cam_getccb(device);
4490 warnx("scsicmd: error allocating ccb");
4494 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4496 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4500 while (isspace(*tstr) && (*tstr != '\0'))
4502 hook.argc = argc - optind;
4503 hook.argv = argv + optind;
4505 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4508 * Increment optind by the number of arguments the
4509 * encoding routine processed. After each call to
4510 * getopt(3), optind points to the argument that
4511 * getopt should process _next_. In this case,
4512 * that means it points to the first command string
4513 * argument, if there is one. Once we increment
4514 * this, it should point to either the next command
4515 * line argument, or it should be past the end of
4522 while (isspace(*tstr) && (*tstr != '\0'))
4524 hook.argc = argc - optind;
4525 hook.argv = argv + optind;
4527 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4530 * Increment optind by the number of arguments the
4531 * encoding routine processed. After each call to
4532 * getopt(3), optind points to the argument that
4533 * getopt should process _next_. In this case,
4534 * that means it points to the first command string
4535 * argument, if there is one. Once we increment
4536 * this, it should point to either the next command
4537 * line argument, or it should be past the end of
4549 if (arglist & CAM_ARG_CMD_OUT) {
4550 warnx("command must either be "
4551 "read or write, not both");
4553 goto scsicmd_bailout;
4555 arglist |= CAM_ARG_CMD_IN;
4557 data_bytes = strtol(optarg, NULL, 0);
4558 if (data_bytes <= 0) {
4559 warnx("invalid number of input bytes %d",
4562 goto scsicmd_bailout;
4564 hook.argc = argc - optind;
4565 hook.argv = argv + optind;
4568 datastr = cget(&hook, NULL);
4570 * If the user supplied "-" instead of a format, he
4571 * wants the data to be written to stdout.
4573 if ((datastr != NULL)
4574 && (datastr[0] == '-'))
4577 data_ptr = (u_int8_t *)malloc(data_bytes);
4578 if (data_ptr == NULL) {
4579 warnx("can't malloc memory for data_ptr");
4581 goto scsicmd_bailout;
4585 if (arglist & CAM_ARG_CMD_IN) {
4586 warnx("command must either be "
4587 "read or write, not both");
4589 goto scsicmd_bailout;
4591 arglist |= CAM_ARG_CMD_OUT;
4592 flags = CAM_DIR_OUT;
4593 data_bytes = strtol(optarg, NULL, 0);
4594 if (data_bytes <= 0) {
4595 warnx("invalid number of output bytes %d",
4598 goto scsicmd_bailout;
4600 hook.argc = argc - optind;
4601 hook.argv = argv + optind;
4603 datastr = cget(&hook, NULL);
4604 data_ptr = (u_int8_t *)malloc(data_bytes);
4605 if (data_ptr == NULL) {
4606 warnx("can't malloc memory for data_ptr");
4608 goto scsicmd_bailout;
4610 bzero(data_ptr, data_bytes);
4612 * If the user supplied "-" instead of a format, he
4613 * wants the data to be read from stdin.
4615 if ((datastr != NULL)
4616 && (datastr[0] == '-'))
4619 buff_encode_visit(data_ptr, data_bytes, datastr,
4625 hook.argc = argc - optind;
4626 hook.argv = argv + optind;
4628 resstr = cget(&hook, NULL);
4629 if ((resstr != NULL) && (resstr[0] == '-'))
4639 * If fd_data is set, and we're writing to the device, we need to
4640 * read the data the user wants written from stdin.
4642 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4644 int amt_to_read = data_bytes;
4645 u_int8_t *buf_ptr = data_ptr;
4647 for (amt_read = 0; amt_to_read > 0;
4648 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4649 if (amt_read == -1) {
4650 warn("error reading data from stdin");
4652 goto scsicmd_bailout;
4654 amt_to_read -= amt_read;
4655 buf_ptr += amt_read;
4659 if (arglist & CAM_ARG_ERR_RECOVER)
4660 flags |= CAM_PASS_ERR_RECOVER;
4662 /* Disable freezing the device queue */
4663 flags |= CAM_DEV_QFRZDIS;
4667 * This is taken from the SCSI-3 draft spec.
4668 * (T10/1157D revision 0.3)
4669 * The top 3 bits of an opcode are the group code.
4670 * The next 5 bits are the command code.
4671 * Group 0: six byte commands
4672 * Group 1: ten byte commands
4673 * Group 2: ten byte commands
4675 * Group 4: sixteen byte commands
4676 * Group 5: twelve byte commands
4677 * Group 6: vendor specific
4678 * Group 7: vendor specific
4680 switch((cdb[0] >> 5) & 0x7) {
4691 /* computed by buff_encode_visit */
4702 * We should probably use csio_build_visit or something like that
4703 * here, but it's easier to encode arguments as you go. The
4704 * alternative would be skipping the CDB argument and then encoding
4705 * it here, since we've got the data buffer argument by now.
4707 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4709 cam_fill_csio(&ccb->csio,
4710 /*retries*/ retry_count,
4713 /*tag_action*/ task_attr,
4714 /*data_ptr*/ data_ptr,
4715 /*dxfer_len*/ data_bytes,
4716 /*sense_len*/ SSD_FULL_SIZE,
4717 /*cdb_len*/ cdb_len,
4718 /*timeout*/ timeout ? timeout : 5000);
4721 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4723 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4725 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4727 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4729 cam_fill_ataio(&ccb->ataio,
4730 /*retries*/ retry_count,
4734 /*data_ptr*/ data_ptr,
4735 /*dxfer_len*/ data_bytes,
4736 /*timeout*/ timeout ? timeout : 5000);
4739 if (((retval = cam_send_ccb(device, ccb)) < 0)
4740 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4741 const char warnstr[] = "error sending command";
4748 if (arglist & CAM_ARG_VERBOSE) {
4749 cam_error_print(device, ccb, CAM_ESF_ALL,
4750 CAM_EPF_ALL, stderr);
4754 goto scsicmd_bailout;
4757 if (atacmd_len && need_res) {
4759 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4761 fprintf(stdout, "\n");
4764 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4765 ccb->ataio.res.status,
4766 ccb->ataio.res.error,
4767 ccb->ataio.res.lba_low,
4768 ccb->ataio.res.lba_mid,
4769 ccb->ataio.res.lba_high,
4770 ccb->ataio.res.device,
4771 ccb->ataio.res.lba_low_exp,
4772 ccb->ataio.res.lba_mid_exp,
4773 ccb->ataio.res.lba_high_exp,
4774 ccb->ataio.res.sector_count,
4775 ccb->ataio.res.sector_count_exp);
4781 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4783 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4784 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4785 && (arglist & CAM_ARG_CMD_IN)
4786 && (valid_bytes > 0)) {
4788 buff_decode_visit(data_ptr, valid_bytes, datastr,
4790 fprintf(stdout, "\n");
4792 ssize_t amt_written;
4793 int amt_to_write = valid_bytes;
4794 u_int8_t *buf_ptr = data_ptr;
4796 for (amt_written = 0; (amt_to_write > 0) &&
4797 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4798 amt_to_write -= amt_written;
4799 buf_ptr += amt_written;
4801 if (amt_written == -1) {
4802 warn("error writing data to stdout");
4804 goto scsicmd_bailout;
4805 } else if ((amt_written == 0)
4806 && (amt_to_write > 0)) {
4807 warnx("only wrote %u bytes out of %u",
4808 valid_bytes - amt_to_write, valid_bytes);
4815 if ((data_bytes > 0) && (data_ptr != NULL))
4824 camdebug(int argc, char **argv, char *combinedopt)
4827 path_id_t bus = CAM_BUS_WILDCARD;
4828 target_id_t target = CAM_TARGET_WILDCARD;
4829 lun_id_t lun = CAM_LUN_WILDCARD;
4830 char *tstr, *tmpstr = NULL;
4834 bzero(&ccb, sizeof(union ccb));
4836 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4839 arglist |= CAM_ARG_DEBUG_INFO;
4840 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4843 arglist |= CAM_ARG_DEBUG_PERIPH;
4844 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4847 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4848 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4851 arglist |= CAM_ARG_DEBUG_TRACE;
4852 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4855 arglist |= CAM_ARG_DEBUG_XPT;
4856 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4859 arglist |= CAM_ARG_DEBUG_CDB;
4860 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4863 arglist |= CAM_ARG_DEBUG_PROBE;
4864 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4871 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4872 warnx("error opening transport layer device %s", XPT_DEVICE);
4873 warn("%s", XPT_DEVICE);
4880 warnx("you must specify \"off\", \"all\" or a bus,");
4881 warnx("bus:target, or bus:target:lun");
4888 while (isspace(*tstr) && (*tstr != '\0'))
4891 if (strncmp(tstr, "off", 3) == 0) {
4892 ccb.cdbg.flags = CAM_DEBUG_NONE;
4893 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4894 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4895 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4896 } else if (strncmp(tstr, "all", 3) != 0) {
4897 tmpstr = (char *)strtok(tstr, ":");
4898 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4899 bus = strtol(tmpstr, NULL, 0);
4900 arglist |= CAM_ARG_BUS;
4901 tmpstr = (char *)strtok(NULL, ":");
4902 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4903 target = strtol(tmpstr, NULL, 0);
4904 arglist |= CAM_ARG_TARGET;
4905 tmpstr = (char *)strtok(NULL, ":");
4906 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4907 lun = strtol(tmpstr, NULL, 0);
4908 arglist |= CAM_ARG_LUN;
4913 warnx("you must specify \"all\", \"off\", or a bus,");
4914 warnx("bus:target, or bus:target:lun to debug");
4920 ccb.ccb_h.func_code = XPT_DEBUG;
4921 ccb.ccb_h.path_id = bus;
4922 ccb.ccb_h.target_id = target;
4923 ccb.ccb_h.target_lun = lun;
4925 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4926 warn("CAMIOCOMMAND ioctl failed");
4931 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4932 CAM_FUNC_NOTAVAIL) {
4933 warnx("CAM debugging not available");
4934 warnx("you need to put options CAMDEBUG in"
4935 " your kernel config file!");
4937 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4939 warnx("XPT_DEBUG CCB failed with status %#x",
4943 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4945 "Debugging turned off\n");
4948 "Debugging enabled for "
4950 bus, target, (uintmax_t)lun);
4961 tagcontrol(struct cam_device *device, int argc, char **argv,
4971 ccb = cam_getccb(device);
4974 warnx("tagcontrol: error allocating ccb");
4978 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4981 numtags = strtol(optarg, NULL, 0);
4983 warnx("tag count %d is < 0", numtags);
4985 goto tagcontrol_bailout;
4996 cam_path_string(device, pathstr, sizeof(pathstr));
4999 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
5000 ccb->ccb_h.func_code = XPT_REL_SIMQ;
5001 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5002 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5003 ccb->crs.openings = numtags;
5006 if (cam_send_ccb(device, ccb) < 0) {
5007 perror("error sending XPT_REL_SIMQ CCB");
5009 goto tagcontrol_bailout;
5012 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5013 warnx("XPT_REL_SIMQ CCB failed");
5014 cam_error_print(device, ccb, CAM_ESF_ALL,
5015 CAM_EPF_ALL, stderr);
5017 goto tagcontrol_bailout;
5022 fprintf(stdout, "%stagged openings now %d\n",
5023 pathstr, ccb->crs.openings);
5026 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5028 ccb->ccb_h.func_code = XPT_GDEV_STATS;
5030 if (cam_send_ccb(device, ccb) < 0) {
5031 perror("error sending XPT_GDEV_STATS CCB");
5033 goto tagcontrol_bailout;
5036 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5037 warnx("XPT_GDEV_STATS CCB failed");
5038 cam_error_print(device, ccb, CAM_ESF_ALL,
5039 CAM_EPF_ALL, stderr);
5041 goto tagcontrol_bailout;
5044 if (arglist & CAM_ARG_VERBOSE) {
5045 fprintf(stdout, "%s", pathstr);
5046 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5047 fprintf(stdout, "%s", pathstr);
5048 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5049 fprintf(stdout, "%s", pathstr);
5050 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5051 fprintf(stdout, "%s", pathstr);
5052 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5053 fprintf(stdout, "%s", pathstr);
5054 fprintf(stdout, "held %d\n", ccb->cgds.held);
5055 fprintf(stdout, "%s", pathstr);
5056 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5057 fprintf(stdout, "%s", pathstr);
5058 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5061 fprintf(stdout, "%s", pathstr);
5062 fprintf(stdout, "device openings: ");
5064 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5065 ccb->cgds.dev_active);
5075 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5079 cam_path_string(device, pathstr, sizeof(pathstr));
5081 if (cts->transport == XPORT_SPI) {
5082 struct ccb_trans_settings_spi *spi =
5083 &cts->xport_specific.spi;
5085 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5087 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5090 if (spi->sync_offset != 0) {
5093 freq = scsi_calc_syncsrate(spi->sync_period);
5094 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5095 pathstr, freq / 1000, freq % 1000);
5099 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5100 fprintf(stdout, "%soffset: %d\n", pathstr,
5104 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5105 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5106 (0x01 << spi->bus_width) * 8);
5109 if (spi->valid & CTS_SPI_VALID_DISC) {
5110 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5111 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5112 "enabled" : "disabled");
5115 if (cts->transport == XPORT_FC) {
5116 struct ccb_trans_settings_fc *fc =
5117 &cts->xport_specific.fc;
5119 if (fc->valid & CTS_FC_VALID_WWNN)
5120 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5121 (long long) fc->wwnn);
5122 if (fc->valid & CTS_FC_VALID_WWPN)
5123 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5124 (long long) fc->wwpn);
5125 if (fc->valid & CTS_FC_VALID_PORT)
5126 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5127 if (fc->valid & CTS_FC_VALID_SPEED)
5128 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5129 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5131 if (cts->transport == XPORT_SAS) {
5132 struct ccb_trans_settings_sas *sas =
5133 &cts->xport_specific.sas;
5135 if (sas->valid & CTS_SAS_VALID_SPEED)
5136 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5137 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5139 if (cts->transport == XPORT_ATA) {
5140 struct ccb_trans_settings_pata *pata =
5141 &cts->xport_specific.ata;
5143 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5144 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5145 ata_mode2string(pata->mode));
5147 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5148 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5151 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5152 fprintf(stdout, "%sPIO transaction length: %d\n",
5153 pathstr, pata->bytecount);
5156 if (cts->transport == XPORT_SATA) {
5157 struct ccb_trans_settings_sata *sata =
5158 &cts->xport_specific.sata;
5160 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5161 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5164 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5165 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5166 ata_mode2string(sata->mode));
5168 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5169 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5172 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5173 fprintf(stdout, "%sPIO transaction length: %d\n",
5174 pathstr, sata->bytecount);
5176 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5177 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5180 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5181 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5184 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5185 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5189 if (cts->protocol == PROTO_ATA) {
5190 struct ccb_trans_settings_ata *ata=
5191 &cts->proto_specific.ata;
5193 if (ata->valid & CTS_ATA_VALID_TQ) {
5194 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5195 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5196 "enabled" : "disabled");
5199 if (cts->protocol == PROTO_SCSI) {
5200 struct ccb_trans_settings_scsi *scsi=
5201 &cts->proto_specific.scsi;
5203 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5204 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5205 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5206 "enabled" : "disabled");
5209 if (cts->protocol == PROTO_NVME) {
5210 struct ccb_trans_settings_nvme *nvmex =
5211 &cts->xport_specific.nvme;
5213 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5214 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5215 NVME_MAJOR(nvmex->spec),
5216 NVME_MINOR(nvmex->spec));
5218 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5219 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5220 nvmex->lanes, nvmex->max_lanes);
5221 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5222 nvmex->speed, nvmex->max_speed);
5228 * Get a path inquiry CCB for the specified device.
5231 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5236 ccb = cam_getccb(device);
5238 warnx("get_cpi: couldn't allocate CCB");
5241 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5242 ccb->ccb_h.func_code = XPT_PATH_INQ;
5243 if (cam_send_ccb(device, ccb) < 0) {
5244 warn("get_cpi: error sending Path Inquiry CCB");
5245 if (arglist & CAM_ARG_VERBOSE)
5246 cam_error_print(device, ccb, CAM_ESF_ALL,
5247 CAM_EPF_ALL, stderr);
5249 goto get_cpi_bailout;
5251 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5252 if (arglist & CAM_ARG_VERBOSE)
5253 cam_error_print(device, ccb, CAM_ESF_ALL,
5254 CAM_EPF_ALL, stderr);
5256 goto get_cpi_bailout;
5258 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5266 * Get a get device CCB for the specified device.
5269 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5274 ccb = cam_getccb(device);
5276 warnx("get_cgd: couldn't allocate CCB");
5279 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5280 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5281 if (cam_send_ccb(device, ccb) < 0) {
5282 warn("get_cgd: error sending Path Inquiry CCB");
5283 if (arglist & CAM_ARG_VERBOSE)
5284 cam_error_print(device, ccb, CAM_ESF_ALL,
5285 CAM_EPF_ALL, stderr);
5287 goto get_cgd_bailout;
5289 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5290 if (arglist & CAM_ARG_VERBOSE)
5291 cam_error_print(device, ccb, CAM_ESF_ALL,
5292 CAM_EPF_ALL, stderr);
5294 goto get_cgd_bailout;
5296 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5304 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5308 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5309 int timeout, int verbosemode)
5311 union ccb *ccb = NULL;
5312 struct scsi_vpd_supported_page_list sup_pages;
5316 ccb = cam_getccb(dev);
5318 warn("Unable to allocate CCB");
5323 /* cam_getccb cleans up the header, caller has to zero the payload */
5324 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5326 bzero(&sup_pages, sizeof(sup_pages));
5328 scsi_inquiry(&ccb->csio,
5329 /*retries*/ retry_count,
5331 /* tag_action */ MSG_SIMPLE_Q_TAG,
5332 /* inq_buf */ (u_int8_t *)&sup_pages,
5333 /* inq_len */ sizeof(sup_pages),
5335 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5336 /* sense_len */ SSD_FULL_SIZE,
5337 /* timeout */ timeout ? timeout : 5000);
5339 /* Disable freezing the device queue */
5340 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5342 if (retry_count != 0)
5343 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5345 if (cam_send_ccb(dev, ccb) < 0) {
5352 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5353 if (verbosemode != 0)
5354 cam_error_print(dev, ccb, CAM_ESF_ALL,
5355 CAM_EPF_ALL, stderr);
5360 for (i = 0; i < sup_pages.length; i++) {
5361 if (sup_pages.list[i] == page_id) {
5374 * devtype is filled in with the type of device.
5375 * Returns 0 for success, non-zero for failure.
5378 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5379 int verbosemode, camcontrol_devtype *devtype)
5381 struct ccb_getdev cgd;
5384 retval = get_cgd(dev, &cgd);
5388 switch (cgd.protocol) {
5394 *devtype = CC_DT_ATA;
5396 break; /*NOTREACHED*/
5398 *devtype = CC_DT_UNKNOWN;
5400 break; /*NOTREACHED*/
5404 * Check for the ATA Information VPD page (0x89). If this is an
5405 * ATA device behind a SCSI to ATA translation layer, this VPD page
5406 * should be present.
5408 * If that VPD page isn't present, or we get an error back from the
5409 * INQUIRY command, we'll just treat it as a normal SCSI device.
5411 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5412 timeout, verbosemode);
5414 *devtype = CC_DT_ATA_BEHIND_SCSI;
5416 *devtype = CC_DT_SCSI;
5425 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5426 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5427 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5428 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5429 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5430 int is48bit, camcontrol_devtype devtype)
5434 if (devtype == CC_DT_ATA) {
5435 cam_fill_ataio(&ccb->ataio,
5436 /*retries*/ retry_count,
5439 /*tag_action*/ tag_action,
5440 /*data_ptr*/ data_ptr,
5441 /*dxfer_len*/ dxfer_len,
5442 /*timeout*/ timeout);
5443 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5444 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5447 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5450 if (auxiliary != 0) {
5451 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5452 ccb->ataio.aux = auxiliary;
5455 if (ata_flags & AP_FLAG_CHK_COND)
5456 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5458 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5459 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5460 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5461 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5463 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5464 protocol |= AP_EXTEND;
5466 retval = scsi_ata_pass(&ccb->csio,
5467 /*retries*/ retry_count,
5470 /*tag_action*/ tag_action,
5471 /*protocol*/ protocol,
5472 /*ata_flags*/ ata_flags,
5473 /*features*/ features,
5474 /*sector_count*/ sector_count,
5476 /*command*/ command,
5479 /*auxiliary*/ auxiliary,
5481 /*data_ptr*/ data_ptr,
5482 /*dxfer_len*/ dxfer_len,
5483 /*cdb_storage*/ cdb_storage,
5484 /*cdb_storage_len*/ cdb_storage_len,
5485 /*minimum_cmd_size*/ 0,
5486 /*sense_len*/ sense_len,
5487 /*timeout*/ timeout);
5494 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5495 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5499 switch (ccb->ccb_h.func_code) {
5502 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5505 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5506 * or 16 byte, and need to see what
5508 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5509 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5511 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5512 if ((opcode != ATA_PASS_12)
5513 && (opcode != ATA_PASS_16)) {
5515 warnx("%s: unsupported opcode %02x", __func__, opcode);
5519 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5521 /* Note: the _ccb() variant returns 0 for an error */
5528 switch (error_code) {
5529 case SSD_DESC_CURRENT_ERROR:
5530 case SSD_DESC_DEFERRED_ERROR: {
5531 struct scsi_sense_data_desc *sense;
5532 struct scsi_sense_ata_ret_desc *desc;
5535 sense = (struct scsi_sense_data_desc *)
5536 &ccb->csio.sense_data;
5538 desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len -
5539 ccb->csio.sense_resid, SSD_DESC_ATA);
5540 if (desc_ptr == NULL) {
5541 cam_error_print(dev, ccb, CAM_ESF_ALL,
5542 CAM_EPF_ALL, stderr);
5546 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5548 *error = desc->error;
5549 *count = (desc->count_15_8 << 8) |
5551 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5552 ((uint64_t)desc->lba_39_32 << 32) |
5553 ((uint64_t)desc->lba_31_24 << 24) |
5554 (desc->lba_23_16 << 16) |
5555 (desc->lba_15_8 << 8) |
5557 *device = desc->device;
5558 *status = desc->status;
5561 * If the extend bit isn't set, the result is for a
5562 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5563 * command without the extend bit set. This means
5564 * that the device is supposed to return 28-bit
5565 * status. The count field is only 8 bits, and the
5566 * LBA field is only 8 bits.
5568 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5574 case SSD_CURRENT_ERROR:
5575 case SSD_DEFERRED_ERROR: {
5577 struct scsi_sense_data_fixed *sense;
5580 * XXX KDM need to support fixed sense data.
5582 warnx("%s: Fixed sense data not supported yet",
5586 break; /*NOTREACHED*/
5597 struct ata_res *res;
5600 * In this case, we have an ATA command, and we need to
5601 * fill in the requested values from the result register
5604 res = &ccb->ataio.res;
5605 *error = res->error;
5606 *status = res->status;
5607 *device = res->device;
5608 *count = res->sector_count;
5609 *lba = (res->lba_high << 16) |
5610 (res->lba_mid << 8) |
5612 if (res->flags & CAM_ATAIO_48BIT) {
5613 *count |= (res->sector_count_exp << 8);
5614 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5615 ((uint64_t)res->lba_mid_exp << 32) |
5616 ((uint64_t)res->lba_high_exp << 40);
5618 *lba |= (res->device & 0xf) << 24;
5631 cpi_print(struct ccb_pathinq *cpi)
5633 char adapter_str[1024];
5636 snprintf(adapter_str, sizeof(adapter_str),
5637 "%s%d:", cpi->dev_name, cpi->unit_number);
5639 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5642 for (i = 1; i < UINT8_MAX; i = i << 1) {
5645 if ((i & cpi->hba_inquiry) == 0)
5648 fprintf(stdout, "%s supports ", adapter_str);
5652 str = "MDP message";
5655 str = "32 bit wide SCSI";
5658 str = "16 bit wide SCSI";
5661 str = "SDTR message";
5664 str = "linked CDBs";
5667 str = "tag queue messages";
5670 str = "soft reset alternative";
5673 str = "SATA Port Multiplier";
5676 str = "unknown PI bit set";
5679 fprintf(stdout, "%s\n", str);
5682 for (i = 1; i < UINT32_MAX; i = i << 1) {
5685 if ((i & cpi->hba_misc) == 0)
5688 fprintf(stdout, "%s ", adapter_str);
5692 str = "can understand ata_ext requests";
5695 str = "64bit extended LUNs supported";
5698 str = "bus scans from high ID to low ID";
5701 str = "removable devices not included in scan";
5703 case PIM_NOINITIATOR:
5704 str = "initiator role not supported";
5706 case PIM_NOBUSRESET:
5707 str = "user has disabled initial BUS RESET or"
5708 " controller is in target/mixed mode";
5711 str = "do not send 6-byte commands";
5714 str = "scan bus sequentially";
5717 str = "unmapped I/O supported";
5720 str = "does its own scanning";
5723 str = "unknown PIM bit set";
5726 fprintf(stdout, "%s\n", str);
5729 for (i = 1; i < UINT16_MAX; i = i << 1) {
5732 if ((i & cpi->target_sprt) == 0)
5735 fprintf(stdout, "%s supports ", adapter_str);
5738 str = "target mode processor mode";
5741 str = "target mode phase cog. mode";
5743 case PIT_DISCONNECT:
5744 str = "disconnects in target mode";
5747 str = "terminate I/O message in target mode";
5750 str = "group 6 commands in target mode";
5753 str = "group 7 commands in target mode";
5756 str = "unknown PIT bit set";
5760 fprintf(stdout, "%s\n", str);
5762 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5764 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5766 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5768 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5769 adapter_str, cpi->hpath_id);
5770 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5772 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5773 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5774 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5775 adapter_str, cpi->hba_vendor);
5776 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5777 adapter_str, cpi->hba_device);
5778 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5779 adapter_str, cpi->hba_subvendor);
5780 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5781 adapter_str, cpi->hba_subdevice);
5782 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5783 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5784 if (cpi->base_transfer_speed > 1000)
5785 fprintf(stdout, "%d.%03dMB/sec\n",
5786 cpi->base_transfer_speed / 1000,
5787 cpi->base_transfer_speed % 1000);
5789 fprintf(stdout, "%dKB/sec\n",
5790 (cpi->base_transfer_speed % 1000) * 1000);
5791 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5792 adapter_str, cpi->maxio);
5796 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5797 struct ccb_trans_settings *cts)
5803 ccb = cam_getccb(device);
5806 warnx("get_print_cts: error allocating ccb");
5810 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5812 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5814 if (user_settings == 0)
5815 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5817 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5819 if (cam_send_ccb(device, ccb) < 0) {
5820 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5821 if (arglist & CAM_ARG_VERBOSE)
5822 cam_error_print(device, ccb, CAM_ESF_ALL,
5823 CAM_EPF_ALL, stderr);
5825 goto get_print_cts_bailout;
5828 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5829 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5830 if (arglist & CAM_ARG_VERBOSE)
5831 cam_error_print(device, ccb, CAM_ESF_ALL,
5832 CAM_EPF_ALL, stderr);
5834 goto get_print_cts_bailout;
5838 cts_print(device, &ccb->cts);
5841 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5843 get_print_cts_bailout:
5851 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
5852 int timeout, int argc, char **argv, char *combinedopt)
5856 int user_settings = 0;
5858 int disc_enable = -1, tag_enable = -1;
5861 double syncrate = -1;
5864 int change_settings = 0, send_tur = 0;
5865 struct ccb_pathinq cpi;
5867 ccb = cam_getccb(device);
5869 warnx("ratecontrol: error allocating ccb");
5872 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5881 if (strncasecmp(optarg, "enable", 6) == 0)
5883 else if (strncasecmp(optarg, "disable", 7) == 0)
5886 warnx("-D argument \"%s\" is unknown", optarg);
5888 goto ratecontrol_bailout;
5890 change_settings = 1;
5893 mode = ata_string2mode(optarg);
5895 warnx("unknown mode '%s'", optarg);
5897 goto ratecontrol_bailout;
5899 change_settings = 1;
5902 offset = strtol(optarg, NULL, 0);
5904 warnx("offset value %d is < 0", offset);
5906 goto ratecontrol_bailout;
5908 change_settings = 1;
5914 syncrate = atof(optarg);
5916 warnx("sync rate %f is < 0", syncrate);
5918 goto ratecontrol_bailout;
5920 change_settings = 1;
5923 if (strncasecmp(optarg, "enable", 6) == 0)
5925 else if (strncasecmp(optarg, "disable", 7) == 0)
5928 warnx("-T argument \"%s\" is unknown", optarg);
5930 goto ratecontrol_bailout;
5932 change_settings = 1;
5938 bus_width = strtol(optarg, NULL, 0);
5939 if (bus_width < 0) {
5940 warnx("bus width %d is < 0", bus_width);
5942 goto ratecontrol_bailout;
5944 change_settings = 1;
5950 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5952 * Grab path inquiry information, so we can determine whether
5953 * or not the initiator is capable of the things that the user
5956 ccb->ccb_h.func_code = XPT_PATH_INQ;
5957 if (cam_send_ccb(device, ccb) < 0) {
5958 perror("error sending XPT_PATH_INQ CCB");
5959 if (arglist & CAM_ARG_VERBOSE) {
5960 cam_error_print(device, ccb, CAM_ESF_ALL,
5961 CAM_EPF_ALL, stderr);
5964 goto ratecontrol_bailout;
5966 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5967 warnx("XPT_PATH_INQ CCB failed");
5968 if (arglist & CAM_ARG_VERBOSE) {
5969 cam_error_print(device, ccb, CAM_ESF_ALL,
5970 CAM_EPF_ALL, stderr);
5973 goto ratecontrol_bailout;
5975 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5976 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5978 fprintf(stdout, "%s parameters:\n",
5979 user_settings ? "User" : "Current");
5981 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5983 goto ratecontrol_bailout;
5985 if (arglist & CAM_ARG_VERBOSE)
5988 if (change_settings) {
5989 int didsettings = 0;
5990 struct ccb_trans_settings_spi *spi = NULL;
5991 struct ccb_trans_settings_pata *pata = NULL;
5992 struct ccb_trans_settings_sata *sata = NULL;
5993 struct ccb_trans_settings_ata *ata = NULL;
5994 struct ccb_trans_settings_scsi *scsi = NULL;
5996 if (ccb->cts.transport == XPORT_SPI)
5997 spi = &ccb->cts.xport_specific.spi;
5998 if (ccb->cts.transport == XPORT_ATA)
5999 pata = &ccb->cts.xport_specific.ata;
6000 if (ccb->cts.transport == XPORT_SATA)
6001 sata = &ccb->cts.xport_specific.sata;
6002 if (ccb->cts.protocol == PROTO_ATA)
6003 ata = &ccb->cts.proto_specific.ata;
6004 if (ccb->cts.protocol == PROTO_SCSI)
6005 scsi = &ccb->cts.proto_specific.scsi;
6006 ccb->cts.xport_specific.valid = 0;
6007 ccb->cts.proto_specific.valid = 0;
6008 if (spi && disc_enable != -1) {
6009 spi->valid |= CTS_SPI_VALID_DISC;
6010 if (disc_enable == 0)
6011 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6013 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6016 if (tag_enable != -1) {
6017 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6018 warnx("HBA does not support tagged queueing, "
6019 "so you cannot modify tag settings");
6021 goto ratecontrol_bailout;
6024 ata->valid |= CTS_SCSI_VALID_TQ;
6025 if (tag_enable == 0)
6026 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6028 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6031 scsi->valid |= CTS_SCSI_VALID_TQ;
6032 if (tag_enable == 0)
6033 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6035 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6039 if (spi && offset != -1) {
6040 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6041 warnx("HBA is not capable of changing offset");
6043 goto ratecontrol_bailout;
6045 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6046 spi->sync_offset = offset;
6049 if (spi && syncrate != -1) {
6050 int prelim_sync_period;
6052 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6053 warnx("HBA is not capable of changing "
6056 goto ratecontrol_bailout;
6058 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6060 * The sync rate the user gives us is in MHz.
6061 * We need to translate it into KHz for this
6066 * Next, we calculate a "preliminary" sync period
6067 * in tenths of a nanosecond.
6070 prelim_sync_period = 0;
6072 prelim_sync_period = 10000000 / syncrate;
6074 scsi_calc_syncparam(prelim_sync_period);
6077 if (sata && syncrate != -1) {
6078 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6079 warnx("HBA is not capable of changing "
6082 goto ratecontrol_bailout;
6084 if (!user_settings) {
6085 warnx("You can modify only user rate "
6086 "settings for SATA");
6088 goto ratecontrol_bailout;
6090 sata->revision = ata_speed2revision(syncrate * 100);
6091 if (sata->revision < 0) {
6092 warnx("Invalid rate %f", syncrate);
6094 goto ratecontrol_bailout;
6096 sata->valid |= CTS_SATA_VALID_REVISION;
6099 if ((pata || sata) && mode != -1) {
6100 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6101 warnx("HBA is not capable of changing "
6104 goto ratecontrol_bailout;
6106 if (!user_settings) {
6107 warnx("You can modify only user mode "
6108 "settings for ATA/SATA");
6110 goto ratecontrol_bailout;
6114 pata->valid |= CTS_ATA_VALID_MODE;
6117 sata->valid |= CTS_SATA_VALID_MODE;
6122 * The bus_width argument goes like this:
6126 * Therefore, if you shift the number of bits given on the
6127 * command line right by 4, you should get the correct
6130 if (spi && bus_width != -1) {
6132 * We might as well validate things here with a
6133 * decipherable error message, rather than what
6134 * will probably be an indecipherable error message
6135 * by the time it gets back to us.
6137 if ((bus_width == 16)
6138 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6139 warnx("HBA does not support 16 bit bus width");
6141 goto ratecontrol_bailout;
6142 } else if ((bus_width == 32)
6143 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6144 warnx("HBA does not support 32 bit bus width");
6146 goto ratecontrol_bailout;
6147 } else if ((bus_width != 8)
6148 && (bus_width != 16)
6149 && (bus_width != 32)) {
6150 warnx("Invalid bus width %d", bus_width);
6152 goto ratecontrol_bailout;
6154 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6155 spi->bus_width = bus_width >> 4;
6158 if (didsettings == 0) {
6159 goto ratecontrol_bailout;
6161 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6162 if (cam_send_ccb(device, ccb) < 0) {
6163 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
6164 if (arglist & CAM_ARG_VERBOSE) {
6165 cam_error_print(device, ccb, CAM_ESF_ALL,
6166 CAM_EPF_ALL, stderr);
6169 goto ratecontrol_bailout;
6171 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6172 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6173 if (arglist & CAM_ARG_VERBOSE) {
6174 cam_error_print(device, ccb, CAM_ESF_ALL,
6175 CAM_EPF_ALL, stderr);
6178 goto ratecontrol_bailout;
6182 retval = testunitready(device, task_attr, retry_count, timeout,
6183 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6185 * If the TUR didn't succeed, just bail.
6189 fprintf(stderr, "Test Unit Ready failed\n");
6190 goto ratecontrol_bailout;
6193 if ((change_settings || send_tur) && !quiet &&
6194 (ccb->cts.transport == XPORT_ATA ||
6195 ccb->cts.transport == XPORT_SATA || send_tur)) {
6196 fprintf(stdout, "New parameters:\n");
6197 retval = get_print_cts(device, user_settings, 0, NULL);
6200 ratecontrol_bailout:
6206 scsiformat(struct cam_device *device, int argc, char **argv,
6207 char *combinedopt, int task_attr, int retry_count, int timeout)
6211 int ycount = 0, quiet = 0;
6212 int error = 0, retval = 0;
6213 int use_timeout = 10800 * 1000;
6215 struct format_defect_list_header fh;
6216 u_int8_t *data_ptr = NULL;
6217 u_int32_t dxfer_len = 0;
6219 int num_warnings = 0;
6222 ccb = cam_getccb(device);
6225 warnx("scsiformat: error allocating ccb");
6229 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6231 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6252 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6253 "following device:\n");
6255 error = scsidoinquiry(device, argc, argv, combinedopt,
6256 task_attr, retry_count, timeout);
6259 warnx("scsiformat: error sending inquiry");
6260 goto scsiformat_bailout;
6265 if (!get_confirmation()) {
6267 goto scsiformat_bailout;
6272 use_timeout = timeout;
6275 fprintf(stdout, "Current format timeout is %d seconds\n",
6276 use_timeout / 1000);
6280 * If the user hasn't disabled questions and didn't specify a
6281 * timeout on the command line, ask them if they want the current
6285 && (timeout == 0)) {
6287 int new_timeout = 0;
6289 fprintf(stdout, "Enter new timeout in seconds or press\n"
6290 "return to keep the current timeout [%d] ",
6291 use_timeout / 1000);
6293 if (fgets(str, sizeof(str), stdin) != NULL) {
6295 new_timeout = atoi(str);
6298 if (new_timeout != 0) {
6299 use_timeout = new_timeout * 1000;
6300 fprintf(stdout, "Using new timeout value %d\n",
6301 use_timeout / 1000);
6306 * Keep this outside the if block below to silence any unused
6307 * variable warnings.
6309 bzero(&fh, sizeof(fh));
6312 * If we're in immediate mode, we've got to include the format
6315 if (immediate != 0) {
6316 fh.byte2 = FU_DLH_IMMED;
6317 data_ptr = (u_int8_t *)&fh;
6318 dxfer_len = sizeof(fh);
6319 byte2 = FU_FMT_DATA;
6320 } else if (quiet == 0) {
6321 fprintf(stdout, "Formatting...");
6325 scsi_format_unit(&ccb->csio,
6326 /* retries */ retry_count,
6328 /* tag_action */ task_attr,
6331 /* data_ptr */ data_ptr,
6332 /* dxfer_len */ dxfer_len,
6333 /* sense_len */ SSD_FULL_SIZE,
6334 /* timeout */ use_timeout);
6336 /* Disable freezing the device queue */
6337 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6339 if (arglist & CAM_ARG_ERR_RECOVER)
6340 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6342 if (((retval = cam_send_ccb(device, ccb)) < 0)
6343 || ((immediate == 0)
6344 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6345 const char errstr[] = "error sending format command";
6352 if (arglist & CAM_ARG_VERBOSE) {
6353 cam_error_print(device, ccb, CAM_ESF_ALL,
6354 CAM_EPF_ALL, stderr);
6357 goto scsiformat_bailout;
6361 * If we ran in non-immediate mode, we already checked for errors
6362 * above and printed out any necessary information. If we're in
6363 * immediate mode, we need to loop through and get status
6364 * information periodically.
6366 if (immediate == 0) {
6368 fprintf(stdout, "Format Complete\n");
6370 goto scsiformat_bailout;
6377 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6380 * There's really no need to do error recovery or
6381 * retries here, since we're just going to sit in a
6382 * loop and wait for the device to finish formatting.
6384 scsi_test_unit_ready(&ccb->csio,
6387 /* tag_action */ task_attr,
6388 /* sense_len */ SSD_FULL_SIZE,
6389 /* timeout */ 5000);
6391 /* Disable freezing the device queue */
6392 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6394 retval = cam_send_ccb(device, ccb);
6397 * If we get an error from the ioctl, bail out. SCSI
6398 * errors are expected.
6401 warn("error sending CAMIOCOMMAND ioctl");
6402 if (arglist & CAM_ARG_VERBOSE) {
6403 cam_error_print(device, ccb, CAM_ESF_ALL,
6404 CAM_EPF_ALL, stderr);
6407 goto scsiformat_bailout;
6410 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6412 if ((status != CAM_REQ_CMP)
6413 && (status == CAM_SCSI_STATUS_ERROR)
6414 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6415 struct scsi_sense_data *sense;
6416 int error_code, sense_key, asc, ascq;
6418 sense = &ccb->csio.sense_data;
6419 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6420 ccb->csio.sense_resid, &error_code, &sense_key,
6421 &asc, &ascq, /*show_errors*/ 1);
6424 * According to the SCSI-2 and SCSI-3 specs, a
6425 * drive that is in the middle of a format should
6426 * return NOT READY with an ASC of "logical unit
6427 * not ready, format in progress". The sense key
6428 * specific bytes will then be a progress indicator.
6430 if ((sense_key == SSD_KEY_NOT_READY)
6431 && (asc == 0x04) && (ascq == 0x04)) {
6434 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6435 ccb->csio.sense_resid, sks) == 0)
6438 u_int64_t percentage;
6440 val = scsi_2btoul(&sks[1]);
6441 percentage = 10000ull * val;
6444 "\rFormatting: %ju.%02u %% "
6446 (uintmax_t)(percentage /
6448 (unsigned)((percentage /
6452 } else if ((quiet == 0)
6453 && (++num_warnings <= 1)) {
6454 warnx("Unexpected SCSI Sense Key "
6455 "Specific value returned "
6457 scsi_sense_print(device, &ccb->csio,
6459 warnx("Unable to print status "
6460 "information, but format will "
6462 warnx("will exit when format is "
6467 warnx("Unexpected SCSI error during format");
6468 cam_error_print(device, ccb, CAM_ESF_ALL,
6469 CAM_EPF_ALL, stderr);
6471 goto scsiformat_bailout;
6474 } else if (status != CAM_REQ_CMP) {
6475 warnx("Unexpected CAM status %#x", status);
6476 if (arglist & CAM_ARG_VERBOSE)
6477 cam_error_print(device, ccb, CAM_ESF_ALL,
6478 CAM_EPF_ALL, stderr);
6480 goto scsiformat_bailout;
6483 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6486 fprintf(stdout, "\nFormat Complete\n");
6496 scsisanitize(struct cam_device *device, int argc, char **argv,
6497 char *combinedopt, int task_attr, int retry_count, int timeout)
6500 u_int8_t action = 0;
6502 int ycount = 0, quiet = 0;
6503 int error = 0, retval = 0;
6504 int use_timeout = 10800 * 1000;
6510 const char *pattern = NULL;
6511 u_int8_t *data_ptr = NULL;
6512 u_int32_t dxfer_len = 0;
6514 int num_warnings = 0;
6517 ccb = cam_getccb(device);
6520 warnx("scsisanitize: error allocating ccb");
6524 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6526 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6529 if (strcasecmp(optarg, "overwrite") == 0)
6530 action = SSZ_SERVICE_ACTION_OVERWRITE;
6531 else if (strcasecmp(optarg, "block") == 0)
6532 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6533 else if (strcasecmp(optarg, "crypto") == 0)
6534 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6535 else if (strcasecmp(optarg, "exitfailure") == 0)
6536 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6538 warnx("invalid service operation \"%s\"",
6541 goto scsisanitize_bailout;
6545 passes = strtol(optarg, NULL, 0);
6546 if (passes < 1 || passes > 31) {
6547 warnx("invalid passes value %d", passes);
6549 goto scsisanitize_bailout;
6580 warnx("an action is required");
6582 goto scsisanitize_bailout;
6583 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6584 struct scsi_sanitize_parameter_list *pl;
6588 if (pattern == NULL) {
6589 warnx("overwrite action requires -P argument");
6591 goto scsisanitize_bailout;
6593 fd = open(pattern, O_RDONLY);
6595 warn("cannot open pattern file %s", pattern);
6597 goto scsisanitize_bailout;
6599 if (fstat(fd, &sb) < 0) {
6600 warn("cannot stat pattern file %s", pattern);
6602 goto scsisanitize_bailout;
6605 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6606 warnx("pattern file size exceeds maximum value %d",
6607 SSZPL_MAX_PATTERN_LENGTH);
6609 goto scsisanitize_bailout;
6611 dxfer_len = sizeof(*pl) + sz;
6612 data_ptr = calloc(1, dxfer_len);
6613 if (data_ptr == NULL) {
6614 warnx("cannot allocate parameter list buffer");
6616 goto scsisanitize_bailout;
6619 amt = read(fd, data_ptr + sizeof(*pl), sz);
6621 warn("cannot read pattern file");
6623 goto scsisanitize_bailout;
6624 } else if (amt != sz) {
6625 warnx("short pattern file read");
6627 goto scsisanitize_bailout;
6630 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6636 pl->byte1 |= SSZPL_INVERT;
6637 scsi_ulto2b(sz, pl->length);
6643 else if (invert != 0)
6645 else if (pattern != NULL)
6650 warnx("%s argument only valid with overwrite "
6653 goto scsisanitize_bailout;
6658 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6659 "following device:\n");
6661 error = scsidoinquiry(device, argc, argv, combinedopt,
6662 task_attr, retry_count, timeout);
6665 warnx("scsisanitize: error sending inquiry");
6666 goto scsisanitize_bailout;
6671 if (!get_confirmation()) {
6673 goto scsisanitize_bailout;
6678 use_timeout = timeout;
6681 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6682 use_timeout / 1000);
6686 * If the user hasn't disabled questions and didn't specify a
6687 * timeout on the command line, ask them if they want the current
6691 && (timeout == 0)) {
6693 int new_timeout = 0;
6695 fprintf(stdout, "Enter new timeout in seconds or press\n"
6696 "return to keep the current timeout [%d] ",
6697 use_timeout / 1000);
6699 if (fgets(str, sizeof(str), stdin) != NULL) {
6701 new_timeout = atoi(str);
6704 if (new_timeout != 0) {
6705 use_timeout = new_timeout * 1000;
6706 fprintf(stdout, "Using new timeout value %d\n",
6707 use_timeout / 1000);
6713 byte2 |= SSZ_UNRESTRICTED_EXIT;
6717 scsi_sanitize(&ccb->csio,
6718 /* retries */ retry_count,
6720 /* tag_action */ task_attr,
6723 /* data_ptr */ data_ptr,
6724 /* dxfer_len */ dxfer_len,
6725 /* sense_len */ SSD_FULL_SIZE,
6726 /* timeout */ use_timeout);
6728 /* Disable freezing the device queue */
6729 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6731 if (arglist & CAM_ARG_ERR_RECOVER)
6732 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6734 if (cam_send_ccb(device, ccb) < 0) {
6735 warn("error sending sanitize command");
6737 goto scsisanitize_bailout;
6740 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6741 struct scsi_sense_data *sense;
6742 int error_code, sense_key, asc, ascq;
6744 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6745 CAM_SCSI_STATUS_ERROR) {
6746 sense = &ccb->csio.sense_data;
6747 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6748 ccb->csio.sense_resid, &error_code, &sense_key,
6749 &asc, &ascq, /*show_errors*/ 1);
6751 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6752 asc == 0x20 && ascq == 0x00)
6753 warnx("sanitize is not supported by "
6756 warnx("error sanitizing this device");
6758 warnx("error sanitizing this device");
6760 if (arglist & CAM_ARG_VERBOSE) {
6761 cam_error_print(device, ccb, CAM_ESF_ALL,
6762 CAM_EPF_ALL, stderr);
6765 goto scsisanitize_bailout;
6769 * If we ran in non-immediate mode, we already checked for errors
6770 * above and printed out any necessary information. If we're in
6771 * immediate mode, we need to loop through and get status
6772 * information periodically.
6774 if (immediate == 0) {
6776 fprintf(stdout, "Sanitize Complete\n");
6778 goto scsisanitize_bailout;
6785 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6788 * There's really no need to do error recovery or
6789 * retries here, since we're just going to sit in a
6790 * loop and wait for the device to finish sanitizing.
6792 scsi_test_unit_ready(&ccb->csio,
6795 /* tag_action */ task_attr,
6796 /* sense_len */ SSD_FULL_SIZE,
6797 /* timeout */ 5000);
6799 /* Disable freezing the device queue */
6800 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6802 retval = cam_send_ccb(device, ccb);
6805 * If we get an error from the ioctl, bail out. SCSI
6806 * errors are expected.
6809 warn("error sending CAMIOCOMMAND ioctl");
6810 if (arglist & CAM_ARG_VERBOSE) {
6811 cam_error_print(device, ccb, CAM_ESF_ALL,
6812 CAM_EPF_ALL, stderr);
6815 goto scsisanitize_bailout;
6818 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6820 if ((status != CAM_REQ_CMP)
6821 && (status == CAM_SCSI_STATUS_ERROR)
6822 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6823 struct scsi_sense_data *sense;
6824 int error_code, sense_key, asc, ascq;
6826 sense = &ccb->csio.sense_data;
6827 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6828 ccb->csio.sense_resid, &error_code, &sense_key,
6829 &asc, &ascq, /*show_errors*/ 1);
6832 * According to the SCSI-3 spec, a drive that is in the
6833 * middle of a sanitize should return NOT READY with an
6834 * ASC of "logical unit not ready, sanitize in
6835 * progress". The sense key specific bytes will then
6836 * be a progress indicator.
6838 if ((sense_key == SSD_KEY_NOT_READY)
6839 && (asc == 0x04) && (ascq == 0x1b)) {
6842 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6843 ccb->csio.sense_resid, sks) == 0)
6846 u_int64_t percentage;
6848 val = scsi_2btoul(&sks[1]);
6849 percentage = 10000 * val;
6852 "\rSanitizing: %ju.%02u %% "
6854 (uintmax_t)(percentage /
6856 (unsigned)((percentage /
6860 } else if ((quiet == 0)
6861 && (++num_warnings <= 1)) {
6862 warnx("Unexpected SCSI Sense Key "
6863 "Specific value returned "
6864 "during sanitize:");
6865 scsi_sense_print(device, &ccb->csio,
6867 warnx("Unable to print status "
6868 "information, but sanitze will "
6870 warnx("will exit when sanitize is "
6875 warnx("Unexpected SCSI error during sanitize");
6876 cam_error_print(device, ccb, CAM_ESF_ALL,
6877 CAM_EPF_ALL, stderr);
6879 goto scsisanitize_bailout;
6882 } else if (status != CAM_REQ_CMP) {
6883 warnx("Unexpected CAM status %#x", status);
6884 if (arglist & CAM_ARG_VERBOSE)
6885 cam_error_print(device, ccb, CAM_ESF_ALL,
6886 CAM_EPF_ALL, stderr);
6888 goto scsisanitize_bailout;
6890 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6893 fprintf(stdout, "\nSanitize Complete\n");
6895 scsisanitize_bailout:
6898 if (data_ptr != NULL)
6906 scsireportluns(struct cam_device *device, int argc, char **argv,
6907 char *combinedopt, int task_attr, int retry_count, int timeout)
6910 int c, countonly, lunsonly;
6911 struct scsi_report_luns_data *lundata;
6913 uint8_t report_type;
6914 uint32_t list_len, i, j;
6919 report_type = RPL_REPORT_DEFAULT;
6920 ccb = cam_getccb(device);
6923 warnx("%s: error allocating ccb", __func__);
6927 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6932 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6941 if (strcasecmp(optarg, "default") == 0)
6942 report_type = RPL_REPORT_DEFAULT;
6943 else if (strcasecmp(optarg, "wellknown") == 0)
6944 report_type = RPL_REPORT_WELLKNOWN;
6945 else if (strcasecmp(optarg, "all") == 0)
6946 report_type = RPL_REPORT_ALL;
6948 warnx("%s: invalid report type \"%s\"",
6959 if ((countonly != 0)
6960 && (lunsonly != 0)) {
6961 warnx("%s: you can only specify one of -c or -l", __func__);
6966 * According to SPC-4, the allocation length must be at least 16
6967 * bytes -- enough for the header and one LUN.
6969 alloc_len = sizeof(*lundata) + 8;
6973 lundata = malloc(alloc_len);
6975 if (lundata == NULL) {
6976 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6981 scsi_report_luns(&ccb->csio,
6982 /*retries*/ retry_count,
6984 /*tag_action*/ task_attr,
6985 /*select_report*/ report_type,
6986 /*rpl_buf*/ lundata,
6987 /*alloc_len*/ alloc_len,
6988 /*sense_len*/ SSD_FULL_SIZE,
6989 /*timeout*/ timeout ? timeout : 5000);
6991 /* Disable freezing the device queue */
6992 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6994 if (arglist & CAM_ARG_ERR_RECOVER)
6995 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6997 if (cam_send_ccb(device, ccb) < 0) {
6998 warn("error sending REPORT LUNS command");
7000 if (arglist & CAM_ARG_VERBOSE)
7001 cam_error_print(device, ccb, CAM_ESF_ALL,
7002 CAM_EPF_ALL, stderr);
7008 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7009 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7015 list_len = scsi_4btoul(lundata->length);
7018 * If we need to list the LUNs, and our allocation
7019 * length was too short, reallocate and retry.
7021 if ((countonly == 0)
7022 && (list_len > (alloc_len - sizeof(*lundata)))) {
7023 alloc_len = list_len + sizeof(*lundata);
7029 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7030 ((list_len / 8) > 1) ? "s" : "");
7035 for (i = 0; i < (list_len / 8); i++) {
7039 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7041 fprintf(stdout, ",");
7042 switch (lundata->luns[i].lundata[j] &
7043 RPL_LUNDATA_ATYP_MASK) {
7044 case RPL_LUNDATA_ATYP_PERIPH:
7045 if ((lundata->luns[i].lundata[j] &
7046 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7047 fprintf(stdout, "%d:",
7048 lundata->luns[i].lundata[j] &
7049 RPL_LUNDATA_PERIPH_BUS_MASK);
7051 && ((lundata->luns[i].lundata[j+2] &
7052 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7055 fprintf(stdout, "%d",
7056 lundata->luns[i].lundata[j+1]);
7058 case RPL_LUNDATA_ATYP_FLAT: {
7060 tmplun[0] = lundata->luns[i].lundata[j] &
7061 RPL_LUNDATA_FLAT_LUN_MASK;
7062 tmplun[1] = lundata->luns[i].lundata[j+1];
7064 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7068 case RPL_LUNDATA_ATYP_LUN:
7069 fprintf(stdout, "%d:%d:%d",
7070 (lundata->luns[i].lundata[j+1] &
7071 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7072 lundata->luns[i].lundata[j] &
7073 RPL_LUNDATA_LUN_TARG_MASK,
7074 lundata->luns[i].lundata[j+1] &
7075 RPL_LUNDATA_LUN_LUN_MASK);
7077 case RPL_LUNDATA_ATYP_EXTLUN: {
7078 int field_len_code, eam_code;
7080 eam_code = lundata->luns[i].lundata[j] &
7081 RPL_LUNDATA_EXT_EAM_MASK;
7082 field_len_code = (lundata->luns[i].lundata[j] &
7083 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7085 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7086 && (field_len_code == 0x00)) {
7087 fprintf(stdout, "%d",
7088 lundata->luns[i].lundata[j+1]);
7089 } else if ((eam_code ==
7090 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7091 && (field_len_code == 0x03)) {
7095 * This format takes up all 8 bytes.
7096 * If we aren't starting at offset 0,
7100 fprintf(stdout, "Invalid "
7103 "specified format", j);
7107 bzero(tmp_lun, sizeof(tmp_lun));
7108 bcopy(&lundata->luns[i].lundata[j+1],
7109 &tmp_lun[1], sizeof(tmp_lun) - 1);
7110 fprintf(stdout, "%#jx",
7111 (intmax_t)scsi_8btou64(tmp_lun));
7114 fprintf(stderr, "Unknown Extended LUN"
7115 "Address method %#x, length "
7116 "code %#x", eam_code,
7123 fprintf(stderr, "Unknown LUN address method "
7124 "%#x\n", lundata->luns[i].lundata[0] &
7125 RPL_LUNDATA_ATYP_MASK);
7129 * For the flat addressing method, there are no
7130 * other levels after it.
7135 fprintf(stdout, "\n");
7148 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7149 char *combinedopt, int task_attr, int retry_count, int timeout)
7152 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
7153 struct scsi_read_capacity_data rcap;
7154 struct scsi_read_capacity_data_long rcaplong;
7168 ccb = cam_getccb(device);
7171 warnx("%s: error allocating ccb", __func__);
7175 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7177 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7204 if ((blocksizeonly != 0)
7205 && (numblocks != 0)) {
7206 warnx("%s: you can only specify one of -b or -N", __func__);
7211 if ((blocksizeonly != 0)
7212 && (sizeonly != 0)) {
7213 warnx("%s: you can only specify one of -b or -s", __func__);
7220 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7226 && (blocksizeonly != 0)) {
7227 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7232 scsi_read_capacity(&ccb->csio,
7233 /*retries*/ retry_count,
7235 /*tag_action*/ task_attr,
7238 /*timeout*/ timeout ? timeout : 5000);
7240 /* Disable freezing the device queue */
7241 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7243 if (arglist & CAM_ARG_ERR_RECOVER)
7244 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7246 if (cam_send_ccb(device, ccb) < 0) {
7247 warn("error sending READ CAPACITY command");
7249 if (arglist & CAM_ARG_VERBOSE)
7250 cam_error_print(device, ccb, CAM_ESF_ALL,
7251 CAM_EPF_ALL, stderr);
7257 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7258 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7263 maxsector = scsi_4btoul(rcap.addr);
7264 block_len = scsi_4btoul(rcap.length);
7267 * A last block of 2^32-1 means that the true capacity is over 2TB,
7268 * and we need to issue the long READ CAPACITY to get the real
7269 * capacity. Otherwise, we're all set.
7271 if (maxsector != 0xffffffff)
7274 scsi_read_capacity_16(&ccb->csio,
7275 /*retries*/ retry_count,
7277 /*tag_action*/ task_attr,
7281 /*rcap_buf*/ (uint8_t *)&rcaplong,
7282 /*rcap_buf_len*/ sizeof(rcaplong),
7283 /*sense_len*/ SSD_FULL_SIZE,
7284 /*timeout*/ timeout ? timeout : 5000);
7286 /* Disable freezing the device queue */
7287 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7289 if (arglist & CAM_ARG_ERR_RECOVER)
7290 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7292 if (cam_send_ccb(device, ccb) < 0) {
7293 warn("error sending READ CAPACITY (16) command");
7295 if (arglist & CAM_ARG_VERBOSE)
7296 cam_error_print(device, ccb, CAM_ESF_ALL,
7297 CAM_EPF_ALL, stderr);
7303 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7304 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7309 maxsector = scsi_8btou64(rcaplong.addr);
7310 block_len = scsi_4btoul(rcaplong.length);
7313 if (blocksizeonly == 0) {
7315 * Humanize implies !quiet, and also implies numblocks.
7317 if (humanize != 0) {
7322 tmpbytes = (maxsector + 1) * block_len;
7323 ret = humanize_number(tmpstr, sizeof(tmpstr),
7324 tmpbytes, "", HN_AUTOSCALE,
7327 HN_DIVISOR_1000 : 0));
7329 warnx("%s: humanize_number failed!", __func__);
7333 fprintf(stdout, "Device Size: %s%s", tmpstr,
7334 (sizeonly == 0) ? ", " : "\n");
7335 } else if (numblocks != 0) {
7336 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7337 "Blocks: " : "", (uintmax_t)maxsector + 1,
7338 (sizeonly == 0) ? ", " : "\n");
7340 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7341 "Last Block: " : "", (uintmax_t)maxsector,
7342 (sizeonly == 0) ? ", " : "\n");
7346 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7347 "Block Length: " : "", block_len, (quiet == 0) ?
7356 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7357 int retry_count, int timeout)
7361 uint8_t *smp_request = NULL, *smp_response = NULL;
7362 int request_size = 0, response_size = 0;
7363 int fd_request = 0, fd_response = 0;
7364 char *datastr = NULL;
7365 struct get_hook hook;
7370 * Note that at the moment we don't support sending SMP CCBs to
7371 * devices that aren't probed by CAM.
7373 ccb = cam_getccb(device);
7375 warnx("%s: error allocating CCB", __func__);
7379 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7381 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7384 arglist |= CAM_ARG_CMD_IN;
7385 response_size = strtol(optarg, NULL, 0);
7386 if (response_size <= 0) {
7387 warnx("invalid number of response bytes %d",
7390 goto smpcmd_bailout;
7392 hook.argc = argc - optind;
7393 hook.argv = argv + optind;
7396 datastr = cget(&hook, NULL);
7398 * If the user supplied "-" instead of a format, he
7399 * wants the data to be written to stdout.
7401 if ((datastr != NULL)
7402 && (datastr[0] == '-'))
7405 smp_response = (u_int8_t *)malloc(response_size);
7406 if (smp_response == NULL) {
7407 warn("can't malloc memory for SMP response");
7409 goto smpcmd_bailout;
7413 arglist |= CAM_ARG_CMD_OUT;
7414 request_size = strtol(optarg, NULL, 0);
7415 if (request_size <= 0) {
7416 warnx("invalid number of request bytes %d",
7419 goto smpcmd_bailout;
7421 hook.argc = argc - optind;
7422 hook.argv = argv + optind;
7424 datastr = cget(&hook, NULL);
7425 smp_request = (u_int8_t *)malloc(request_size);
7426 if (smp_request == NULL) {
7427 warn("can't malloc memory for SMP request");
7429 goto smpcmd_bailout;
7431 bzero(smp_request, request_size);
7433 * If the user supplied "-" instead of a format, he
7434 * wants the data to be read from stdin.
7436 if ((datastr != NULL)
7437 && (datastr[0] == '-'))
7440 buff_encode_visit(smp_request, request_size,
7451 * If fd_data is set, and we're writing to the device, we need to
7452 * read the data the user wants written from stdin.
7454 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7456 int amt_to_read = request_size;
7457 u_int8_t *buf_ptr = smp_request;
7459 for (amt_read = 0; amt_to_read > 0;
7460 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7461 if (amt_read == -1) {
7462 warn("error reading data from stdin");
7464 goto smpcmd_bailout;
7466 amt_to_read -= amt_read;
7467 buf_ptr += amt_read;
7471 if (((arglist & CAM_ARG_CMD_IN) == 0)
7472 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7473 warnx("%s: need both the request (-r) and response (-R) "
7474 "arguments", __func__);
7476 goto smpcmd_bailout;
7479 flags |= CAM_DEV_QFRZDIS;
7481 cam_fill_smpio(&ccb->smpio,
7482 /*retries*/ retry_count,
7485 /*smp_request*/ smp_request,
7486 /*smp_request_len*/ request_size,
7487 /*smp_response*/ smp_response,
7488 /*smp_response_len*/ response_size,
7489 /*timeout*/ timeout ? timeout : 5000);
7491 ccb->smpio.flags = SMP_FLAG_NONE;
7493 if (((retval = cam_send_ccb(device, ccb)) < 0)
7494 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7495 const char warnstr[] = "error sending command";
7502 if (arglist & CAM_ARG_VERBOSE) {
7503 cam_error_print(device, ccb, CAM_ESF_ALL,
7504 CAM_EPF_ALL, stderr);
7508 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7509 && (response_size > 0)) {
7510 if (fd_response == 0) {
7511 buff_decode_visit(smp_response, response_size,
7512 datastr, arg_put, NULL);
7513 fprintf(stdout, "\n");
7515 ssize_t amt_written;
7516 int amt_to_write = response_size;
7517 u_int8_t *buf_ptr = smp_response;
7519 for (amt_written = 0; (amt_to_write > 0) &&
7520 (amt_written = write(STDOUT_FILENO, buf_ptr,
7521 amt_to_write)) > 0;){
7522 amt_to_write -= amt_written;
7523 buf_ptr += amt_written;
7525 if (amt_written == -1) {
7526 warn("error writing data to stdout");
7528 goto smpcmd_bailout;
7529 } else if ((amt_written == 0)
7530 && (amt_to_write > 0)) {
7531 warnx("only wrote %u bytes out of %u",
7532 response_size - amt_to_write,
7541 if (smp_request != NULL)
7544 if (smp_response != NULL)
7551 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7552 int retry_count, int timeout)
7556 int32_t mmc_opcode = 0, mmc_arg = 0;
7557 int32_t mmc_flags = -1;
7560 int is_bw_4 = 0, is_bw_1 = 0;
7561 int is_highspeed = 0, is_stdspeed = 0;
7562 int is_info_request = 0;
7564 uint8_t mmc_data_byte = 0;
7566 /* For IO_RW_EXTENDED command */
7567 uint8_t *mmc_data = NULL;
7568 struct mmc_data mmc_d;
7569 int mmc_data_len = 0;
7572 * Note that at the moment we don't support sending SMP CCBs to
7573 * devices that aren't probed by CAM.
7575 ccb = cam_getccb(device);
7577 warnx("%s: error allocating CCB", __func__);
7581 bzero(&(&ccb->ccb_h)[1],
7582 sizeof(union ccb) - sizeof(struct ccb_hdr));
7584 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7593 if (!strcmp(optarg, "high"))
7599 is_info_request = 1;
7602 mmc_opcode = strtol(optarg, NULL, 0);
7603 if (mmc_opcode < 0) {
7604 warnx("invalid MMC opcode %d",
7607 goto mmccmd_bailout;
7611 mmc_arg = strtol(optarg, NULL, 0);
7613 warnx("invalid MMC arg %d",
7616 goto mmccmd_bailout;
7620 mmc_flags = strtol(optarg, NULL, 0);
7621 if (mmc_flags < 0) {
7622 warnx("invalid MMC flags %d",
7625 goto mmccmd_bailout;
7629 mmc_data_len = strtol(optarg, NULL, 0);
7630 if (mmc_data_len <= 0) {
7631 warnx("invalid MMC data len %d",
7634 goto mmccmd_bailout;
7641 mmc_data_byte = strtol(optarg, NULL, 0);
7647 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7649 /* If flags are left default, supply the right flags */
7651 switch (mmc_opcode) {
7652 case MMC_GO_IDLE_STATE:
7653 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7655 case IO_SEND_OP_COND:
7656 mmc_flags = MMC_RSP_R4;
7658 case SD_SEND_RELATIVE_ADDR:
7659 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7661 case MMC_SELECT_CARD:
7662 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7663 mmc_arg = mmc_arg << 16;
7665 case SD_IO_RW_DIRECT:
7666 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7667 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7669 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7671 case SD_IO_RW_EXTENDED:
7672 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7673 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7674 int len_arg = mmc_data_len;
7675 if (mmc_data_len == 512)
7679 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7681 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7684 mmc_flags = MMC_RSP_R1;
7688 // Switch bus width instead of sending IO command
7689 if (is_bw_4 || is_bw_1) {
7690 struct ccb_trans_settings_mmc *cts;
7691 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7692 ccb->ccb_h.flags = 0;
7693 cts = &ccb->cts.proto_specific.mmc;
7694 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7695 cts->ios_valid = MMC_BW;
7696 if (((retval = cam_send_ccb(device, ccb)) < 0)
7697 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7698 warn("Error sending command");
7700 printf("Parameters set OK\n");
7706 // Switch bus speed instead of sending IO command
7707 if (is_stdspeed || is_highspeed) {
7708 struct ccb_trans_settings_mmc *cts;
7709 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7710 ccb->ccb_h.flags = 0;
7711 cts = &ccb->cts.proto_specific.mmc;
7712 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
7713 cts->ios_valid = MMC_BT;
7714 if (((retval = cam_send_ccb(device, ccb)) < 0)
7715 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7716 warn("Error sending command");
7718 printf("Speed set OK (HS: %d)\n", is_highspeed);
7724 // Get information about controller and its settings
7725 if (is_info_request) {
7726 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
7727 ccb->ccb_h.flags = 0;
7728 struct ccb_trans_settings_mmc *cts;
7729 cts = &ccb->cts.proto_specific.mmc;
7730 if (((retval = cam_send_ccb(device, ccb)) < 0)
7731 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7732 warn("Error sending command");
7735 printf("Host controller information\n");
7736 printf("Host OCR: 0x%x\n", cts->host_ocr);
7737 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
7738 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
7739 printf("Supported bus width: ");
7740 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
7742 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
7744 printf("\nCurrent settings:\n");
7745 printf("Bus width: ");
7746 switch (cts->ios.bus_width) {
7757 printf("Freq: %d.%03d MHz%s\n",
7758 cts->ios.clock / 1000000,
7759 (cts->ios.clock / 1000) % 1000,
7760 cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : "");
7764 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
7766 if (mmc_data_len > 0) {
7767 flags |= CAM_DIR_IN;
7768 mmc_data = malloc(mmc_data_len);
7769 memset(mmc_data, 0, mmc_data_len);
7770 mmc_d.len = mmc_data_len;
7771 mmc_d.data = mmc_data;
7772 mmc_d.flags = MMC_DATA_READ;
7773 } else flags |= CAM_DIR_NONE;
7775 cam_fill_mmcio(&ccb->mmcio,
7776 /*retries*/ retry_count,
7779 /*mmc_opcode*/ mmc_opcode,
7780 /*mmc_arg*/ mmc_arg,
7781 /*mmc_flags*/ mmc_flags,
7782 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
7783 /*timeout*/ timeout ? timeout : 5000);
7785 if (((retval = cam_send_ccb(device, ccb)) < 0)
7786 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7787 const char warnstr[] = "error sending command";
7794 if (arglist & CAM_ARG_VERBOSE) {
7795 cam_error_print(device, ccb, CAM_ESF_ALL,
7796 CAM_EPF_ALL, stderr);
7800 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
7801 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
7802 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
7803 ccb->mmcio.cmd.resp[1],
7804 ccb->mmcio.cmd.resp[2],
7805 ccb->mmcio.cmd.resp[3]);
7807 switch (mmc_opcode) {
7808 case SD_IO_RW_DIRECT:
7809 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
7810 SD_R5_DATA(ccb->mmcio.cmd.resp),
7811 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
7813 case SD_IO_RW_EXTENDED:
7814 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
7815 hexdump(mmc_data, mmc_data_len, NULL, 0);
7817 case SD_SEND_RELATIVE_ADDR:
7818 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
7821 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
7828 if (mmc_data_len > 0 && mmc_data != NULL)
7835 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7836 char *combinedopt, int retry_count, int timeout)
7839 struct smp_report_general_request *request = NULL;
7840 struct smp_report_general_response *response = NULL;
7841 struct sbuf *sb = NULL;
7843 int c, long_response = 0;
7847 * Note that at the moment we don't support sending SMP CCBs to
7848 * devices that aren't probed by CAM.
7850 ccb = cam_getccb(device);
7852 warnx("%s: error allocating CCB", __func__);
7856 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7858 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7867 request = malloc(sizeof(*request));
7868 if (request == NULL) {
7869 warn("%s: unable to allocate %zd bytes", __func__,
7875 response = malloc(sizeof(*response));
7876 if (response == NULL) {
7877 warn("%s: unable to allocate %zd bytes", __func__,
7884 smp_report_general(&ccb->smpio,
7888 /*request_len*/ sizeof(*request),
7889 (uint8_t *)response,
7890 /*response_len*/ sizeof(*response),
7891 /*long_response*/ long_response,
7894 if (((retval = cam_send_ccb(device, ccb)) < 0)
7895 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7896 const char warnstr[] = "error sending command";
7903 if (arglist & CAM_ARG_VERBOSE) {
7904 cam_error_print(device, ccb, CAM_ESF_ALL,
7905 CAM_EPF_ALL, stderr);
7912 * If the device supports the long response bit, try again and see
7913 * if we can get all of the data.
7915 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7916 && (long_response == 0)) {
7917 ccb->ccb_h.status = CAM_REQ_INPROG;
7918 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7924 * XXX KDM detect and decode SMP errors here.
7926 sb = sbuf_new_auto();
7928 warnx("%s: error allocating sbuf", __func__);
7932 smp_report_general_sbuf(response, sizeof(*response), sb);
7934 if (sbuf_finish(sb) != 0) {
7935 warnx("%s: sbuf_finish", __func__);
7939 printf("%s", sbuf_data(sb));
7945 if (request != NULL)
7948 if (response != NULL)
7957 static struct camcontrol_opts phy_ops[] = {
7958 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7959 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7960 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7961 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7962 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7963 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7964 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7965 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7966 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7971 smpphycontrol(struct cam_device *device, int argc, char **argv,
7972 char *combinedopt, int retry_count, int timeout)
7975 struct smp_phy_control_request *request = NULL;
7976 struct smp_phy_control_response *response = NULL;
7977 int long_response = 0;
7980 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7982 uint64_t attached_dev_name = 0;
7983 int dev_name_set = 0;
7984 uint32_t min_plr = 0, max_plr = 0;
7985 uint32_t pp_timeout_val = 0;
7986 int slumber_partial = 0;
7987 int set_pp_timeout_val = 0;
7991 * Note that at the moment we don't support sending SMP CCBs to
7992 * devices that aren't probed by CAM.
7994 ccb = cam_getccb(device);
7996 warnx("%s: error allocating CCB", __func__);
8000 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8002 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8010 if (strcasecmp(optarg, "enable") == 0)
8012 else if (strcasecmp(optarg, "disable") == 0)
8015 warnx("%s: Invalid argument %s", __func__,
8022 slumber_partial |= enable <<
8023 SMP_PC_SAS_SLUMBER_SHIFT;
8026 slumber_partial |= enable <<
8027 SMP_PC_SAS_PARTIAL_SHIFT;
8030 slumber_partial |= enable <<
8031 SMP_PC_SATA_SLUMBER_SHIFT;
8034 slumber_partial |= enable <<
8035 SMP_PC_SATA_PARTIAL_SHIFT;
8038 warnx("%s: programmer error", __func__);
8041 break; /*NOTREACHED*/
8046 attached_dev_name = (uintmax_t)strtoumax(optarg,
8055 * We don't do extensive checking here, so this
8056 * will continue to work when new speeds come out.
8058 min_plr = strtoul(optarg, NULL, 0);
8060 || (min_plr > 0xf)) {
8061 warnx("%s: invalid link rate %x",
8069 * We don't do extensive checking here, so this
8070 * will continue to work when new speeds come out.
8072 max_plr = strtoul(optarg, NULL, 0);
8074 || (max_plr > 0xf)) {
8075 warnx("%s: invalid link rate %x",
8082 camcontrol_optret optreturn;
8083 cam_argmask argnums;
8086 if (phy_op_set != 0) {
8087 warnx("%s: only one phy operation argument "
8088 "(-o) allowed", __func__);
8096 * Allow the user to specify the phy operation
8097 * numerically, as well as with a name. This will
8098 * future-proof it a bit, so options that are added
8099 * in future specs can be used.
8101 if (isdigit(optarg[0])) {
8102 phy_operation = strtoul(optarg, NULL, 0);
8103 if ((phy_operation == 0)
8104 || (phy_operation > 0xff)) {
8105 warnx("%s: invalid phy operation %#x",
8106 __func__, phy_operation);
8112 optreturn = getoption(phy_ops, optarg, &phy_operation,
8115 if (optreturn == CC_OR_AMBIGUOUS) {
8116 warnx("%s: ambiguous option %s", __func__,
8121 } else if (optreturn == CC_OR_NOT_FOUND) {
8122 warnx("%s: option %s not found", __func__,
8134 pp_timeout_val = strtoul(optarg, NULL, 0);
8135 if (pp_timeout_val > 15) {
8136 warnx("%s: invalid partial pathway timeout "
8137 "value %u, need a value less than 16",
8138 __func__, pp_timeout_val);
8142 set_pp_timeout_val = 1;
8150 warnx("%s: a PHY (-p phy) argument is required",__func__);
8155 if (((dev_name_set != 0)
8156 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8157 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8158 && (dev_name_set == 0))) {
8159 warnx("%s: -d name and -o setdevname arguments both "
8160 "required to set device name", __func__);
8165 request = malloc(sizeof(*request));
8166 if (request == NULL) {
8167 warn("%s: unable to allocate %zd bytes", __func__,
8173 response = malloc(sizeof(*response));
8174 if (response == NULL) {
8175 warn("%s: unable to allocate %zd bytes", __func__,
8181 smp_phy_control(&ccb->smpio,
8186 (uint8_t *)response,
8189 /*expected_exp_change_count*/ 0,
8192 (set_pp_timeout_val != 0) ? 1 : 0,
8200 if (((retval = cam_send_ccb(device, ccb)) < 0)
8201 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8202 const char warnstr[] = "error sending command";
8209 if (arglist & CAM_ARG_VERBOSE) {
8211 * Use CAM_EPF_NORMAL so we only get one line of
8212 * SMP command decoding.
8214 cam_error_print(device, ccb, CAM_ESF_ALL,
8215 CAM_EPF_NORMAL, stderr);
8221 /* XXX KDM print out something here for success? */
8226 if (request != NULL)
8229 if (response != NULL)
8236 smpmaninfo(struct cam_device *device, int argc, char **argv,
8237 char *combinedopt, int retry_count, int timeout)
8240 struct smp_report_manuf_info_request request;
8241 struct smp_report_manuf_info_response response;
8242 struct sbuf *sb = NULL;
8243 int long_response = 0;
8248 * Note that at the moment we don't support sending SMP CCBs to
8249 * devices that aren't probed by CAM.
8251 ccb = cam_getccb(device);
8253 warnx("%s: error allocating CCB", __func__);
8257 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8259 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8268 bzero(&request, sizeof(request));
8269 bzero(&response, sizeof(response));
8271 smp_report_manuf_info(&ccb->smpio,
8276 (uint8_t *)&response,
8281 if (((retval = cam_send_ccb(device, ccb)) < 0)
8282 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8283 const char warnstr[] = "error sending command";
8290 if (arglist & CAM_ARG_VERBOSE) {
8291 cam_error_print(device, ccb, CAM_ESF_ALL,
8292 CAM_EPF_ALL, stderr);
8298 sb = sbuf_new_auto();
8300 warnx("%s: error allocating sbuf", __func__);
8304 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8306 if (sbuf_finish(sb) != 0) {
8307 warnx("%s: sbuf_finish", __func__);
8311 printf("%s", sbuf_data(sb));
8325 getdevid(struct cam_devitem *item)
8328 union ccb *ccb = NULL;
8330 struct cam_device *dev;
8332 dev = cam_open_btl(item->dev_match.path_id,
8333 item->dev_match.target_id,
8334 item->dev_match.target_lun, O_RDWR, NULL);
8337 warnx("%s", cam_errbuf);
8342 item->device_id_len = 0;
8344 ccb = cam_getccb(dev);
8346 warnx("%s: error allocating CCB", __func__);
8351 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8354 * On the first try, we just probe for the size of the data, and
8355 * then allocate that much memory and try again.
8358 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8359 ccb->ccb_h.flags = CAM_DIR_IN;
8360 ccb->cdai.flags = CDAI_FLAG_NONE;
8361 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8362 ccb->cdai.bufsiz = item->device_id_len;
8363 if (item->device_id_len != 0)
8364 ccb->cdai.buf = (uint8_t *)item->device_id;
8366 if (cam_send_ccb(dev, ccb) < 0) {
8367 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8372 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8373 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8378 if (item->device_id_len == 0) {
8380 * This is our first time through. Allocate the buffer,
8381 * and then go back to get the data.
8383 if (ccb->cdai.provsiz == 0) {
8384 warnx("%s: invalid .provsiz field returned with "
8385 "XPT_GDEV_ADVINFO CCB", __func__);
8389 item->device_id_len = ccb->cdai.provsiz;
8390 item->device_id = malloc(item->device_id_len);
8391 if (item->device_id == NULL) {
8392 warn("%s: unable to allocate %d bytes", __func__,
8393 item->device_id_len);
8397 ccb->ccb_h.status = CAM_REQ_INPROG;
8403 cam_close_device(dev);
8412 * XXX KDM merge this code with getdevtree()?
8415 buildbusdevlist(struct cam_devlist *devlist)
8418 int bufsize, fd = -1;
8419 struct dev_match_pattern *patterns;
8420 struct cam_devitem *item = NULL;
8421 int skip_device = 0;
8424 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8425 warn("couldn't open %s", XPT_DEVICE);
8429 bzero(&ccb, sizeof(union ccb));
8431 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8432 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8433 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8435 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8436 bufsize = sizeof(struct dev_match_result) * 100;
8437 ccb.cdm.match_buf_len = bufsize;
8438 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8439 if (ccb.cdm.matches == NULL) {
8440 warnx("can't malloc memory for matches");
8444 ccb.cdm.num_matches = 0;
8445 ccb.cdm.num_patterns = 2;
8446 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8447 ccb.cdm.num_patterns;
8449 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8450 if (patterns == NULL) {
8451 warnx("can't malloc memory for patterns");
8456 ccb.cdm.patterns = patterns;
8457 bzero(patterns, ccb.cdm.pattern_buf_len);
8459 patterns[0].type = DEV_MATCH_DEVICE;
8460 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8461 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8462 patterns[1].type = DEV_MATCH_PERIPH;
8463 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8464 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8467 * We do the ioctl multiple times if necessary, in case there are
8468 * more than 100 nodes in the EDT.
8473 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8474 warn("error sending CAMIOCOMMAND ioctl");
8479 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8480 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8481 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8482 warnx("got CAM error %#x, CDM error %d\n",
8483 ccb.ccb_h.status, ccb.cdm.status);
8488 for (i = 0; i < ccb.cdm.num_matches; i++) {
8489 switch (ccb.cdm.matches[i].type) {
8490 case DEV_MATCH_DEVICE: {
8491 struct device_match_result *dev_result;
8494 &ccb.cdm.matches[i].result.device_result;
8496 if (dev_result->flags &
8497 DEV_RESULT_UNCONFIGURED) {
8503 item = malloc(sizeof(*item));
8505 warn("%s: unable to allocate %zd bytes",
8506 __func__, sizeof(*item));
8510 bzero(item, sizeof(*item));
8511 bcopy(dev_result, &item->dev_match,
8512 sizeof(*dev_result));
8513 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8516 if (getdevid(item) != 0) {
8522 case DEV_MATCH_PERIPH: {
8523 struct periph_match_result *periph_result;
8526 &ccb.cdm.matches[i].result.periph_result;
8528 if (skip_device != 0)
8530 item->num_periphs++;
8531 item->periph_matches = realloc(
8532 item->periph_matches,
8534 sizeof(struct periph_match_result));
8535 if (item->periph_matches == NULL) {
8536 warn("%s: error allocating periph "
8541 bcopy(periph_result, &item->periph_matches[
8542 item->num_periphs - 1],
8543 sizeof(*periph_result));
8547 fprintf(stderr, "%s: unexpected match "
8548 "type %d\n", __func__,
8549 ccb.cdm.matches[i].type);
8552 break; /*NOTREACHED*/
8555 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8556 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8564 free(ccb.cdm.matches);
8567 freebusdevlist(devlist);
8573 freebusdevlist(struct cam_devlist *devlist)
8575 struct cam_devitem *item, *item2;
8577 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8578 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8580 free(item->device_id);
8581 free(item->periph_matches);
8586 static struct cam_devitem *
8587 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8589 struct cam_devitem *item;
8591 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8592 struct scsi_vpd_id_descriptor *idd;
8595 * XXX KDM look for LUN IDs as well?
8597 idd = scsi_get_devid(item->device_id,
8598 item->device_id_len,
8599 scsi_devid_is_sas_target);
8603 if (scsi_8btou64(idd->identifier) == sasaddr)
8611 smpphylist(struct cam_device *device, int argc, char **argv,
8612 char *combinedopt, int retry_count, int timeout)
8614 struct smp_report_general_request *rgrequest = NULL;
8615 struct smp_report_general_response *rgresponse = NULL;
8616 struct smp_discover_request *disrequest = NULL;
8617 struct smp_discover_response *disresponse = NULL;
8618 struct cam_devlist devlist;
8620 int long_response = 0;
8627 * Note that at the moment we don't support sending SMP CCBs to
8628 * devices that aren't probed by CAM.
8630 ccb = cam_getccb(device);
8632 warnx("%s: error allocating CCB", __func__);
8636 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8637 STAILQ_INIT(&devlist.dev_queue);
8639 rgrequest = malloc(sizeof(*rgrequest));
8640 if (rgrequest == NULL) {
8641 warn("%s: unable to allocate %zd bytes", __func__,
8642 sizeof(*rgrequest));
8647 rgresponse = malloc(sizeof(*rgresponse));
8648 if (rgresponse == NULL) {
8649 warn("%s: unable to allocate %zd bytes", __func__,
8650 sizeof(*rgresponse));
8655 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8668 smp_report_general(&ccb->smpio,
8672 /*request_len*/ sizeof(*rgrequest),
8673 (uint8_t *)rgresponse,
8674 /*response_len*/ sizeof(*rgresponse),
8675 /*long_response*/ long_response,
8678 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8680 if (((retval = cam_send_ccb(device, ccb)) < 0)
8681 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8682 const char warnstr[] = "error sending command";
8689 if (arglist & CAM_ARG_VERBOSE) {
8690 cam_error_print(device, ccb, CAM_ESF_ALL,
8691 CAM_EPF_ALL, stderr);
8697 num_phys = rgresponse->num_phys;
8699 if (num_phys == 0) {
8701 fprintf(stdout, "%s: No Phys reported\n", __func__);
8706 devlist.path_id = device->path_id;
8708 retval = buildbusdevlist(&devlist);
8713 fprintf(stdout, "%d PHYs:\n", num_phys);
8714 fprintf(stdout, "PHY Attached SAS Address\n");
8717 disrequest = malloc(sizeof(*disrequest));
8718 if (disrequest == NULL) {
8719 warn("%s: unable to allocate %zd bytes", __func__,
8720 sizeof(*disrequest));
8725 disresponse = malloc(sizeof(*disresponse));
8726 if (disresponse == NULL) {
8727 warn("%s: unable to allocate %zd bytes", __func__,
8728 sizeof(*disresponse));
8733 for (i = 0; i < num_phys; i++) {
8734 struct cam_devitem *item;
8735 struct device_match_result *dev_match;
8736 char vendor[16], product[48], revision[16];
8740 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8742 ccb->ccb_h.status = CAM_REQ_INPROG;
8743 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8745 smp_discover(&ccb->smpio,
8749 sizeof(*disrequest),
8750 (uint8_t *)disresponse,
8751 sizeof(*disresponse),
8753 /*ignore_zone_group*/ 0,
8757 if (((retval = cam_send_ccb(device, ccb)) < 0)
8758 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
8759 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
8760 const char warnstr[] = "error sending command";
8767 if (arglist & CAM_ARG_VERBOSE) {
8768 cam_error_print(device, ccb, CAM_ESF_ALL,
8769 CAM_EPF_ALL, stderr);
8775 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
8777 fprintf(stdout, "%3d <vacant>\n", i);
8781 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
8784 item = findsasdevice(&devlist,
8785 scsi_8btou64(disresponse->attached_sas_address));
8789 || (item != NULL)) {
8790 fprintf(stdout, "%3d 0x%016jx", i,
8791 (uintmax_t)scsi_8btou64(
8792 disresponse->attached_sas_address));
8794 fprintf(stdout, "\n");
8797 } else if (quiet != 0)
8800 dev_match = &item->dev_match;
8802 if (dev_match->protocol == PROTO_SCSI) {
8803 cam_strvis(vendor, dev_match->inq_data.vendor,
8804 sizeof(dev_match->inq_data.vendor),
8806 cam_strvis(product, dev_match->inq_data.product,
8807 sizeof(dev_match->inq_data.product),
8809 cam_strvis(revision, dev_match->inq_data.revision,
8810 sizeof(dev_match->inq_data.revision),
8812 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8814 } else if ((dev_match->protocol == PROTO_ATA)
8815 || (dev_match->protocol == PROTO_SATAPM)) {
8816 cam_strvis(product, dev_match->ident_data.model,
8817 sizeof(dev_match->ident_data.model),
8819 cam_strvis(revision, dev_match->ident_data.revision,
8820 sizeof(dev_match->ident_data.revision),
8822 sprintf(tmpstr, "<%s %s>", product, revision);
8824 sprintf(tmpstr, "<>");
8826 fprintf(stdout, " %-33s ", tmpstr);
8829 * If we have 0 periphs, that's a bug...
8831 if (item->num_periphs == 0) {
8832 fprintf(stdout, "\n");
8836 fprintf(stdout, "(");
8837 for (j = 0; j < item->num_periphs; j++) {
8839 fprintf(stdout, ",");
8841 fprintf(stdout, "%s%d",
8842 item->periph_matches[j].periph_name,
8843 item->periph_matches[j].unit_number);
8846 fprintf(stdout, ")\n");
8860 freebusdevlist(&devlist);
8866 atapm(struct cam_device *device, int argc, char **argv,
8867 char *combinedopt, int retry_count, int timeout)
8875 ccb = cam_getccb(device);
8878 warnx("%s: error allocating ccb", __func__);
8882 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8891 if (strcmp(argv[1], "idle") == 0) {
8893 cmd = ATA_IDLE_IMMEDIATE;
8896 } else if (strcmp(argv[1], "standby") == 0) {
8898 cmd = ATA_STANDBY_IMMEDIATE;
8900 cmd = ATA_STANDBY_CMD;
8908 else if (t <= (240 * 5))
8910 else if (t <= (252 * 5))
8911 /* special encoding for 21 minutes */
8913 else if (t <= (11 * 30 * 60))
8914 sc = (t - 1) / (30 * 60) + 241;
8918 retval = ata_do_28bit_cmd(device,
8920 /*retries*/retry_count,
8921 /*flags*/CAM_DIR_NONE,
8922 /*protocol*/AP_PROTO_NON_DATA,
8923 /*tag_action*/MSG_SIMPLE_Q_TAG,
8930 /*timeout*/timeout ? timeout : 30 * 1000,
8938 ataaxm(struct cam_device *device, int argc, char **argv,
8939 char *combinedopt, int retry_count, int timeout)
8947 ccb = cam_getccb(device);
8950 warnx("%s: error allocating ccb", __func__);
8954 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8964 if (strcmp(argv[1], "apm") == 0) {
8980 retval = ata_do_28bit_cmd(device,
8982 /*retries*/retry_count,
8983 /*flags*/CAM_DIR_NONE,
8984 /*protocol*/AP_PROTO_NON_DATA,
8985 /*tag_action*/MSG_SIMPLE_Q_TAG,
8986 /*command*/ATA_SETFEATURES,
8992 /*timeout*/timeout ? timeout : 30 * 1000,
9000 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9001 int show_sa_errors, int sa_set, int service_action,
9002 int timeout_desc, int task_attr, int retry_count, int timeout,
9003 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9005 union ccb *ccb = NULL;
9006 uint8_t *buf = NULL;
9007 uint32_t alloc_len = 0, num_opcodes;
9008 uint32_t valid_len = 0;
9009 uint32_t avail_len = 0;
9010 struct scsi_report_supported_opcodes_all *all_hdr;
9011 struct scsi_report_supported_opcodes_one *one;
9016 * Make it clear that we haven't yet allocated or filled anything.
9021 ccb = cam_getccb(device);
9023 warnx("couldn't allocate CCB");
9028 /* cam_getccb cleans up the header, caller has to zero the payload */
9029 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9031 if (opcode_set != 0) {
9032 options |= RSO_OPTIONS_OC;
9034 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9037 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9038 sizeof(struct scsi_report_supported_opcodes_descr));
9041 if (timeout_desc != 0) {
9042 options |= RSO_RCTD;
9043 alloc_len += num_opcodes *
9044 sizeof(struct scsi_report_supported_opcodes_timeout);
9048 options |= RSO_OPTIONS_OC_SA;
9049 if (show_sa_errors != 0)
9050 options &= ~RSO_OPTIONS_OC;
9059 buf = malloc(alloc_len);
9061 warn("Unable to allocate %u bytes", alloc_len);
9065 bzero(buf, alloc_len);
9067 scsi_report_supported_opcodes(&ccb->csio,
9068 /*retries*/ retry_count,
9070 /*tag_action*/ task_attr,
9071 /*options*/ options,
9072 /*req_opcode*/ opcode,
9073 /*req_service_action*/ service_action,
9075 /*dxfer_len*/ alloc_len,
9076 /*sense_len*/ SSD_FULL_SIZE,
9077 /*timeout*/ timeout ? timeout : 10000);
9079 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9081 if (retry_count != 0)
9082 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9084 if (cam_send_ccb(device, ccb) < 0) {
9085 perror("error sending REPORT SUPPORTED OPERATION CODES");
9090 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9091 if (verbosemode != 0)
9092 cam_error_print(device, ccb, CAM_ESF_ALL,
9093 CAM_EPF_ALL, stderr);
9098 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9100 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9101 && (valid_len >= sizeof(*all_hdr))) {
9102 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9103 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9104 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9105 && (valid_len >= sizeof(*one))) {
9106 uint32_t cdb_length;
9108 one = (struct scsi_report_supported_opcodes_one *)buf;
9109 cdb_length = scsi_2btoul(one->cdb_length);
9110 avail_len = sizeof(*one) + cdb_length;
9111 if (one->support & RSO_ONE_CTDP) {
9112 struct scsi_report_supported_opcodes_timeout *td;
9114 td = (struct scsi_report_supported_opcodes_timeout *)
9116 if (valid_len >= (avail_len + sizeof(td->length))) {
9117 avail_len += scsi_2btoul(td->length) +
9120 avail_len += sizeof(*td);
9126 * avail_len could be zero if we didn't get enough data back from
9127 * thet target to determine
9129 if ((avail_len != 0)
9130 && (avail_len > valid_len)) {
9131 alloc_len = avail_len;
9135 *fill_len = valid_len;
9147 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9148 int req_sa, uint8_t *buf, uint32_t valid_len)
9150 struct scsi_report_supported_opcodes_one *one;
9151 struct scsi_report_supported_opcodes_timeout *td;
9152 uint32_t cdb_len = 0, td_len = 0;
9153 const char *op_desc = NULL;
9157 one = (struct scsi_report_supported_opcodes_one *)buf;
9160 * If we don't have the full single opcode descriptor, no point in
9163 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9165 warnx("Only %u bytes returned, not enough to verify support",
9171 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9173 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9176 printf(", SA 0x%x", req_sa);
9179 switch (one->support & RSO_ONE_SUP_MASK) {
9180 case RSO_ONE_SUP_UNAVAIL:
9181 printf("No command support information currently available\n");
9183 case RSO_ONE_SUP_NOT_SUP:
9184 printf("Command not supported\n");
9187 break; /*NOTREACHED*/
9188 case RSO_ONE_SUP_AVAIL:
9189 printf("Command is supported, complies with a SCSI standard\n");
9191 case RSO_ONE_SUP_VENDOR:
9192 printf("Command is supported, vendor-specific "
9193 "implementation\n");
9196 printf("Unknown command support flags 0x%#x\n",
9197 one->support & RSO_ONE_SUP_MASK);
9202 * If we don't have the CDB length, it isn't exactly an error, the
9203 * command probably isn't supported.
9205 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9209 cdb_len = scsi_2btoul(one->cdb_length);
9212 * If our valid data doesn't include the full reported length,
9213 * return. The caller should have detected this and adjusted his
9214 * allocation length to get all of the available data.
9216 if (valid_len < sizeof(*one) + cdb_len) {
9222 * If all we have is the opcode, there is no point in printing out
9230 printf("CDB usage bitmap:");
9231 for (i = 0; i < cdb_len; i++) {
9232 printf(" %02x", one->cdb_usage[i]);
9237 * If we don't have a timeout descriptor, we're done.
9239 if ((one->support & RSO_ONE_CTDP) == 0)
9243 * If we don't have enough valid length to include the timeout
9244 * descriptor length, we're done.
9246 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9249 td = (struct scsi_report_supported_opcodes_timeout *)
9250 &buf[sizeof(*one) + cdb_len];
9251 td_len = scsi_2btoul(td->length);
9252 td_len += sizeof(td->length);
9255 * If we don't have the full timeout descriptor, we're done.
9257 if (td_len < sizeof(*td))
9261 * If we don't have enough valid length to contain the full timeout
9262 * descriptor, we're done.
9264 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9267 printf("Timeout information:\n");
9268 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9269 printf("Nominal timeout: %u seconds\n",
9270 scsi_4btoul(td->nominal_time));
9271 printf("Recommended timeout: %u seconds\n",
9272 scsi_4btoul(td->recommended_time));
9279 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9282 struct scsi_report_supported_opcodes_all *hdr;
9283 struct scsi_report_supported_opcodes_descr *desc;
9284 uint32_t avail_len = 0, used_len = 0;
9288 if (valid_len < sizeof(*hdr)) {
9289 warnx("%s: not enough returned data (%u bytes) opcode list",
9290 __func__, valid_len);
9294 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9295 avail_len = scsi_4btoul(hdr->length);
9296 avail_len += sizeof(hdr->length);
9298 * Take the lesser of the amount of data the drive claims is
9299 * available, and the amount of data the HBA says was returned.
9301 avail_len = MIN(avail_len, valid_len);
9303 used_len = sizeof(hdr->length);
9305 printf("%-6s %4s %8s ",
9306 "Opcode", "SA", "CDB len" );
9309 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9310 printf(" Description\n");
9312 while ((avail_len - used_len) > sizeof(*desc)) {
9313 struct scsi_report_supported_opcodes_timeout *td;
9315 const char *op_desc = NULL;
9317 cur_ptr = &buf[used_len];
9318 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9320 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9321 if (op_desc == NULL)
9322 op_desc = "UNKNOWN";
9324 printf("0x%02x %#4x %8u ", desc->opcode,
9325 scsi_2btoul(desc->service_action),
9326 scsi_2btoul(desc->cdb_length));
9328 used_len += sizeof(*desc);
9330 if ((desc->flags & RSO_CTDP) == 0) {
9331 printf(" %s\n", op_desc);
9336 * If we don't have enough space to fit a timeout
9337 * descriptor, then we're done.
9339 if (avail_len - used_len < sizeof(*td)) {
9340 used_len = avail_len;
9341 printf(" %s\n", op_desc);
9344 cur_ptr = &buf[used_len];
9345 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9346 td_len = scsi_2btoul(td->length);
9347 td_len += sizeof(td->length);
9351 * If the given timeout descriptor length is less than what
9352 * we understand, skip it.
9354 if (td_len < sizeof(*td)) {
9355 printf(" %s\n", op_desc);
9359 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9360 scsi_4btoul(td->nominal_time),
9361 scsi_4btoul(td->recommended_time), op_desc);
9368 scsiopcodes(struct cam_device *device, int argc, char **argv,
9369 char *combinedopt, int task_attr, int retry_count, int timeout,
9373 uint32_t opcode = 0, service_action = 0;
9374 int td_set = 0, opcode_set = 0, sa_set = 0;
9375 int show_sa_errors = 1;
9376 uint32_t valid_len = 0;
9377 uint8_t *buf = NULL;
9381 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9387 opcode = strtoul(optarg, &endptr, 0);
9388 if (*endptr != '\0') {
9389 warnx("Invalid opcode \"%s\", must be a number",
9394 if (opcode > 0xff) {
9395 warnx("Invalid opcode 0x%#x, must be between"
9396 "0 and 0xff inclusive", opcode);
9403 service_action = strtoul(optarg, &endptr, 0);
9404 if (*endptr != '\0') {
9405 warnx("Invalid service action \"%s\", must "
9406 "be a number", optarg);
9410 if (service_action > 0xffff) {
9411 warnx("Invalid service action 0x%#x, must "
9412 "be between 0 and 0xffff inclusive",
9427 && (opcode_set == 0)) {
9428 warnx("You must specify an opcode with -o if a service "
9433 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9434 sa_set, service_action, td_set, task_attr,
9435 retry_count, timeout, verbosemode, &valid_len,
9440 if ((opcode_set != 0)
9442 retval = scsiprintoneopcode(device, opcode, sa_set,
9443 service_action, buf, valid_len);
9445 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9454 #endif /* MINIMALISTIC */
9457 scsireprobe(struct cam_device *device)
9462 ccb = cam_getccb(device);
9465 warnx("%s: error allocating ccb", __func__);
9469 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9471 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9473 if (cam_send_ccb(device, ccb) < 0) {
9474 warn("error sending XPT_REPROBE_LUN CCB");
9479 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9480 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9492 usage(int printlong)
9495 fprintf(printlong ? stdout : stderr,
9496 "usage: camcontrol <command> [device id][generic args][command args]\n"
9497 " camcontrol devlist [-b] [-v]\n"
9498 #ifndef MINIMALISTIC
9499 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9500 " camcontrol tur [dev_id][generic args]\n"
9501 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9502 " camcontrol identify [dev_id][generic args] [-v]\n"
9503 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9504 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9506 " camcontrol start [dev_id][generic args]\n"
9507 " camcontrol stop [dev_id][generic args]\n"
9508 " camcontrol load [dev_id][generic args]\n"
9509 " camcontrol eject [dev_id][generic args]\n"
9510 " camcontrol reprobe [dev_id][generic args]\n"
9511 #endif /* MINIMALISTIC */
9512 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9513 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9514 #ifndef MINIMALISTIC
9515 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9516 " [-q][-s][-S offset][-X]\n"
9517 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9518 " [-P pagectl][-e | -b][-d]\n"
9519 " camcontrol cmd [dev_id][generic args]\n"
9520 " <-a cmd [args] | -c cmd [args]>\n"
9521 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9522 " camcontrol smpcmd [dev_id][generic args]\n"
9523 " <-r len fmt [args]> <-R len fmt [args]>\n"
9524 " camcontrol smprg [dev_id][generic args][-l]\n"
9525 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9526 " [-o operation][-d name][-m rate][-M rate]\n"
9527 " [-T pp_timeout][-a enable|disable]\n"
9528 " [-A enable|disable][-s enable|disable]\n"
9529 " [-S enable|disable]\n"
9530 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9531 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9532 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9533 " <all|bus[:target[:lun]]|off>\n"
9534 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9535 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9536 " [-D <enable|disable>][-M mode][-O offset]\n"
9537 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9538 " [-U][-W bus_width]\n"
9539 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9540 " camcontrol sanitize [dev_id][generic args]\n"
9541 " [-a overwrite|block|crypto|exitfailure]\n"
9542 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9544 " camcontrol idle [dev_id][generic args][-t time]\n"
9545 " camcontrol standby [dev_id][generic args][-t time]\n"
9546 " camcontrol sleep [dev_id][generic args]\n"
9547 " camcontrol apm [dev_id][generic args][-l level]\n"
9548 " camcontrol aam [dev_id][generic args][-l level]\n"
9549 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9551 " camcontrol security [dev_id][generic args]\n"
9552 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9553 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9554 " [-U <user|master>] [-y]\n"
9555 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9556 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9557 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9558 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9559 " [-s scope][-S][-T type][-U]\n"
9560 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9561 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9562 " [-p part][-s start][-T type][-V vol]\n"
9563 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9565 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9566 " [-o rep_opts] [-P print_opts]\n"
9567 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9568 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9569 " [-S power_src] [-T timer]\n"
9570 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9571 " <-s <-f format -T time | -U >>\n"
9573 #endif /* MINIMALISTIC */
9574 " camcontrol help\n");
9577 #ifndef MINIMALISTIC
9579 "Specify one of the following options:\n"
9580 "devlist list all CAM devices\n"
9581 "periphlist list all CAM peripheral drivers attached to a device\n"
9582 "tur send a test unit ready to the named device\n"
9583 "inquiry send a SCSI inquiry command to the named device\n"
9584 "identify send a ATA identify command to the named device\n"
9585 "reportluns send a SCSI report luns command to the device\n"
9586 "readcap send a SCSI read capacity command to the device\n"
9587 "start send a Start Unit command to the device\n"
9588 "stop send a Stop Unit command to the device\n"
9589 "load send a Start Unit command to the device with the load bit set\n"
9590 "eject send a Stop Unit command to the device with the eject bit set\n"
9591 "reprobe update capacity information of the given device\n"
9592 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9593 "reset reset all buses, the given bus, bus:target:lun or device\n"
9594 "defects read the defect list of the specified device\n"
9595 "modepage display or edit (-e) the given mode page\n"
9596 "cmd send the given SCSI command, may need -i or -o as well\n"
9597 "smpcmd send the given SMP command, requires -o and -i\n"
9598 "smprg send the SMP Report General command\n"
9599 "smppc send the SMP PHY Control command, requires -p\n"
9600 "smpphylist display phys attached to a SAS expander\n"
9601 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9602 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9603 "tags report or set the number of transaction slots for a device\n"
9604 "negotiate report or set device negotiation parameters\n"
9605 "format send the SCSI FORMAT UNIT command to the named device\n"
9606 "sanitize send the SCSI SANITIZE command to the named device\n"
9607 "idle send the ATA IDLE command to the named device\n"
9608 "standby send the ATA STANDBY command to the named device\n"
9609 "sleep send the ATA SLEEP command to the named device\n"
9610 "fwdownload program firmware of the named device with the given image\n"
9611 "security report or send ATA security commands to the named device\n"
9612 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9613 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9614 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9615 "zone manage Zoned Block (Shingled) devices\n"
9616 "epc send ATA Extended Power Conditions commands\n"
9617 "timestamp report or set the device's timestamp\n"
9618 "help this message\n"
9619 "Device Identifiers:\n"
9620 "bus:target specify the bus and target, lun defaults to 0\n"
9621 "bus:target:lun specify the bus, target and lun\n"
9622 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
9623 "Generic arguments:\n"
9624 "-v be verbose, print out sense information\n"
9625 "-t timeout command timeout in seconds, overrides default timeout\n"
9626 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
9627 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
9628 "-E have the kernel attempt to perform SCSI error recovery\n"
9629 "-C count specify the SCSI command retry count (needs -E to work)\n"
9630 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
9631 "modepage arguments:\n"
9632 "-l list all available mode pages\n"
9633 "-m page specify the mode page to view or edit\n"
9634 "-e edit the specified mode page\n"
9635 "-b force view to binary mode\n"
9636 "-d disable block descriptors for mode sense\n"
9637 "-P pgctl page control field 0-3\n"
9638 "defects arguments:\n"
9639 "-f format specify defect list format (block, bfi or phys)\n"
9640 "-G get the grown defect list\n"
9641 "-P get the permanent defect list\n"
9642 "inquiry arguments:\n"
9643 "-D get the standard inquiry data\n"
9644 "-S get the serial number\n"
9645 "-R get the transfer rate, etc.\n"
9646 "reportluns arguments:\n"
9647 "-c only report a count of available LUNs\n"
9648 "-l only print out luns, and not a count\n"
9649 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
9650 "readcap arguments\n"
9651 "-b only report the blocksize\n"
9652 "-h human readable device size, base 2\n"
9653 "-H human readable device size, base 10\n"
9654 "-N print the number of blocks instead of last block\n"
9655 "-q quiet, print numbers only\n"
9656 "-s only report the last block/device size\n"
9658 "-c cdb [args] specify the SCSI CDB\n"
9659 "-i len fmt specify input data and input data format\n"
9660 "-o len fmt [args] specify output data and output data fmt\n"
9661 "smpcmd arguments:\n"
9662 "-r len fmt [args] specify the SMP command to be sent\n"
9663 "-R len fmt [args] specify SMP response format\n"
9664 "smprg arguments:\n"
9665 "-l specify the long response format\n"
9666 "smppc arguments:\n"
9667 "-p phy specify the PHY to operate on\n"
9668 "-l specify the long request/response format\n"
9669 "-o operation specify the phy control operation\n"
9670 "-d name set the attached device name\n"
9671 "-m rate set the minimum physical link rate\n"
9672 "-M rate set the maximum physical link rate\n"
9673 "-T pp_timeout set the partial pathway timeout value\n"
9674 "-a enable|disable enable or disable SATA slumber\n"
9675 "-A enable|disable enable or disable SATA partial phy power\n"
9676 "-s enable|disable enable or disable SAS slumber\n"
9677 "-S enable|disable enable or disable SAS partial phy power\n"
9678 "smpphylist arguments:\n"
9679 "-l specify the long response format\n"
9680 "-q only print phys with attached devices\n"
9681 "smpmaninfo arguments:\n"
9682 "-l specify the long response format\n"
9683 "debug arguments:\n"
9684 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
9685 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
9686 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
9687 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
9689 "-N tags specify the number of tags to use for this device\n"
9690 "-q be quiet, don't report the number of tags\n"
9691 "-v report a number of tag-related parameters\n"
9692 "negotiate arguments:\n"
9693 "-a send a test unit ready after negotiation\n"
9694 "-c report/set current negotiation settings\n"
9695 "-D <arg> \"enable\" or \"disable\" disconnection\n"
9696 "-M mode set ATA mode\n"
9697 "-O offset set command delay offset\n"
9698 "-q be quiet, don't report anything\n"
9699 "-R syncrate synchronization rate in MHz\n"
9700 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
9701 "-U report/set user negotiation settings\n"
9702 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
9703 "-v also print a Path Inquiry CCB for the controller\n"
9704 "format arguments:\n"
9705 "-q be quiet, don't print status messages\n"
9706 "-r run in report only mode\n"
9707 "-w don't send immediate format command\n"
9708 "-y don't ask any questions\n"
9709 "sanitize arguments:\n"
9710 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
9711 "-c passes overwrite passes to perform (1 to 31)\n"
9712 "-I invert overwrite pattern after each pass\n"
9713 "-P pattern path to overwrite pattern file\n"
9714 "-q be quiet, don't print status messages\n"
9715 "-r run in report only mode\n"
9716 "-U run operation in unrestricted completion exit mode\n"
9717 "-w don't send immediate sanitize command\n"
9718 "-y don't ask any questions\n"
9719 "idle/standby arguments:\n"
9720 "-t <arg> number of seconds before respective state.\n"
9721 "fwdownload arguments:\n"
9722 "-f fw_image path to firmware image file\n"
9723 "-q don't print informational messages, only errors\n"
9724 "-s run in simulation mode\n"
9725 "-v print info for every firmware segment sent to device\n"
9726 "-y don't ask any questions\n"
9727 "security arguments:\n"
9728 "-d pwd disable security using the given password for the selected\n"
9730 "-e pwd erase the device using the given pwd for the selected user\n"
9731 "-f freeze the security configuration of the specified device\n"
9732 "-h pwd enhanced erase the device using the given pwd for the\n"
9734 "-k pwd unlock the device using the given pwd for the selected\n"
9736 "-l <high|maximum> specifies which security level to set: high or maximum\n"
9737 "-q be quiet, do not print any status messages\n"
9738 "-s pwd password the device (enable security) using the given\n"
9739 " pwd for the selected user\n"
9740 "-T timeout overrides the timeout (seconds) used for erase operation\n"
9741 "-U <user|master> specifies which user to set: user or master\n"
9742 "-y don't ask any questions\n"
9744 "-f freeze the HPA configuration of the device\n"
9745 "-l lock the HPA configuration of the device\n"
9746 "-P make the HPA max sectors persist\n"
9747 "-p pwd Set the HPA configuration password required for unlock\n"
9749 "-q be quiet, do not print any status messages\n"
9750 "-s sectors configures the maximum user accessible sectors of the\n"
9752 "-U pwd unlock the HPA configuration of the device\n"
9753 "-y don't ask any questions\n"
9754 "persist arguments:\n"
9755 "-i action specify read_keys, read_reservation, report_cap, or\n"
9756 " read_full_status\n"
9757 "-o action specify register, register_ignore, reserve, release,\n"
9758 " clear, preempt, preempt_abort, register_move, replace_lost\n"
9759 "-a set the All Target Ports (ALL_TG_PT) bit\n"
9760 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
9761 "-k key specify the Reservation Key\n"
9762 "-K sa_key specify the Service Action Reservation Key\n"
9763 "-p set the Activate Persist Through Power Loss bit\n"
9764 "-R rtp specify the Relative Target Port\n"
9765 "-s scope specify the scope: lun, extent, element or a number\n"
9766 "-S specify Transport ID for register, requires -I\n"
9767 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
9768 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
9769 "-U unregister the current initiator for register_move\n"
9770 "attrib arguments:\n"
9771 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
9773 "-w attr specify an attribute to write, one -w argument per attr\n"
9774 "-a attr_num only display this attribute number\n"
9775 "-c get cached attributes\n"
9776 "-e elem_addr request attributes for the given element in a changer\n"
9777 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
9778 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
9779 " field_none, field_desc, field_num, field_size, field_rw\n"
9780 "-p partition request attributes for the given partition\n"
9781 "-s start_attr request attributes starting at the given number\n"
9782 "-T elem_type specify the element type (used with -e)\n"
9783 "-V logical_vol specify the logical volume ID\n"
9784 "opcodes arguments:\n"
9785 "-o opcode specify the individual opcode to list\n"
9786 "-s service_action specify the service action for the opcode\n"
9787 "-N do not return SCSI error for unsupported SA\n"
9788 "-T request nominal and recommended timeout values\n"
9790 "-c cmd required: rz, open, close, finish, or rwp\n"
9791 "-a apply the action to all zones\n"
9792 "-l LBA specify the zone starting LBA\n"
9793 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
9794 " closed, full, ro, offline, reset, nonseq, nonwp\n"
9795 "-P print_opt report zones printing: normal, summary, script\n"
9797 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
9798 " source, status, list\n"
9799 "-d disable power mode (timer, state)\n"
9800 "-D delayed entry (goto)\n"
9801 "-e enable power mode (timer, state)\n"
9802 "-H hold power mode (goto)\n"
9803 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
9805 "-P only display power mode (status)\n"
9806 "-r rst_src restore settings from: default, saved (restore)\n"
9807 "-s save mode (timer, state, restore)\n"
9808 "-S power_src set power source: battery, nonbattery (source)\n"
9809 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
9810 "timestamp arguments:\n"
9811 "-r report the timestamp of the device\n"
9812 "-f format report the timestamp of the device with the given\n"
9813 " strftime(3) format string\n"
9814 "-m report the timestamp of the device as milliseconds since\n"
9815 " January 1st, 1970\n"
9816 "-U report the time with UTC instead of the local time zone\n"
9817 "-s set the timestamp of the device\n"
9818 "-f format the format of the time string passed into strptime(3)\n"
9819 "-T time the time value passed into strptime(3)\n"
9820 "-U set the timestamp of the device to UTC time\n"
9822 #endif /* MINIMALISTIC */
9826 main(int argc, char **argv)
9829 char *device = NULL;
9831 struct cam_device *cam_dev = NULL;
9832 int timeout = 0, retry_count = 1;
9833 camcontrol_optret optreturn;
9835 const char *mainopt = "C:En:Q:t:u:v";
9836 const char *subopt = NULL;
9837 char combinedopt[256];
9838 int error = 0, optstart = 2;
9839 int task_attr = MSG_SIMPLE_Q_TAG;
9841 #ifndef MINIMALISTIC
9845 #endif /* MINIMALISTIC */
9847 cmdlist = CAM_CMD_NONE;
9848 arglist = CAM_ARG_NONE;
9856 * Get the base option.
9858 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
9860 if (optreturn == CC_OR_AMBIGUOUS) {
9861 warnx("ambiguous option %s", argv[1]);
9864 } else if (optreturn == CC_OR_NOT_FOUND) {
9865 warnx("option %s not found", argv[1]);
9871 * Ahh, getopt(3) is a pain.
9873 * This is a gross hack. There really aren't many other good
9874 * options (excuse the pun) for parsing options in a situation like
9875 * this. getopt is kinda braindead, so you end up having to run
9876 * through the options twice, and give each invocation of getopt
9877 * the option string for the other invocation.
9879 * You would think that you could just have two groups of options.
9880 * The first group would get parsed by the first invocation of
9881 * getopt, and the second group would get parsed by the second
9882 * invocation of getopt. It doesn't quite work out that way. When
9883 * the first invocation of getopt finishes, it leaves optind pointing
9884 * to the argument _after_ the first argument in the second group.
9885 * So when the second invocation of getopt comes around, it doesn't
9886 * recognize the first argument it gets and then bails out.
9888 * A nice alternative would be to have a flag for getopt that says
9889 * "just keep parsing arguments even when you encounter an unknown
9890 * argument", but there isn't one. So there's no real clean way to
9891 * easily parse two sets of arguments without having one invocation
9892 * of getopt know about the other.
9894 * Without this hack, the first invocation of getopt would work as
9895 * long as the generic arguments are first, but the second invocation
9896 * (in the subfunction) would fail in one of two ways. In the case
9897 * where you don't set optreset, it would fail because optind may be
9898 * pointing to the argument after the one it should be pointing at.
9899 * In the case where you do set optreset, and reset optind, it would
9900 * fail because getopt would run into the first set of options, which
9901 * it doesn't understand.
9903 * All of this would "sort of" work if you could somehow figure out
9904 * whether optind had been incremented one option too far. The
9905 * mechanics of that, however, are more daunting than just giving
9906 * both invocations all of the expect options for either invocation.
9908 * Needless to say, I wouldn't mind if someone invented a better
9909 * (non-GPL!) command line parsing interface than getopt. I
9910 * wouldn't mind if someone added more knobs to getopt to make it
9911 * work better. Who knows, I may talk myself into doing it someday,
9912 * if the standards weenies let me. As it is, it just leads to
9913 * hackery like this and causes people to avoid it in some cases.
9915 * KDM, September 8th, 1998
9918 sprintf(combinedopt, "%s%s", mainopt, subopt);
9920 sprintf(combinedopt, "%s", mainopt);
9923 * For these options we do not parse optional device arguments and
9924 * we do not open a passthrough device.
9926 if ((cmdlist == CAM_CMD_RESCAN)
9927 || (cmdlist == CAM_CMD_RESET)
9928 || (cmdlist == CAM_CMD_DEVTREE)
9929 || (cmdlist == CAM_CMD_USAGE)
9930 || (cmdlist == CAM_CMD_DEBUG))
9933 #ifndef MINIMALISTIC
9935 && (argc > 2 && argv[2][0] != '-')) {
9939 if (isdigit(argv[2][0])) {
9940 /* device specified as bus:target[:lun] */
9941 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9943 errx(1, "numeric device specification must "
9944 "be either bus:target, or "
9946 /* default to 0 if lun was not specified */
9947 if ((arglist & CAM_ARG_LUN) == 0) {
9949 arglist |= CAM_ARG_LUN;
9953 if (cam_get_device(argv[2], name, sizeof name, &unit)
9955 errx(1, "%s", cam_errbuf);
9956 device = strdup(name);
9957 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
9961 #endif /* MINIMALISTIC */
9963 * Start getopt processing at argv[2/3], since we've already
9964 * accepted argv[1..2] as the command name, and as a possible
9970 * Now we run through the argument list looking for generic
9971 * options, and ignoring options that possibly belong to
9974 while ((c = getopt(argc, argv, combinedopt))!= -1){
9977 retry_count = strtol(optarg, NULL, 0);
9978 if (retry_count < 0)
9979 errx(1, "retry count %d is < 0",
9981 arglist |= CAM_ARG_RETRIES;
9984 arglist |= CAM_ARG_ERR_RECOVER;
9987 arglist |= CAM_ARG_DEVICE;
9989 while (isspace(*tstr) && (*tstr != '\0'))
9991 device = (char *)strdup(tstr);
9995 int table_entry = 0;
9998 while (isspace(*tstr) && (*tstr != '\0'))
10000 if (isdigit(*tstr)) {
10001 task_attr = strtol(tstr, &endptr, 0);
10002 if (*endptr != '\0') {
10003 errx(1, "Invalid queue option "
10008 scsi_nv_status status;
10010 table_size = sizeof(task_attrs) /
10011 sizeof(task_attrs[0]);
10012 status = scsi_get_nv(task_attrs,
10013 table_size, tstr, &table_entry,
10014 SCSI_NV_FLAG_IG_CASE);
10015 if (status == SCSI_NV_FOUND)
10016 task_attr = task_attrs[
10017 table_entry].value;
10019 errx(1, "%s option %s",
10020 (status == SCSI_NV_AMBIGUOUS)?
10021 "ambiguous" : "invalid",
10028 timeout = strtol(optarg, NULL, 0);
10030 errx(1, "invalid timeout %d", timeout);
10031 /* Convert the timeout from seconds to ms */
10033 arglist |= CAM_ARG_TIMEOUT;
10036 arglist |= CAM_ARG_UNIT;
10037 unit = strtol(optarg, NULL, 0);
10040 arglist |= CAM_ARG_VERBOSE;
10047 #ifndef MINIMALISTIC
10049 * For most commands we'll want to open the passthrough device
10050 * associated with the specified device. In the case of the rescan
10051 * commands, we don't use a passthrough device at all, just the
10052 * transport layer device.
10054 if (devopen == 1) {
10055 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10056 && (((arglist & CAM_ARG_DEVICE) == 0)
10057 || ((arglist & CAM_ARG_UNIT) == 0))) {
10058 errx(1, "subcommand \"%s\" requires a valid device "
10059 "identifier", argv[1]);
10062 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10063 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10064 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10066 errx(1,"%s", cam_errbuf);
10068 #endif /* MINIMALISTIC */
10071 * Reset optind to 2, and reset getopt, so these routines can parse
10072 * the arguments again.
10078 #ifndef MINIMALISTIC
10079 case CAM_CMD_DEVLIST:
10080 error = getdevlist(cam_dev);
10083 error = atahpa(cam_dev, retry_count, timeout,
10084 argc, argv, combinedopt);
10086 #endif /* MINIMALISTIC */
10087 case CAM_CMD_DEVTREE:
10088 error = getdevtree(argc, argv, combinedopt);
10090 #ifndef MINIMALISTIC
10092 error = testunitready(cam_dev, task_attr, retry_count,
10095 case CAM_CMD_INQUIRY:
10096 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10097 task_attr, retry_count, timeout);
10099 case CAM_CMD_IDENTIFY:
10100 error = identify(cam_dev, retry_count, timeout);
10102 case CAM_CMD_STARTSTOP:
10103 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10104 arglist & CAM_ARG_EJECT, task_attr,
10105 retry_count, timeout);
10107 #endif /* MINIMALISTIC */
10108 case CAM_CMD_RESCAN:
10109 error = dorescan_or_reset(argc, argv, 1);
10111 case CAM_CMD_RESET:
10112 error = dorescan_or_reset(argc, argv, 0);
10114 #ifndef MINIMALISTIC
10115 case CAM_CMD_READ_DEFECTS:
10116 error = readdefects(cam_dev, argc, argv, combinedopt,
10117 task_attr, retry_count, timeout);
10119 case CAM_CMD_MODE_PAGE:
10120 modepage(cam_dev, argc, argv, combinedopt,
10121 task_attr, retry_count, timeout);
10123 case CAM_CMD_SCSI_CMD:
10124 error = scsicmd(cam_dev, argc, argv, combinedopt,
10125 task_attr, retry_count, timeout);
10127 case CAM_CMD_MMCSD_CMD:
10128 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10129 retry_count, timeout);
10131 case CAM_CMD_SMP_CMD:
10132 error = smpcmd(cam_dev, argc, argv, combinedopt,
10133 retry_count, timeout);
10135 case CAM_CMD_SMP_RG:
10136 error = smpreportgeneral(cam_dev, argc, argv,
10137 combinedopt, retry_count,
10140 case CAM_CMD_SMP_PC:
10141 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10142 retry_count, timeout);
10144 case CAM_CMD_SMP_PHYLIST:
10145 error = smpphylist(cam_dev, argc, argv, combinedopt,
10146 retry_count, timeout);
10148 case CAM_CMD_SMP_MANINFO:
10149 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10150 retry_count, timeout);
10152 case CAM_CMD_DEBUG:
10153 error = camdebug(argc, argv, combinedopt);
10156 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10159 error = ratecontrol(cam_dev, task_attr, retry_count,
10160 timeout, argc, argv, combinedopt);
10162 case CAM_CMD_FORMAT:
10163 error = scsiformat(cam_dev, argc, argv,
10164 combinedopt, task_attr, retry_count,
10167 case CAM_CMD_REPORTLUNS:
10168 error = scsireportluns(cam_dev, argc, argv,
10169 combinedopt, task_attr,
10170 retry_count, timeout);
10172 case CAM_CMD_READCAP:
10173 error = scsireadcapacity(cam_dev, argc, argv,
10174 combinedopt, task_attr,
10175 retry_count, timeout);
10178 case CAM_CMD_STANDBY:
10179 case CAM_CMD_SLEEP:
10180 error = atapm(cam_dev, argc, argv,
10181 combinedopt, retry_count, timeout);
10185 error = ataaxm(cam_dev, argc, argv,
10186 combinedopt, retry_count, timeout);
10188 case CAM_CMD_SECURITY:
10189 error = atasecurity(cam_dev, retry_count, timeout,
10190 argc, argv, combinedopt);
10192 case CAM_CMD_DOWNLOAD_FW:
10193 error = fwdownload(cam_dev, argc, argv, combinedopt,
10194 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10197 case CAM_CMD_SANITIZE:
10198 error = scsisanitize(cam_dev, argc, argv,
10199 combinedopt, task_attr,
10200 retry_count, timeout);
10202 case CAM_CMD_PERSIST:
10203 error = scsipersist(cam_dev, argc, argv, combinedopt,
10204 task_attr, retry_count, timeout,
10205 arglist & CAM_ARG_VERBOSE,
10206 arglist & CAM_ARG_ERR_RECOVER);
10208 case CAM_CMD_ATTRIB:
10209 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10210 task_attr, retry_count, timeout,
10211 arglist & CAM_ARG_VERBOSE,
10212 arglist & CAM_ARG_ERR_RECOVER);
10214 case CAM_CMD_OPCODES:
10215 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10216 task_attr, retry_count, timeout,
10217 arglist & CAM_ARG_VERBOSE);
10219 case CAM_CMD_REPROBE:
10220 error = scsireprobe(cam_dev);
10223 error = zone(cam_dev, argc, argv, combinedopt,
10224 task_attr, retry_count, timeout,
10225 arglist & CAM_ARG_VERBOSE);
10228 error = epc(cam_dev, argc, argv, combinedopt,
10229 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10231 case CAM_CMD_TIMESTAMP:
10232 error = timestamp(cam_dev, argc, argv, combinedopt,
10233 task_attr, retry_count, timeout,
10234 arglist & CAM_ARG_VERBOSE);
10236 #endif /* MINIMALISTIC */
10237 case CAM_CMD_USAGE:
10246 if (cam_dev != NULL)
10247 cam_close_device(cam_dev);