2 * Copyright (c) 1997-2007 Kenneth D. Merry
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/ioctl.h>
33 #include <sys/stdint.h>
34 #include <sys/types.h>
36 #include <sys/endian.h>
55 #include <cam/cam_debug.h>
56 #include <cam/cam_ccb.h>
57 #include <cam/scsi/scsi_all.h>
58 #include <cam/scsi/scsi_da.h>
59 #include <cam/scsi/scsi_pass.h>
60 #include <cam/scsi/scsi_message.h>
61 #include <cam/scsi/smp_all.h>
62 #include <cam/ata/ata_all.h>
63 #include <cam/mmc/mmc_all.h>
65 #include "camcontrol.h"
67 #include "nvmecontrol_ext.h"
71 CAM_CMD_NONE = 0x00000000,
72 CAM_CMD_DEVLIST = 0x00000001,
73 CAM_CMD_TUR = 0x00000002,
74 CAM_CMD_INQUIRY = 0x00000003,
75 CAM_CMD_STARTSTOP = 0x00000004,
76 CAM_CMD_RESCAN = 0x00000005,
77 CAM_CMD_READ_DEFECTS = 0x00000006,
78 CAM_CMD_MODE_PAGE = 0x00000007,
79 CAM_CMD_SCSI_CMD = 0x00000008,
80 CAM_CMD_DEVTREE = 0x00000009,
81 CAM_CMD_USAGE = 0x0000000a,
82 CAM_CMD_DEBUG = 0x0000000b,
83 CAM_CMD_RESET = 0x0000000c,
84 CAM_CMD_FORMAT = 0x0000000d,
85 CAM_CMD_TAG = 0x0000000e,
86 CAM_CMD_RATE = 0x0000000f,
87 CAM_CMD_DETACH = 0x00000010,
88 CAM_CMD_REPORTLUNS = 0x00000011,
89 CAM_CMD_READCAP = 0x00000012,
90 CAM_CMD_IDENTIFY = 0x00000013,
91 CAM_CMD_IDLE = 0x00000014,
92 CAM_CMD_STANDBY = 0x00000015,
93 CAM_CMD_SLEEP = 0x00000016,
94 CAM_CMD_SMP_CMD = 0x00000017,
95 CAM_CMD_SMP_RG = 0x00000018,
96 CAM_CMD_SMP_PC = 0x00000019,
97 CAM_CMD_SMP_PHYLIST = 0x0000001a,
98 CAM_CMD_SMP_MANINFO = 0x0000001b,
99 CAM_CMD_DOWNLOAD_FW = 0x0000001c,
100 CAM_CMD_SECURITY = 0x0000001d,
101 CAM_CMD_HPA = 0x0000001e,
102 CAM_CMD_SANITIZE = 0x0000001f,
103 CAM_CMD_PERSIST = 0x00000020,
104 CAM_CMD_APM = 0x00000021,
105 CAM_CMD_AAM = 0x00000022,
106 CAM_CMD_ATTRIB = 0x00000023,
107 CAM_CMD_OPCODES = 0x00000024,
108 CAM_CMD_REPROBE = 0x00000025,
109 CAM_CMD_ZONE = 0x00000026,
110 CAM_CMD_EPC = 0x00000027,
111 CAM_CMD_TIMESTAMP = 0x00000028,
112 CAM_CMD_MMCSD_CMD = 0x00000029
116 CAM_ARG_NONE = 0x00000000,
117 CAM_ARG_VERBOSE = 0x00000001,
118 CAM_ARG_DEVICE = 0x00000002,
119 CAM_ARG_BUS = 0x00000004,
120 CAM_ARG_TARGET = 0x00000008,
121 CAM_ARG_LUN = 0x00000010,
122 CAM_ARG_EJECT = 0x00000020,
123 CAM_ARG_UNIT = 0x00000040,
124 CAM_ARG_FORMAT_BLOCK = 0x00000080,
125 CAM_ARG_FORMAT_BFI = 0x00000100,
126 CAM_ARG_FORMAT_PHYS = 0x00000200,
127 CAM_ARG_PLIST = 0x00000400,
128 CAM_ARG_GLIST = 0x00000800,
129 CAM_ARG_GET_SERIAL = 0x00001000,
130 CAM_ARG_GET_STDINQ = 0x00002000,
131 CAM_ARG_GET_XFERRATE = 0x00004000,
132 CAM_ARG_INQ_MASK = 0x00007000,
133 CAM_ARG_TIMEOUT = 0x00020000,
134 CAM_ARG_CMD_IN = 0x00040000,
135 CAM_ARG_CMD_OUT = 0x00080000,
136 CAM_ARG_ERR_RECOVER = 0x00200000,
137 CAM_ARG_RETRIES = 0x00400000,
138 CAM_ARG_START_UNIT = 0x00800000,
139 CAM_ARG_DEBUG_INFO = 0x01000000,
140 CAM_ARG_DEBUG_TRACE = 0x02000000,
141 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
142 CAM_ARG_DEBUG_CDB = 0x08000000,
143 CAM_ARG_DEBUG_XPT = 0x10000000,
144 CAM_ARG_DEBUG_PERIPH = 0x20000000,
145 CAM_ARG_DEBUG_PROBE = 0x40000000,
148 struct camcontrol_opts {
156 struct ata_res_pass16 {
157 u_int16_t reserved[5];
160 u_int8_t sector_count_exp;
161 u_int8_t sector_count;
162 u_int8_t lba_low_exp;
164 u_int8_t lba_mid_exp;
166 u_int8_t lba_high_exp;
172 struct ata_set_max_pwd
175 u_int8_t password[32];
176 u_int16_t reserved2[239];
179 static struct scsi_nv task_attrs[] = {
180 { "simple", MSG_SIMPLE_Q_TAG },
181 { "head", MSG_HEAD_OF_Q_TAG },
182 { "ordered", MSG_ORDERED_Q_TAG },
183 { "iwr", MSG_IGN_WIDE_RESIDUE },
184 { "aca", MSG_ACA_TASK }
187 static const char scsicmd_opts[] = "a:c:dfi:o:r";
188 static const char readdefect_opts[] = "f:GPqsS:X";
189 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
190 static const char smprg_opts[] = "l";
191 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
192 static const char smpphylist_opts[] = "lq";
196 static struct camcontrol_opts option_table[] = {
198 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
199 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
200 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
201 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
202 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
203 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
204 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
205 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
206 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
207 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
208 #endif /* MINIMALISTIC */
209 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
210 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
212 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
213 {"mmcsdcmd", CAM_CMD_MMCSD_CMD, CAM_ARG_NONE, "c:a:f:Wb:l:41S:I"},
214 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
215 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
216 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
217 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
218 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
219 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
220 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
221 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
222 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
223 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
224 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
225 #endif /* MINIMALISTIC */
226 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
228 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
229 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
230 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
231 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
232 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
233 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
234 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
235 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
236 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
237 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
238 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
239 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
240 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
241 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
242 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
243 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
244 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
245 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
246 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
247 {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
248 {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
249 {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
250 #endif /* MINIMALISTIC */
251 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
252 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
253 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
258 struct device_match_result dev_match;
260 struct periph_match_result *periph_matches;
261 struct scsi_vpd_device_id *device_id;
263 STAILQ_ENTRY(cam_devitem) links;
267 STAILQ_HEAD(, cam_devitem) dev_queue;
271 static cam_cmdmask cmdlist;
272 static cam_argmask arglist;
274 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
275 uint32_t *cmdnum, cam_argmask *argnum,
276 const char **subopt);
278 static int getdevlist(struct cam_device *device);
279 #endif /* MINIMALISTIC */
280 static int getdevtree(int argc, char **argv, char *combinedopt);
281 static int print_dev_scsi(struct device_match_result *dev_result, char *tmpstr);
282 static int print_dev_ata(struct device_match_result *dev_result, char *tmpstr);
283 static int print_dev_semb(struct device_match_result *dev_result, char *tmpstr);
284 static int print_dev_mmcsd(struct device_match_result *dev_result,
287 static int print_dev_nvme(struct device_match_result *dev_result, char *tmpstr);
290 static int testunitready(struct cam_device *device, int task_attr,
291 int retry_count, int timeout, int quiet);
292 static int scsistart(struct cam_device *device, int startstop, int loadeject,
293 int task_attr, int retry_count, int timeout);
294 static int scsiinquiry(struct cam_device *device, int task_attr,
295 int retry_count, int timeout);
296 static int scsiserial(struct cam_device *device, int task_attr,
297 int retry_count, int timeout);
298 #endif /* MINIMALISTIC */
299 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
300 lun_id_t *lun, cam_argmask *arglst);
301 static int dorescan_or_reset(int argc, char **argv, int rescan);
302 static int rescan_or_reset_bus(path_id_t bus, int rescan);
303 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
304 lun_id_t lun, int scan);
306 static int readdefects(struct cam_device *device, int argc, char **argv,
307 char *combinedopt, int task_attr, int retry_count,
309 static void modepage(struct cam_device *device, int argc, char **argv,
310 char *combinedopt, int task_attr, int retry_count,
312 static int scsicmd(struct cam_device *device, int argc, char **argv,
313 char *combinedopt, int task_attr, int retry_count,
315 static int smpcmd(struct cam_device *device, int argc, char **argv,
316 char *combinedopt, int retry_count, int timeout);
317 static int mmcsdcmd(struct cam_device *device, int argc, char **argv,
318 char *combinedopt, int retry_count, int timeout);
319 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
320 char *combinedopt, int retry_count, int timeout);
321 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
322 char *combinedopt, int retry_count, int timeout);
323 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
324 char *combinedopt, int retry_count, int timeout);
325 static int getdevid(struct cam_devitem *item);
326 static int buildbusdevlist(struct cam_devlist *devlist);
327 static void freebusdevlist(struct cam_devlist *devlist);
328 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
330 static int smpphylist(struct cam_device *device, int argc, char **argv,
331 char *combinedopt, int retry_count, int timeout);
332 static int tagcontrol(struct cam_device *device, int argc, char **argv,
334 static void cts_print(struct cam_device *device,
335 struct ccb_trans_settings *cts);
336 static void cpi_print(struct ccb_pathinq *cpi);
337 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
338 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
339 static int get_print_cts(struct cam_device *device, int user_settings,
340 int quiet, struct ccb_trans_settings *cts);
341 static int ratecontrol(struct cam_device *device, int task_attr,
342 int retry_count, int timeout, int argc, char **argv,
344 static int scsiformat(struct cam_device *device, int argc, char **argv,
345 char *combinedopt, int task_attr, int retry_count,
347 static int scsisanitize(struct cam_device *device, int argc, char **argv,
348 char *combinedopt, int task_attr, int retry_count,
350 static int scsireportluns(struct cam_device *device, int argc, char **argv,
351 char *combinedopt, int task_attr, int retry_count,
353 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
354 char *combinedopt, int task_attr, int retry_count,
356 static int atapm(struct cam_device *device, int argc, char **argv,
357 char *combinedopt, int retry_count, int timeout);
358 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
359 int argc, char **argv, char *combinedopt);
360 static int atahpa(struct cam_device *device, int retry_count, int timeout,
361 int argc, char **argv, char *combinedopt);
362 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
363 int sa_set, int req_sa, uint8_t *buf,
365 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
367 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
368 char *combinedopt, int task_attr, int retry_count,
369 int timeout, int verbose);
370 static int scsireprobe(struct cam_device *device);
372 #endif /* MINIMALISTIC */
374 #define min(a,b) (((a)<(b))?(a):(b))
377 #define max(a,b) (((a)>(b))?(a):(b))
381 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
382 cam_argmask *argnum, const char **subopt)
384 struct camcontrol_opts *opts;
387 for (opts = table; (opts != NULL) && (opts->optname != NULL);
389 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
390 *cmdnum = opts->cmdnum;
391 *argnum = opts->argnum;
392 *subopt = opts->subopt;
393 if (++num_matches > 1)
394 return (CC_OR_AMBIGUOUS);
399 return (CC_OR_FOUND);
401 return (CC_OR_NOT_FOUND);
406 getdevlist(struct cam_device *device)
412 ccb = cam_getccb(device);
414 ccb->ccb_h.func_code = XPT_GDEVLIST;
415 ccb->ccb_h.flags = CAM_DIR_NONE;
416 ccb->ccb_h.retry_count = 1;
418 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
419 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
420 if (cam_send_ccb(device, ccb) < 0) {
421 perror("error getting device list");
428 switch (ccb->cgdl.status) {
429 case CAM_GDEVLIST_MORE_DEVS:
430 strcpy(status, "MORE");
432 case CAM_GDEVLIST_LAST_DEVICE:
433 strcpy(status, "LAST");
435 case CAM_GDEVLIST_LIST_CHANGED:
436 strcpy(status, "CHANGED");
438 case CAM_GDEVLIST_ERROR:
439 strcpy(status, "ERROR");
444 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
445 ccb->cgdl.periph_name,
446 ccb->cgdl.unit_number,
447 ccb->cgdl.generation,
452 * If the list has changed, we need to start over from the
455 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
463 #endif /* MINIMALISTIC */
466 getdevtree(int argc, char **argv, char *combinedopt)
477 while ((c = getopt(argc, argv, combinedopt)) != -1) {
480 if ((arglist & CAM_ARG_VERBOSE) == 0)
488 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
489 warn("couldn't open %s", XPT_DEVICE);
493 bzero(&ccb, sizeof(union ccb));
495 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
496 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
497 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
499 ccb.ccb_h.func_code = XPT_DEV_MATCH;
500 bufsize = sizeof(struct dev_match_result) * 100;
501 ccb.cdm.match_buf_len = bufsize;
502 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
503 if (ccb.cdm.matches == NULL) {
504 warnx("can't malloc memory for matches");
508 ccb.cdm.num_matches = 0;
511 * We fetch all nodes, since we display most of them in the default
512 * case, and all in the verbose case.
514 ccb.cdm.num_patterns = 0;
515 ccb.cdm.pattern_buf_len = 0;
518 * We do the ioctl multiple times if necessary, in case there are
519 * more than 100 nodes in the EDT.
522 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
523 warn("error sending CAMIOCOMMAND ioctl");
528 if ((ccb.ccb_h.status != CAM_REQ_CMP)
529 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
530 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
531 warnx("got CAM error %#x, CDM error %d\n",
532 ccb.ccb_h.status, ccb.cdm.status);
537 for (i = 0; i < ccb.cdm.num_matches; i++) {
538 switch (ccb.cdm.matches[i].type) {
539 case DEV_MATCH_BUS: {
540 struct bus_match_result *bus_result;
543 * Only print the bus information if the
544 * user turns on the verbose flag.
546 if ((busonly == 0) &&
547 (arglist & CAM_ARG_VERBOSE) == 0)
551 &ccb.cdm.matches[i].result.bus_result;
554 fprintf(stdout, ")\n");
558 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
560 bus_result->dev_name,
561 bus_result->unit_number,
563 (busonly ? "" : ":"));
566 case DEV_MATCH_DEVICE: {
567 struct device_match_result *dev_result;
574 &ccb.cdm.matches[i].result.device_result;
576 if ((dev_result->flags
577 & DEV_RESULT_UNCONFIGURED)
578 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
584 if (dev_result->protocol == PROTO_SCSI) {
585 if (print_dev_scsi(dev_result,
590 } else if (dev_result->protocol == PROTO_ATA ||
591 dev_result->protocol == PROTO_SATAPM) {
592 if (print_dev_ata(dev_result,
597 } else if (dev_result->protocol == PROTO_MMCSD){
598 if (print_dev_mmcsd(dev_result,
603 } else if (dev_result->protocol == PROTO_SEMB) {
604 if (print_dev_semb(dev_result,
610 } else if (dev_result->protocol == PROTO_NVME) {
611 if (print_dev_nvme(dev_result,
618 sprintf(tmpstr, "<>");
621 fprintf(stdout, ")\n");
625 fprintf(stdout, "%-33s at scbus%d "
626 "target %d lun %jx (",
629 dev_result->target_id,
630 (uintmax_t)dev_result->target_lun);
636 case DEV_MATCH_PERIPH: {
637 struct periph_match_result *periph_result;
640 &ccb.cdm.matches[i].result.periph_result;
642 if (busonly || skip_device != 0)
646 fprintf(stdout, ",");
648 fprintf(stdout, "%s%d",
649 periph_result->periph_name,
650 periph_result->unit_number);
656 fprintf(stdout, "unknown match type\n");
661 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
662 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
665 fprintf(stdout, ")\n");
673 print_dev_scsi(struct device_match_result *dev_result, char *tmpstr)
675 char vendor[16], product[48], revision[16];
677 cam_strvis(vendor, dev_result->inq_data.vendor,
678 sizeof(dev_result->inq_data.vendor), sizeof(vendor));
679 cam_strvis(product, dev_result->inq_data.product,
680 sizeof(dev_result->inq_data.product), sizeof(product));
681 cam_strvis(revision, dev_result->inq_data.revision,
682 sizeof(dev_result->inq_data.revision), sizeof(revision));
683 sprintf(tmpstr, "<%s %s %s>", vendor, product, revision);
689 print_dev_ata(struct device_match_result *dev_result, char *tmpstr)
691 char product[48], revision[16];
693 cam_strvis(product, dev_result->ident_data.model,
694 sizeof(dev_result->ident_data.model), sizeof(product));
695 cam_strvis(revision, dev_result->ident_data.revision,
696 sizeof(dev_result->ident_data.revision), sizeof(revision));
697 sprintf(tmpstr, "<%s %s>", product, revision);
703 print_dev_semb(struct device_match_result *dev_result, char *tmpstr)
705 struct sep_identify_data *sid;
706 char vendor[16], product[48], revision[16], fw[5];
708 sid = (struct sep_identify_data *)&dev_result->ident_data;
709 cam_strvis(vendor, sid->vendor_id,
710 sizeof(sid->vendor_id), sizeof(vendor));
711 cam_strvis(product, sid->product_id,
712 sizeof(sid->product_id), sizeof(product));
713 cam_strvis(revision, sid->product_rev,
714 sizeof(sid->product_rev), sizeof(revision));
715 cam_strvis(fw, sid->firmware_rev,
716 sizeof(sid->firmware_rev), sizeof(fw));
717 sprintf(tmpstr, "<%s %s %s %s>", vendor, product, revision, fw);
723 print_dev_mmcsd(struct device_match_result *dev_result, char *tmpstr)
726 struct ccb_dev_advinfo *advi;
727 struct cam_device *dev;
728 struct mmc_params mmc_ident_data;
730 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
731 dev_result->target_lun, O_RDWR, NULL);
733 warnx("%s", cam_errbuf);
737 ccb = cam_getccb(dev);
739 warnx("couldn't allocate CCB");
740 cam_close_device(dev);
745 advi->ccb_h.flags = CAM_DIR_IN;
746 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
747 advi->flags = CDAI_FLAG_NONE;
748 advi->buftype = CDAI_TYPE_MMC_PARAMS;
749 advi->bufsiz = sizeof(struct mmc_params);
750 advi->buf = (uint8_t *)&mmc_ident_data;
752 if (cam_send_ccb(dev, ccb) < 0) {
753 warn("error sending CAMIOCOMMAND ioctl");
755 cam_close_device(dev);
759 if (strlen(mmc_ident_data.model) > 0) {
760 sprintf(tmpstr, "<%s>", mmc_ident_data.model);
762 sprintf(tmpstr, "<%s card>",
763 mmc_ident_data.card_features &
764 CARD_FEATURE_SDIO ? "SDIO" : "unknown");
768 cam_close_device(dev);
774 nvme_get_cdata(struct cam_device *dev, struct nvme_controller_data *cdata)
777 struct ccb_dev_advinfo *advi;
779 ccb = cam_getccb(dev);
781 warnx("couldn't allocate CCB");
782 cam_close_device(dev);
787 advi->ccb_h.flags = CAM_DIR_IN;
788 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
789 advi->flags = CDAI_FLAG_NONE;
790 advi->buftype = CDAI_TYPE_NVME_CNTRL;
791 advi->bufsiz = sizeof(struct nvme_controller_data);
792 advi->buf = (uint8_t *)cdata;
794 if (cam_send_ccb(dev, ccb) < 0) {
795 warn("error sending CAMIOCOMMAND ioctl");
797 cam_close_device(dev);
800 if (advi->ccb_h.status != CAM_REQ_CMP) {
801 warnx("got CAM error %#x", advi->ccb_h.status);
803 cam_close_device(dev);
811 print_dev_nvme(struct device_match_result *dev_result, char *tmpstr)
813 struct cam_device *dev;
814 struct nvme_controller_data cdata;
815 char vendor[64], product[64];
817 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
818 dev_result->target_lun, O_RDWR, NULL);
820 warnx("%s", cam_errbuf);
824 if (nvme_get_cdata(dev, &cdata))
827 cam_strvis(vendor, cdata.mn, sizeof(cdata.mn), sizeof(vendor));
828 cam_strvis(product, cdata.fr, sizeof(cdata.fr), sizeof(product));
829 sprintf(tmpstr, "<%s %s>", vendor, product);
831 cam_close_device(dev);
838 testunitready(struct cam_device *device, int task_attr, int retry_count,
839 int timeout, int quiet)
844 ccb = cam_getccb(device);
846 scsi_test_unit_ready(&ccb->csio,
847 /* retries */ retry_count,
849 /* tag_action */ task_attr,
850 /* sense_len */ SSD_FULL_SIZE,
851 /* timeout */ timeout ? timeout : 5000);
853 /* Disable freezing the device queue */
854 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
856 if (arglist & CAM_ARG_ERR_RECOVER)
857 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
859 if (cam_send_ccb(device, ccb) < 0) {
861 perror("error sending test unit ready");
863 if (arglist & CAM_ARG_VERBOSE) {
864 cam_error_print(device, ccb, CAM_ESF_ALL,
865 CAM_EPF_ALL, stderr);
872 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
874 fprintf(stdout, "Unit is ready\n");
877 fprintf(stdout, "Unit is not ready\n");
880 if (arglist & CAM_ARG_VERBOSE) {
881 cam_error_print(device, ccb, CAM_ESF_ALL,
882 CAM_EPF_ALL, stderr);
892 scsistart(struct cam_device *device, int startstop, int loadeject,
893 int task_attr, int retry_count, int timeout)
898 ccb = cam_getccb(device);
901 * If we're stopping, send an ordered tag so the drive in question
902 * will finish any previously queued writes before stopping. If
903 * the device isn't capable of tagged queueing, or if tagged
904 * queueing is turned off, the tag action is a no-op. We override
905 * the default simple tag, although this also has the effect of
906 * overriding the user's wishes if he wanted to specify a simple
910 && (task_attr == MSG_SIMPLE_Q_TAG))
911 task_attr = MSG_ORDERED_Q_TAG;
913 scsi_start_stop(&ccb->csio,
914 /* retries */ retry_count,
916 /* tag_action */ task_attr,
917 /* start/stop */ startstop,
918 /* load_eject */ loadeject,
920 /* sense_len */ SSD_FULL_SIZE,
921 /* timeout */ timeout ? timeout : 120000);
923 /* Disable freezing the device queue */
924 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
926 if (arglist & CAM_ARG_ERR_RECOVER)
927 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
929 if (cam_send_ccb(device, ccb) < 0) {
930 perror("error sending start unit");
932 if (arglist & CAM_ARG_VERBOSE) {
933 cam_error_print(device, ccb, CAM_ESF_ALL,
934 CAM_EPF_ALL, stderr);
941 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
943 fprintf(stdout, "Unit started successfully");
945 fprintf(stdout,", Media loaded\n");
947 fprintf(stdout,"\n");
949 fprintf(stdout, "Unit stopped successfully");
951 fprintf(stdout, ", Media ejected\n");
953 fprintf(stdout, "\n");
959 "Error received from start unit command\n");
962 "Error received from stop unit command\n");
964 if (arglist & CAM_ARG_VERBOSE) {
965 cam_error_print(device, ccb, CAM_ESF_ALL,
966 CAM_EPF_ALL, stderr);
976 scsidoinquiry(struct cam_device *device, int argc, char **argv,
977 char *combinedopt, int task_attr, int retry_count, int timeout)
982 while ((c = getopt(argc, argv, combinedopt)) != -1) {
985 arglist |= CAM_ARG_GET_STDINQ;
988 arglist |= CAM_ARG_GET_XFERRATE;
991 arglist |= CAM_ARG_GET_SERIAL;
999 * If the user didn't specify any inquiry options, he wants all of
1002 if ((arglist & CAM_ARG_INQ_MASK) == 0)
1003 arglist |= CAM_ARG_INQ_MASK;
1005 if (arglist & CAM_ARG_GET_STDINQ)
1006 error = scsiinquiry(device, task_attr, retry_count, timeout);
1011 if (arglist & CAM_ARG_GET_SERIAL)
1012 scsiserial(device, task_attr, retry_count, timeout);
1014 if (arglist & CAM_ARG_GET_XFERRATE)
1015 error = camxferrate(device);
1021 scsiinquiry(struct cam_device *device, int task_attr, int retry_count,
1025 struct scsi_inquiry_data *inq_buf;
1028 ccb = cam_getccb(device);
1031 warnx("couldn't allocate CCB");
1035 /* cam_getccb cleans up the header, caller has to zero the payload */
1036 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1038 inq_buf = (struct scsi_inquiry_data *)malloc(
1039 sizeof(struct scsi_inquiry_data));
1041 if (inq_buf == NULL) {
1043 warnx("can't malloc memory for inquiry\n");
1046 bzero(inq_buf, sizeof(*inq_buf));
1049 * Note that although the size of the inquiry buffer is the full
1050 * 256 bytes specified in the SCSI spec, we only tell the device
1051 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
1052 * two reasons for this:
1054 * - The SCSI spec says that when a length field is only 1 byte,
1055 * a value of 0 will be interpreted as 256. Therefore
1056 * scsi_inquiry() will convert an inq_len (which is passed in as
1057 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
1058 * to 0. Evidently, very few devices meet the spec in that
1059 * regard. Some devices, like many Seagate disks, take the 0 as
1060 * 0, and don't return any data. One Pioneer DVD-R drive
1061 * returns more data than the command asked for.
1063 * So, since there are numerous devices that just don't work
1064 * right with the full inquiry size, we don't send the full size.
1066 * - The second reason not to use the full inquiry data length is
1067 * that we don't need it here. The only reason we issue a
1068 * standard inquiry is to get the vendor name, device name,
1069 * and revision so scsi_print_inquiry() can print them.
1071 * If, at some point in the future, more inquiry data is needed for
1072 * some reason, this code should use a procedure similar to the
1073 * probe code. i.e., issue a short inquiry, and determine from
1074 * the additional length passed back from the device how much
1075 * inquiry data the device supports. Once the amount the device
1076 * supports is determined, issue an inquiry for that amount and no
1081 scsi_inquiry(&ccb->csio,
1082 /* retries */ retry_count,
1084 /* tag_action */ task_attr,
1085 /* inq_buf */ (u_int8_t *)inq_buf,
1086 /* inq_len */ SHORT_INQUIRY_LENGTH,
1089 /* sense_len */ SSD_FULL_SIZE,
1090 /* timeout */ timeout ? timeout : 5000);
1092 /* Disable freezing the device queue */
1093 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1095 if (arglist & CAM_ARG_ERR_RECOVER)
1096 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1098 if (cam_send_ccb(device, ccb) < 0) {
1099 perror("error sending SCSI inquiry");
1101 if (arglist & CAM_ARG_VERBOSE) {
1102 cam_error_print(device, ccb, CAM_ESF_ALL,
1103 CAM_EPF_ALL, stderr);
1110 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1113 if (arglist & CAM_ARG_VERBOSE) {
1114 cam_error_print(device, ccb, CAM_ESF_ALL,
1115 CAM_EPF_ALL, stderr);
1126 fprintf(stdout, "%s%d: ", device->device_name,
1127 device->dev_unit_num);
1128 scsi_print_inquiry(inq_buf);
1136 scsiserial(struct cam_device *device, int task_attr, int retry_count,
1140 struct scsi_vpd_unit_serial_number *serial_buf;
1141 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
1144 ccb = cam_getccb(device);
1147 warnx("couldn't allocate CCB");
1151 /* cam_getccb cleans up the header, caller has to zero the payload */
1152 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1154 serial_buf = (struct scsi_vpd_unit_serial_number *)
1155 malloc(sizeof(*serial_buf));
1157 if (serial_buf == NULL) {
1159 warnx("can't malloc memory for serial number");
1163 scsi_inquiry(&ccb->csio,
1164 /*retries*/ retry_count,
1166 /* tag_action */ task_attr,
1167 /* inq_buf */ (u_int8_t *)serial_buf,
1168 /* inq_len */ sizeof(*serial_buf),
1170 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
1171 /* sense_len */ SSD_FULL_SIZE,
1172 /* timeout */ timeout ? timeout : 5000);
1174 /* Disable freezing the device queue */
1175 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1177 if (arglist & CAM_ARG_ERR_RECOVER)
1178 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1180 if (cam_send_ccb(device, ccb) < 0) {
1181 warn("error getting serial number");
1183 if (arglist & CAM_ARG_VERBOSE) {
1184 cam_error_print(device, ccb, CAM_ESF_ALL,
1185 CAM_EPF_ALL, stderr);
1193 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1196 if (arglist & CAM_ARG_VERBOSE) {
1197 cam_error_print(device, ccb, CAM_ESF_ALL,
1198 CAM_EPF_ALL, stderr);
1209 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1210 serial_num[serial_buf->length] = '\0';
1212 if ((arglist & CAM_ARG_GET_STDINQ)
1213 || (arglist & CAM_ARG_GET_XFERRATE))
1214 fprintf(stdout, "%s%d: Serial Number ",
1215 device->device_name, device->dev_unit_num);
1217 fprintf(stdout, "%.60s\n", serial_num);
1225 camxferrate(struct cam_device *device)
1227 struct ccb_pathinq cpi;
1229 u_int32_t speed = 0;
1234 if ((retval = get_cpi(device, &cpi)) != 0)
1237 ccb = cam_getccb(device);
1240 warnx("couldn't allocate CCB");
1244 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
1246 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1247 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1249 if (((retval = cam_send_ccb(device, ccb)) < 0)
1250 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1251 const char error_string[] = "error getting transfer settings";
1256 warnx(error_string);
1258 if (arglist & CAM_ARG_VERBOSE)
1259 cam_error_print(device, ccb, CAM_ESF_ALL,
1260 CAM_EPF_ALL, stderr);
1264 goto xferrate_bailout;
1268 speed = cpi.base_transfer_speed;
1270 if (ccb->cts.transport == XPORT_SPI) {
1271 struct ccb_trans_settings_spi *spi =
1272 &ccb->cts.xport_specific.spi;
1274 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1275 freq = scsi_calc_syncsrate(spi->sync_period);
1278 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1279 speed *= (0x01 << spi->bus_width);
1281 } else if (ccb->cts.transport == XPORT_FC) {
1282 struct ccb_trans_settings_fc *fc =
1283 &ccb->cts.xport_specific.fc;
1285 if (fc->valid & CTS_FC_VALID_SPEED)
1286 speed = fc->bitrate;
1287 } else if (ccb->cts.transport == XPORT_SAS) {
1288 struct ccb_trans_settings_sas *sas =
1289 &ccb->cts.xport_specific.sas;
1291 if (sas->valid & CTS_SAS_VALID_SPEED)
1292 speed = sas->bitrate;
1293 } else if (ccb->cts.transport == XPORT_ATA) {
1294 struct ccb_trans_settings_pata *pata =
1295 &ccb->cts.xport_specific.ata;
1297 if (pata->valid & CTS_ATA_VALID_MODE)
1298 speed = ata_mode2speed(pata->mode);
1299 } else if (ccb->cts.transport == XPORT_SATA) {
1300 struct ccb_trans_settings_sata *sata =
1301 &ccb->cts.xport_specific.sata;
1303 if (sata->valid & CTS_SATA_VALID_REVISION)
1304 speed = ata_revision2speed(sata->revision);
1309 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1310 device->device_name, device->dev_unit_num,
1313 fprintf(stdout, "%s%d: %dKB/s transfers",
1314 device->device_name, device->dev_unit_num,
1318 if (ccb->cts.transport == XPORT_SPI) {
1319 struct ccb_trans_settings_spi *spi =
1320 &ccb->cts.xport_specific.spi;
1322 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1323 && (spi->sync_offset != 0))
1324 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1325 freq % 1000, spi->sync_offset);
1327 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1328 && (spi->bus_width > 0)) {
1329 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1330 && (spi->sync_offset != 0)) {
1331 fprintf(stdout, ", ");
1333 fprintf(stdout, " (");
1335 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1336 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1337 && (spi->sync_offset != 0)) {
1338 fprintf(stdout, ")");
1340 } else if (ccb->cts.transport == XPORT_ATA) {
1341 struct ccb_trans_settings_pata *pata =
1342 &ccb->cts.xport_specific.ata;
1345 if (pata->valid & CTS_ATA_VALID_MODE)
1346 printf("%s, ", ata_mode2string(pata->mode));
1347 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1348 printf("ATAPI %dbytes, ", pata->atapi);
1349 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1350 printf("PIO %dbytes", pata->bytecount);
1352 } else if (ccb->cts.transport == XPORT_SATA) {
1353 struct ccb_trans_settings_sata *sata =
1354 &ccb->cts.xport_specific.sata;
1357 if (sata->valid & CTS_SATA_VALID_REVISION)
1358 printf("SATA %d.x, ", sata->revision);
1361 if (sata->valid & CTS_SATA_VALID_MODE)
1362 printf("%s, ", ata_mode2string(sata->mode));
1363 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1364 printf("ATAPI %dbytes, ", sata->atapi);
1365 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1366 printf("PIO %dbytes", sata->bytecount);
1370 if (ccb->cts.protocol == PROTO_SCSI) {
1371 struct ccb_trans_settings_scsi *scsi =
1372 &ccb->cts.proto_specific.scsi;
1373 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1374 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1375 fprintf(stdout, ", Command Queueing Enabled");
1380 fprintf(stdout, "\n");
1390 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1392 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1393 ((u_int32_t)parm->lba_size_2 << 16);
1395 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1396 ((u_int64_t)parm->lba_size48_2 << 16) |
1397 ((u_int64_t)parm->lba_size48_3 << 32) |
1398 ((u_int64_t)parm->lba_size48_4 << 48);
1402 "Support Enabled Value\n");
1405 printf("Host Protected Area (HPA) ");
1406 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1407 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1408 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1411 printf("HPA - Security ");
1412 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1422 atasata(struct ata_params *parm)
1426 if (parm->satacapabilities != 0xffff &&
1427 parm->satacapabilities != 0x0000)
1434 atacapprint(struct ata_params *parm)
1436 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1437 ((u_int32_t)parm->lba_size_2 << 16);
1439 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1440 ((u_int64_t)parm->lba_size48_2 << 16) |
1441 ((u_int64_t)parm->lba_size48_3 << 32) |
1442 ((u_int64_t)parm->lba_size48_4 << 48);
1445 printf("protocol ");
1446 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1447 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1448 if (parm->satacapabilities & ATA_SATA_GEN3)
1449 printf(" SATA 3.x\n");
1450 else if (parm->satacapabilities & ATA_SATA_GEN2)
1451 printf(" SATA 2.x\n");
1452 else if (parm->satacapabilities & ATA_SATA_GEN1)
1453 printf(" SATA 1.x\n");
1459 printf("device model %.40s\n", parm->model);
1460 printf("firmware revision %.8s\n", parm->revision);
1461 printf("serial number %.20s\n", parm->serial);
1462 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1463 printf("WWN %04x%04x%04x%04x\n",
1464 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1466 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1467 printf("media serial number %.30s\n",
1468 parm->media_serial);
1471 printf("cylinders %d\n", parm->cylinders);
1472 printf("heads %d\n", parm->heads);
1473 printf("sectors/track %d\n", parm->sectors);
1474 printf("sector size logical %u, physical %lu, offset %lu\n",
1475 ata_logical_sector_size(parm),
1476 (unsigned long)ata_physical_sector_size(parm),
1477 (unsigned long)ata_logical_sector_offset(parm));
1479 if (parm->config == ATA_PROTO_CFA ||
1480 (parm->support.command2 & ATA_SUPPORT_CFA))
1481 printf("CFA supported\n");
1483 printf("LBA%ssupported ",
1484 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1486 printf("%d sectors\n", lbasize);
1490 printf("LBA48%ssupported ",
1491 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1493 printf("%ju sectors\n", (uintmax_t)lbasize48);
1497 printf("PIO supported PIO");
1498 switch (ata_max_pmode(parm)) {
1514 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1515 printf(" w/o IORDY");
1518 printf("DMA%ssupported ",
1519 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1520 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1521 if (parm->mwdmamodes & 0xff) {
1523 if (parm->mwdmamodes & 0x04)
1525 else if (parm->mwdmamodes & 0x02)
1527 else if (parm->mwdmamodes & 0x01)
1531 if ((parm->atavalid & ATA_FLAG_88) &&
1532 (parm->udmamodes & 0xff)) {
1534 if (parm->udmamodes & 0x40)
1536 else if (parm->udmamodes & 0x20)
1538 else if (parm->udmamodes & 0x10)
1540 else if (parm->udmamodes & 0x08)
1542 else if (parm->udmamodes & 0x04)
1544 else if (parm->udmamodes & 0x02)
1546 else if (parm->udmamodes & 0x01)
1553 if (parm->media_rotation_rate == 1) {
1554 printf("media RPM non-rotating\n");
1555 } else if (parm->media_rotation_rate >= 0x0401 &&
1556 parm->media_rotation_rate <= 0xFFFE) {
1557 printf("media RPM %d\n",
1558 parm->media_rotation_rate);
1561 printf("Zoned-Device Commands ");
1562 switch (parm->support3 & ATA_SUPPORT_ZONE_MASK) {
1563 case ATA_SUPPORT_ZONE_DEV_MANAGED:
1564 printf("device managed\n");
1566 case ATA_SUPPORT_ZONE_HOST_AWARE:
1567 printf("host aware\n");
1574 "Support Enabled Value Vendor\n");
1575 printf("read ahead %s %s\n",
1576 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1577 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1578 printf("write cache %s %s\n",
1579 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1580 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1581 printf("flush cache %s %s\n",
1582 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1583 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1584 printf("overlap %s\n",
1585 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1586 printf("Tagged Command Queuing (TCQ) %s %s",
1587 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1588 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1589 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1590 printf(" %d tags\n",
1591 ATA_QUEUE_LEN(parm->queue) + 1);
1594 printf("Native Command Queuing (NCQ) ");
1595 if (parm->satacapabilities != 0xffff &&
1596 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1597 printf("yes %d tags\n",
1598 ATA_QUEUE_LEN(parm->queue) + 1);
1602 printf("NCQ Queue Management %s\n", atasata(parm) &&
1603 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1605 printf("NCQ Streaming %s\n", atasata(parm) &&
1606 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1608 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1609 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1612 printf("SMART %s %s\n",
1613 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1614 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1615 printf("microcode download %s %s\n",
1616 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1617 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1618 printf("security %s %s\n",
1619 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1620 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1621 printf("power management %s %s\n",
1622 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1623 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1624 printf("advanced power management %s %s",
1625 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1626 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1627 if (parm->support.command2 & ATA_SUPPORT_APM) {
1628 printf(" %d/0x%02X\n",
1629 parm->apm_value & 0xff, parm->apm_value & 0xff);
1632 printf("automatic acoustic management %s %s",
1633 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1634 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1635 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1636 printf(" %d/0x%02X %d/0x%02X\n",
1637 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1638 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1639 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1640 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1643 printf("media status notification %s %s\n",
1644 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1645 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1646 printf("power-up in Standby %s %s\n",
1647 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1648 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1649 printf("write-read-verify %s %s",
1650 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1651 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1652 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1653 printf(" %d/0x%x\n",
1654 parm->wrv_mode, parm->wrv_mode);
1657 printf("unload %s %s\n",
1658 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1659 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1660 printf("general purpose logging %s %s\n",
1661 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1662 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1663 printf("free-fall %s %s\n",
1664 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1665 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1666 printf("Data Set Management (DSM/TRIM) ");
1667 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1669 printf("DSM - max 512byte blocks ");
1670 if (parm->max_dsm_blocks == 0x00)
1671 printf("yes not specified\n");
1674 parm->max_dsm_blocks);
1676 printf("DSM - deterministic read ");
1677 if (parm->support3 & ATA_SUPPORT_DRAT) {
1678 if (parm->support3 & ATA_SUPPORT_RZAT)
1679 printf("yes zeroed\n");
1681 printf("yes any value\n");
1691 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1693 struct ata_pass_16 *ata_pass_16;
1694 struct ata_cmd ata_cmd;
1696 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1697 ata_cmd.command = ata_pass_16->command;
1698 ata_cmd.control = ata_pass_16->control;
1699 ata_cmd.features = ata_pass_16->features;
1701 if (arglist & CAM_ARG_VERBOSE) {
1702 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1703 ata_op_string(&ata_cmd),
1704 ccb->csio.ccb_h.timeout);
1707 /* Disable freezing the device queue */
1708 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1710 if (arglist & CAM_ARG_ERR_RECOVER)
1711 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1713 if (cam_send_ccb(device, ccb) < 0) {
1714 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1715 warn("error sending ATA %s via pass_16",
1716 ata_op_string(&ata_cmd));
1719 if (arglist & CAM_ARG_VERBOSE) {
1720 cam_error_print(device, ccb, CAM_ESF_ALL,
1721 CAM_EPF_ALL, stderr);
1727 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1728 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1729 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1730 warnx("ATA %s via pass_16 failed",
1731 ata_op_string(&ata_cmd));
1733 if (arglist & CAM_ARG_VERBOSE) {
1734 cam_error_print(device, ccb, CAM_ESF_ALL,
1735 CAM_EPF_ALL, stderr);
1746 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1748 if (arglist & CAM_ARG_VERBOSE) {
1749 warnx("sending ATA %s with timeout of %u msecs",
1750 ata_op_string(&(ccb->ataio.cmd)),
1751 ccb->ataio.ccb_h.timeout);
1754 /* Disable freezing the device queue */
1755 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1757 if (arglist & CAM_ARG_ERR_RECOVER)
1758 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1760 if (cam_send_ccb(device, ccb) < 0) {
1761 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1762 warn("error sending ATA %s",
1763 ata_op_string(&(ccb->ataio.cmd)));
1766 if (arglist & CAM_ARG_VERBOSE) {
1767 cam_error_print(device, ccb, CAM_ESF_ALL,
1768 CAM_EPF_ALL, stderr);
1774 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1775 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1776 warnx("ATA %s failed: %d",
1777 ata_op_string(&(ccb->ataio.cmd)), quiet);
1780 if (arglist & CAM_ARG_VERBOSE) {
1781 cam_error_print(device, ccb, CAM_ESF_ALL,
1782 CAM_EPF_ALL, stderr);
1792 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1793 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1794 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1795 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1796 u_int16_t dxfer_len, int timeout, int quiet)
1798 if (data_ptr != NULL) {
1799 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1800 AP_FLAG_TLEN_SECT_CNT;
1801 if (flags & CAM_DIR_OUT)
1802 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1804 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1806 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1809 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1811 scsi_ata_pass_16(&ccb->csio,
1825 /*sense_len*/SSD_FULL_SIZE,
1828 return scsi_cam_pass_16_send(device, ccb, quiet);
1832 ata_try_pass_16(struct cam_device *device)
1834 struct ccb_pathinq cpi;
1836 if (get_cpi(device, &cpi) != 0) {
1837 warnx("couldn't get CPI");
1841 if (cpi.protocol == PROTO_SCSI) {
1842 /* possibly compatible with pass_16 */
1846 /* likely not compatible with pass_16 */
1851 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1852 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1853 u_int8_t command, u_int8_t features, u_int32_t lba,
1854 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1855 int timeout, int quiet)
1859 switch (ata_try_pass_16(device)) {
1863 /* Try using SCSI Passthrough */
1864 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1865 0, tag_action, command, features, lba,
1866 sector_count, data_ptr, dxfer_len,
1870 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1871 cam_fill_ataio(&ccb->ataio,
1880 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1881 return ata_cam_send(device, ccb, quiet);
1885 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1886 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1887 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1888 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1889 u_int16_t dxfer_len, int timeout, int force48bit)
1893 retval = ata_try_pass_16(device);
1900 /* Try using SCSI Passthrough */
1901 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1902 ata_flags, tag_action, command, features,
1903 lba, sector_count, data_ptr, dxfer_len,
1906 if (ata_flags & AP_FLAG_CHK_COND) {
1907 /* Decode ata_res from sense data */
1908 struct ata_res_pass16 *res_pass16;
1909 struct ata_res *res;
1913 /* sense_data is 4 byte aligned */
1914 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1915 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1916 ptr[i] = le16toh(ptr[i]);
1918 /* sense_data is 4 byte aligned */
1919 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1920 &ccb->csio.sense_data;
1921 res = &ccb->ataio.res;
1922 res->flags = res_pass16->flags;
1923 res->status = res_pass16->status;
1924 res->error = res_pass16->error;
1925 res->lba_low = res_pass16->lba_low;
1926 res->lba_mid = res_pass16->lba_mid;
1927 res->lba_high = res_pass16->lba_high;
1928 res->device = res_pass16->device;
1929 res->lba_low_exp = res_pass16->lba_low_exp;
1930 res->lba_mid_exp = res_pass16->lba_mid_exp;
1931 res->lba_high_exp = res_pass16->lba_high_exp;
1932 res->sector_count = res_pass16->sector_count;
1933 res->sector_count_exp = res_pass16->sector_count_exp;
1939 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1940 cam_fill_ataio(&ccb->ataio,
1949 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1950 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1952 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1954 if (ata_flags & AP_FLAG_CHK_COND)
1955 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1957 return ata_cam_send(device, ccb, 0);
1961 dump_data(uint16_t *ptr, uint32_t len)
1965 for (i = 0; i < len / 2; i++) {
1967 printf(" %3d: ", i);
1968 printf("%04hx ", ptr[i]);
1977 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1978 int is48bit, u_int64_t *hpasize)
1980 struct ata_res *res;
1982 res = &ccb->ataio.res;
1983 if (res->status & ATA_STATUS_ERROR) {
1984 if (arglist & CAM_ARG_VERBOSE) {
1985 cam_error_print(device, ccb, CAM_ESF_ALL,
1986 CAM_EPF_ALL, stderr);
1987 printf("error = 0x%02x, sector_count = 0x%04x, "
1988 "device = 0x%02x, status = 0x%02x\n",
1989 res->error, res->sector_count,
1990 res->device, res->status);
1993 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1994 warnx("Max address has already been set since "
1995 "last power-on or hardware reset");
2001 if (arglist & CAM_ARG_VERBOSE) {
2002 fprintf(stdout, "%s%d: Raw native max data:\n",
2003 device->device_name, device->dev_unit_num);
2004 /* res is 4 byte aligned */
2005 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
2007 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
2008 "status = 0x%02x\n", res->error, res->sector_count,
2009 res->device, res->status);
2012 if (hpasize != NULL) {
2014 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
2015 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
2016 ((res->lba_high << 16) | (res->lba_mid << 8) |
2019 *hpasize = (((res->device & 0x0f) << 24) |
2020 (res->lba_high << 16) | (res->lba_mid << 8) |
2029 ata_read_native_max(struct cam_device *device, int retry_count,
2030 u_int32_t timeout, union ccb *ccb,
2031 struct ata_params *parm, u_int64_t *hpasize)
2037 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
2038 protocol = AP_PROTO_NON_DATA;
2041 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
2042 protocol |= AP_EXTEND;
2044 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
2047 error = ata_do_cmd(device,
2050 /*flags*/CAM_DIR_NONE,
2051 /*protocol*/protocol,
2052 /*ata_flags*/AP_FLAG_CHK_COND,
2053 /*tag_action*/MSG_SIMPLE_Q_TAG,
2060 timeout ? timeout : 1000,
2066 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
2070 atahpa_set_max(struct cam_device *device, int retry_count,
2071 u_int32_t timeout, union ccb *ccb,
2072 int is48bit, u_int64_t maxsize, int persist)
2078 protocol = AP_PROTO_NON_DATA;
2081 cmd = ATA_SET_MAX_ADDRESS48;
2082 protocol |= AP_EXTEND;
2084 cmd = ATA_SET_MAX_ADDRESS;
2087 /* lba's are zero indexed so the max lba is requested max - 1 */
2091 error = ata_do_cmd(device,
2094 /*flags*/CAM_DIR_NONE,
2095 /*protocol*/protocol,
2096 /*ata_flags*/AP_FLAG_CHK_COND,
2097 /*tag_action*/MSG_SIMPLE_Q_TAG,
2099 /*features*/ATA_HPA_FEAT_MAX_ADDR,
2101 /*sector_count*/persist,
2104 timeout ? timeout : 1000,
2110 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2114 atahpa_password(struct cam_device *device, int retry_count,
2115 u_int32_t timeout, union ccb *ccb,
2116 int is48bit, struct ata_set_max_pwd *pwd)
2122 protocol = AP_PROTO_PIO_OUT;
2123 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2125 error = ata_do_cmd(device,
2128 /*flags*/CAM_DIR_OUT,
2129 /*protocol*/protocol,
2130 /*ata_flags*/AP_FLAG_CHK_COND,
2131 /*tag_action*/MSG_SIMPLE_Q_TAG,
2133 /*features*/ATA_HPA_FEAT_SET_PWD,
2136 /*data_ptr*/(u_int8_t*)pwd,
2137 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2138 timeout ? timeout : 1000,
2144 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2148 atahpa_lock(struct cam_device *device, int retry_count,
2149 u_int32_t timeout, union ccb *ccb, int is48bit)
2155 protocol = AP_PROTO_NON_DATA;
2156 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2158 error = ata_do_cmd(device,
2161 /*flags*/CAM_DIR_NONE,
2162 /*protocol*/protocol,
2163 /*ata_flags*/AP_FLAG_CHK_COND,
2164 /*tag_action*/MSG_SIMPLE_Q_TAG,
2166 /*features*/ATA_HPA_FEAT_LOCK,
2171 timeout ? timeout : 1000,
2177 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2181 atahpa_unlock(struct cam_device *device, int retry_count,
2182 u_int32_t timeout, union ccb *ccb,
2183 int is48bit, struct ata_set_max_pwd *pwd)
2189 protocol = AP_PROTO_PIO_OUT;
2190 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2192 error = ata_do_cmd(device,
2195 /*flags*/CAM_DIR_OUT,
2196 /*protocol*/protocol,
2197 /*ata_flags*/AP_FLAG_CHK_COND,
2198 /*tag_action*/MSG_SIMPLE_Q_TAG,
2200 /*features*/ATA_HPA_FEAT_UNLOCK,
2203 /*data_ptr*/(u_int8_t*)pwd,
2204 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2205 timeout ? timeout : 1000,
2211 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2215 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2216 u_int32_t timeout, union ccb *ccb, int is48bit)
2222 protocol = AP_PROTO_NON_DATA;
2223 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2225 error = ata_do_cmd(device,
2228 /*flags*/CAM_DIR_NONE,
2229 /*protocol*/protocol,
2230 /*ata_flags*/AP_FLAG_CHK_COND,
2231 /*tag_action*/MSG_SIMPLE_Q_TAG,
2233 /*features*/ATA_HPA_FEAT_FREEZE,
2238 timeout ? timeout : 1000,
2244 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2249 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2250 union ccb *ccb, struct ata_params** ident_bufp)
2252 struct ata_params *ident_buf;
2253 struct ccb_pathinq cpi;
2254 struct ccb_getdev cgd;
2257 u_int8_t command, retry_command;
2259 if (get_cpi(device, &cpi) != 0) {
2260 warnx("couldn't get CPI");
2264 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2265 if (cpi.protocol == PROTO_ATA) {
2266 if (get_cgd(device, &cgd) != 0) {
2267 warnx("couldn't get CGD");
2271 command = (cgd.protocol == PROTO_ATA) ?
2272 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2275 /* We don't know which for sure so try both */
2276 command = ATA_ATA_IDENTIFY;
2277 retry_command = ATA_ATAPI_IDENTIFY;
2280 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2282 warnx("can't calloc memory for identify\n");
2286 error = ata_do_28bit_cmd(device,
2288 /*retries*/retry_count,
2289 /*flags*/CAM_DIR_IN,
2290 /*protocol*/AP_PROTO_PIO_IN,
2291 /*tag_action*/MSG_SIMPLE_Q_TAG,
2296 /*data_ptr*/(u_int8_t *)ptr,
2297 /*dxfer_len*/sizeof(struct ata_params),
2298 /*timeout*/timeout ? timeout : 30 * 1000,
2302 if (retry_command == 0) {
2306 error = ata_do_28bit_cmd(device,
2308 /*retries*/retry_count,
2309 /*flags*/CAM_DIR_IN,
2310 /*protocol*/AP_PROTO_PIO_IN,
2311 /*tag_action*/MSG_SIMPLE_Q_TAG,
2312 /*command*/retry_command,
2316 /*data_ptr*/(u_int8_t *)ptr,
2317 /*dxfer_len*/sizeof(struct ata_params),
2318 /*timeout*/timeout ? timeout : 30 * 1000,
2328 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2329 ptr[i] = le16toh(ptr[i]);
2334 if (arglist & CAM_ARG_VERBOSE) {
2335 fprintf(stdout, "%s%d: Raw identify data:\n",
2336 device->device_name, device->dev_unit_num);
2337 dump_data(ptr, sizeof(struct ata_params));
2340 /* check for invalid (all zero) response */
2342 warnx("Invalid identify response detected");
2347 ident_buf = (struct ata_params *)ptr;
2348 if (strncmp(ident_buf->model, "FX", 2) &&
2349 strncmp(ident_buf->model, "NEC", 3) &&
2350 strncmp(ident_buf->model, "Pioneer", 7) &&
2351 strncmp(ident_buf->model, "SHARP", 5)) {
2352 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2353 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2354 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2355 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2357 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2358 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2359 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2360 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2361 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2362 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2363 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2364 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2365 sizeof(ident_buf->media_serial));
2367 *ident_bufp = ident_buf;
2374 ataidentify(struct cam_device *device, int retry_count, int timeout)
2377 struct ata_params *ident_buf;
2380 if ((ccb = cam_getccb(device)) == NULL) {
2381 warnx("couldn't allocate CCB");
2385 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2390 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2391 if (ata_read_native_max(device, retry_count, timeout, ccb,
2392 ident_buf, &hpasize) != 0) {
2400 printf("%s%d: ", device->device_name, device->dev_unit_num);
2401 ata_print_ident(ident_buf);
2402 camxferrate(device);
2403 atacapprint(ident_buf);
2404 atahpa_print(ident_buf, hpasize, 0);
2414 nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused)
2416 struct nvme_controller_data cdata;
2418 if (nvme_get_cdata(device, &cdata))
2420 nvme_print_controller(&cdata);
2427 identify(struct cam_device *device, int retry_count, int timeout)
2430 struct ccb_pathinq cpi;
2432 if (get_cpi(device, &cpi) != 0) {
2433 warnx("couldn't get CPI");
2437 if (cpi.protocol == PROTO_NVME) {
2438 return (nvmeidentify(device, retry_count, timeout));
2441 return (ataidentify(device, retry_count, timeout));
2443 #endif /* MINIMALISTIC */
2446 #ifndef MINIMALISTIC
2448 ATA_SECURITY_ACTION_PRINT,
2449 ATA_SECURITY_ACTION_FREEZE,
2450 ATA_SECURITY_ACTION_UNLOCK,
2451 ATA_SECURITY_ACTION_DISABLE,
2452 ATA_SECURITY_ACTION_ERASE,
2453 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2454 ATA_SECURITY_ACTION_SET_PASSWORD
2458 atasecurity_print_time(u_int16_t tw)
2462 printf("unspecified");
2464 printf("> 508 min");
2466 printf("%i min", 2 * tw);
2470 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2474 return 2 * 3600 * 1000; /* default: two hours */
2475 else if (timeout > 255)
2476 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2478 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2483 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2487 bzero(&cmd, sizeof(cmd));
2488 cmd.command = command;
2489 printf("Issuing %s", ata_op_string(&cmd));
2492 char pass[sizeof(pwd->password)+1];
2494 /* pwd->password may not be null terminated */
2495 pass[sizeof(pwd->password)] = '\0';
2496 strncpy(pass, pwd->password, sizeof(pwd->password));
2497 printf(" password='%s', user='%s'",
2499 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2502 if (command == ATA_SECURITY_SET_PASSWORD) {
2503 printf(", mode='%s'",
2504 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2505 "maximum" : "high");
2513 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2514 int retry_count, u_int32_t timeout, int quiet)
2518 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2520 return ata_do_28bit_cmd(device,
2523 /*flags*/CAM_DIR_NONE,
2524 /*protocol*/AP_PROTO_NON_DATA,
2525 /*tag_action*/MSG_SIMPLE_Q_TAG,
2526 /*command*/ATA_SECURITY_FREEZE_LOCK,
2537 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2538 int retry_count, u_int32_t timeout,
2539 struct ata_security_password *pwd, int quiet)
2543 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2545 return ata_do_28bit_cmd(device,
2548 /*flags*/CAM_DIR_OUT,
2549 /*protocol*/AP_PROTO_PIO_OUT,
2550 /*tag_action*/MSG_SIMPLE_Q_TAG,
2551 /*command*/ATA_SECURITY_UNLOCK,
2555 /*data_ptr*/(u_int8_t *)pwd,
2556 /*dxfer_len*/sizeof(*pwd),
2562 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2563 int retry_count, u_int32_t timeout,
2564 struct ata_security_password *pwd, int quiet)
2568 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2569 return ata_do_28bit_cmd(device,
2572 /*flags*/CAM_DIR_OUT,
2573 /*protocol*/AP_PROTO_PIO_OUT,
2574 /*tag_action*/MSG_SIMPLE_Q_TAG,
2575 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2579 /*data_ptr*/(u_int8_t *)pwd,
2580 /*dxfer_len*/sizeof(*pwd),
2587 atasecurity_erase_confirm(struct cam_device *device,
2588 struct ata_params* ident_buf)
2591 printf("\nYou are about to ERASE ALL DATA from the following"
2592 " device:\n%s%d,%s%d: ", device->device_name,
2593 device->dev_unit_num, device->given_dev_name,
2594 device->given_unit_number);
2595 ata_print_ident(ident_buf);
2599 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2601 if (fgets(str, sizeof(str), stdin) != NULL) {
2602 if (strncasecmp(str, "yes", 3) == 0) {
2604 } else if (strncasecmp(str, "no", 2) == 0) {
2607 printf("Please answer \"yes\" or "
2618 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2619 int retry_count, u_int32_t timeout,
2620 u_int32_t erase_timeout,
2621 struct ata_security_password *pwd, int quiet)
2626 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2628 error = ata_do_28bit_cmd(device,
2631 /*flags*/CAM_DIR_NONE,
2632 /*protocol*/AP_PROTO_NON_DATA,
2633 /*tag_action*/MSG_SIMPLE_Q_TAG,
2634 /*command*/ATA_SECURITY_ERASE_PREPARE,
2647 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2649 error = ata_do_28bit_cmd(device,
2652 /*flags*/CAM_DIR_OUT,
2653 /*protocol*/AP_PROTO_PIO_OUT,
2654 /*tag_action*/MSG_SIMPLE_Q_TAG,
2655 /*command*/ATA_SECURITY_ERASE_UNIT,
2659 /*data_ptr*/(u_int8_t *)pwd,
2660 /*dxfer_len*/sizeof(*pwd),
2661 /*timeout*/erase_timeout,
2664 if (error == 0 && quiet == 0)
2665 printf("\nErase Complete\n");
2671 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2672 int retry_count, u_int32_t timeout,
2673 struct ata_security_password *pwd, int quiet)
2677 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2679 return ata_do_28bit_cmd(device,
2682 /*flags*/CAM_DIR_OUT,
2683 /*protocol*/AP_PROTO_PIO_OUT,
2684 /*tag_action*/MSG_SIMPLE_Q_TAG,
2685 /*command*/ATA_SECURITY_SET_PASSWORD,
2689 /*data_ptr*/(u_int8_t *)pwd,
2690 /*dxfer_len*/sizeof(*pwd),
2696 atasecurity_print(struct ata_params *parm)
2699 printf("\nSecurity Option Value\n");
2700 if (arglist & CAM_ARG_VERBOSE) {
2701 printf("status %04x\n",
2702 parm->security_status);
2704 printf("supported %s\n",
2705 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2706 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2708 printf("enabled %s\n",
2709 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2710 printf("drive locked %s\n",
2711 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2712 printf("security config frozen %s\n",
2713 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2714 printf("count expired %s\n",
2715 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2716 printf("security level %s\n",
2717 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2718 printf("enhanced erase supported %s\n",
2719 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2720 printf("erase time ");
2721 atasecurity_print_time(parm->erase_time);
2723 printf("enhanced erase time ");
2724 atasecurity_print_time(parm->enhanced_erase_time);
2726 printf("master password rev %04x%s\n",
2727 parm->master_passwd_revision,
2728 parm->master_passwd_revision == 0x0000 ||
2729 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2733 * Validates and copies the password in optarg to the passed buffer.
2734 * If the password in optarg is the same length as the buffer then
2735 * the data will still be copied but no null termination will occur.
2738 ata_getpwd(u_int8_t *passwd, int max, char opt)
2742 len = strlen(optarg);
2744 warnx("-%c password is too long", opt);
2746 } else if (len == 0) {
2747 warnx("-%c password is missing", opt);
2749 } else if (optarg[0] == '-'){
2750 warnx("-%c password starts with '-' (generic arg?)", opt);
2752 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2753 warnx("-%c password conflicts with existing password from -%c",
2758 /* Callers pass in a buffer which does NOT need to be terminated */
2759 strncpy(passwd, optarg, max);
2766 ATA_HPA_ACTION_PRINT,
2767 ATA_HPA_ACTION_SET_MAX,
2768 ATA_HPA_ACTION_SET_PWD,
2769 ATA_HPA_ACTION_LOCK,
2770 ATA_HPA_ACTION_UNLOCK,
2771 ATA_HPA_ACTION_FREEZE_LOCK
2775 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2776 u_int64_t maxsize, int persist)
2778 printf("\nYou are about to configure HPA to limit the user accessible\n"
2779 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2780 persist ? "persistently" : "temporarily",
2781 device->device_name, device->dev_unit_num,
2782 device->given_dev_name, device->given_unit_number);
2783 ata_print_ident(ident_buf);
2787 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2789 if (NULL != fgets(str, sizeof(str), stdin)) {
2790 if (0 == strncasecmp(str, "yes", 3)) {
2792 } else if (0 == strncasecmp(str, "no", 2)) {
2795 printf("Please answer \"yes\" or "
2806 atahpa(struct cam_device *device, int retry_count, int timeout,
2807 int argc, char **argv, char *combinedopt)
2810 struct ata_params *ident_buf;
2811 struct ccb_getdev cgd;
2812 struct ata_set_max_pwd pwd;
2813 int error, confirm, quiet, c, action, actions, persist;
2814 int security, is48bit, pwdsize;
2815 u_int64_t hpasize, maxsize;
2824 memset(&pwd, 0, sizeof(pwd));
2826 /* default action is to print hpa information */
2827 action = ATA_HPA_ACTION_PRINT;
2828 pwdsize = sizeof(pwd.password);
2830 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2833 action = ATA_HPA_ACTION_SET_MAX;
2834 maxsize = strtoumax(optarg, NULL, 0);
2839 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2841 action = ATA_HPA_ACTION_SET_PWD;
2847 action = ATA_HPA_ACTION_LOCK;
2853 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2855 action = ATA_HPA_ACTION_UNLOCK;
2861 action = ATA_HPA_ACTION_FREEZE_LOCK;
2881 warnx("too many hpa actions specified");
2885 if (get_cgd(device, &cgd) != 0) {
2886 warnx("couldn't get CGD");
2890 ccb = cam_getccb(device);
2892 warnx("couldn't allocate CCB");
2896 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2903 printf("%s%d: ", device->device_name, device->dev_unit_num);
2904 ata_print_ident(ident_buf);
2905 camxferrate(device);
2908 if (action == ATA_HPA_ACTION_PRINT) {
2909 error = ata_read_native_max(device, retry_count, timeout, ccb,
2910 ident_buf, &hpasize);
2912 atahpa_print(ident_buf, hpasize, 1);
2919 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2920 warnx("HPA is not supported by this device");
2926 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2927 warnx("HPA Security is not supported by this device");
2933 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2936 * The ATA spec requires:
2937 * 1. Read native max addr is called directly before set max addr
2938 * 2. Read native max addr is NOT called before any other set max call
2941 case ATA_HPA_ACTION_SET_MAX:
2943 atahpa_set_confirm(device, ident_buf, maxsize,
2950 error = ata_read_native_max(device, retry_count, timeout,
2951 ccb, ident_buf, &hpasize);
2953 error = atahpa_set_max(device, retry_count, timeout,
2954 ccb, is48bit, maxsize, persist);
2956 /* redo identify to get new lba values */
2957 error = ata_do_identify(device, retry_count,
2960 atahpa_print(ident_buf, hpasize, 1);
2965 case ATA_HPA_ACTION_SET_PWD:
2966 error = atahpa_password(device, retry_count, timeout,
2967 ccb, is48bit, &pwd);
2969 printf("HPA password has been set\n");
2972 case ATA_HPA_ACTION_LOCK:
2973 error = atahpa_lock(device, retry_count, timeout,
2976 printf("HPA has been locked\n");
2979 case ATA_HPA_ACTION_UNLOCK:
2980 error = atahpa_unlock(device, retry_count, timeout,
2981 ccb, is48bit, &pwd);
2983 printf("HPA has been unlocked\n");
2986 case ATA_HPA_ACTION_FREEZE_LOCK:
2987 error = atahpa_freeze_lock(device, retry_count, timeout,
2990 printf("HPA has been frozen\n");
2994 errx(1, "Option currently not supported");
3004 atasecurity(struct cam_device *device, int retry_count, int timeout,
3005 int argc, char **argv, char *combinedopt)
3008 struct ata_params *ident_buf;
3009 int error, confirm, quiet, c, action, actions, setpwd;
3010 int security_enabled, erase_timeout, pwdsize;
3011 struct ata_security_password pwd;
3019 memset(&pwd, 0, sizeof(pwd));
3021 /* default action is to print security information */
3022 action = ATA_SECURITY_ACTION_PRINT;
3024 /* user is master by default as its safer that way */
3025 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3026 pwdsize = sizeof(pwd.password);
3028 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3031 action = ATA_SECURITY_ACTION_FREEZE;
3036 if (strcasecmp(optarg, "user") == 0) {
3037 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
3038 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
3039 } else if (strcasecmp(optarg, "master") == 0) {
3040 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3041 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
3043 warnx("-U argument '%s' is invalid (must be "
3044 "'user' or 'master')", optarg);
3050 if (strcasecmp(optarg, "high") == 0) {
3051 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3052 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3053 } else if (strcasecmp(optarg, "maximum") == 0) {
3054 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3055 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3057 warnx("-l argument '%s' is unknown (must be "
3058 "'high' or 'maximum')", optarg);
3064 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3066 action = ATA_SECURITY_ACTION_UNLOCK;
3071 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3073 action = ATA_SECURITY_ACTION_DISABLE;
3078 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3080 action = ATA_SECURITY_ACTION_ERASE;
3085 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3087 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3088 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3093 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3096 if (action == ATA_SECURITY_ACTION_PRINT)
3097 action = ATA_SECURITY_ACTION_SET_PASSWORD;
3099 * Don't increment action as this can be combined
3100 * with other actions.
3113 erase_timeout = atoi(optarg) * 1000;
3119 warnx("too many security actions specified");
3123 if ((ccb = cam_getccb(device)) == NULL) {
3124 warnx("couldn't allocate CCB");
3128 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3135 printf("%s%d: ", device->device_name, device->dev_unit_num);
3136 ata_print_ident(ident_buf);
3137 camxferrate(device);
3140 if (action == ATA_SECURITY_ACTION_PRINT) {
3141 atasecurity_print(ident_buf);
3147 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3148 warnx("Security not supported");
3154 /* default timeout 15 seconds the same as linux hdparm */
3155 timeout = timeout ? timeout : 15 * 1000;
3157 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3159 /* first set the password if requested */
3161 /* confirm we can erase before setting the password if erasing */
3163 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3164 action == ATA_SECURITY_ACTION_ERASE) &&
3165 atasecurity_erase_confirm(device, ident_buf) == 0) {
3171 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3172 pwd.revision = ident_buf->master_passwd_revision;
3173 if (pwd.revision != 0 && pwd.revision != 0xfff &&
3174 --pwd.revision == 0) {
3175 pwd.revision = 0xfffe;
3178 error = atasecurity_set_password(device, ccb, retry_count,
3179 timeout, &pwd, quiet);
3185 security_enabled = 1;
3189 case ATA_SECURITY_ACTION_FREEZE:
3190 error = atasecurity_freeze(device, ccb, retry_count,
3194 case ATA_SECURITY_ACTION_UNLOCK:
3195 if (security_enabled) {
3196 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3197 error = atasecurity_unlock(device, ccb,
3198 retry_count, timeout, &pwd, quiet);
3200 warnx("Can't unlock, drive is not locked");
3204 warnx("Can't unlock, security is disabled");
3209 case ATA_SECURITY_ACTION_DISABLE:
3210 if (security_enabled) {
3211 /* First unlock the drive if its locked */
3212 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3213 error = atasecurity_unlock(device, ccb,
3221 error = atasecurity_disable(device,
3229 warnx("Can't disable security (already disabled)");
3234 case ATA_SECURITY_ACTION_ERASE:
3235 if (security_enabled) {
3236 if (erase_timeout == 0) {
3237 erase_timeout = atasecurity_erase_timeout_msecs(
3238 ident_buf->erase_time);
3241 error = atasecurity_erase(device, ccb, retry_count,
3242 timeout, erase_timeout, &pwd, quiet);
3244 warnx("Can't secure erase (security is disabled)");
3249 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3250 if (security_enabled) {
3251 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3252 if (erase_timeout == 0) {
3254 atasecurity_erase_timeout_msecs(
3255 ident_buf->enhanced_erase_time);
3258 error = atasecurity_erase(device, ccb,
3259 retry_count, timeout,
3260 erase_timeout, &pwd,
3263 warnx("Enhanced erase is not supported");
3267 warnx("Can't secure erase (enhanced), "
3268 "(security is disabled)");
3279 #endif /* MINIMALISTIC */
3282 * Parse out a bus, or a bus, target and lun in the following
3288 * Returns the number of parsed components, or 0.
3291 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3292 cam_argmask *arglst)
3297 while (isspace(*tstr) && (*tstr != '\0'))
3300 tmpstr = (char *)strtok(tstr, ":");
3301 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3302 *bus = strtol(tmpstr, NULL, 0);
3303 *arglst |= CAM_ARG_BUS;
3305 tmpstr = (char *)strtok(NULL, ":");
3306 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3307 *target = strtol(tmpstr, NULL, 0);
3308 *arglst |= CAM_ARG_TARGET;
3310 tmpstr = (char *)strtok(NULL, ":");
3311 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3312 *lun = strtol(tmpstr, NULL, 0);
3313 *arglst |= CAM_ARG_LUN;
3323 dorescan_or_reset(int argc, char **argv, int rescan)
3325 static const char must[] =
3326 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3328 path_id_t bus = CAM_BUS_WILDCARD;
3329 target_id_t target = CAM_TARGET_WILDCARD;
3330 lun_id_t lun = CAM_LUN_WILDCARD;
3334 warnx(must, rescan? "rescan" : "reset");
3338 tstr = argv[optind];
3339 while (isspace(*tstr) && (*tstr != '\0'))
3341 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3342 arglist |= CAM_ARG_BUS;
3343 else if (isdigit(*tstr)) {
3344 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3345 if (rv != 1 && rv != 3) {
3346 warnx(must, rescan? "rescan" : "reset");
3356 * Note that resetting or rescanning a device used to
3357 * require a bus or bus:target:lun. This is because the
3358 * device in question may not exist and you're trying to
3359 * get the controller to rescan to find it. It may also be
3360 * because the device is hung / unresponsive, and opening
3361 * an unresponsive device is not desireable.
3363 * It can be more convenient to reference a device by
3364 * peripheral name and unit number, though, and it is
3365 * possible to get the bus:target:lun for devices that
3366 * currently exist in the EDT. So this can work for
3367 * devices that we want to reset, or devices that exist
3368 * that we want to rescan, but not devices that do not
3371 * So, we are careful here to look up the bus/target/lun
3372 * for the device the user wants to operate on, specified
3373 * by peripheral instance (e.g. da0, pass32) without
3374 * actually opening that device. The process is similar to
3375 * what cam_lookup_pass() does, except that we don't
3376 * actually open the passthrough driver instance in the end.
3379 if (cam_get_device(tstr, name, sizeof(name), &unit) == -1) {
3380 warnx("%s", cam_errbuf);
3385 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3386 warn("Unable to open %s", XPT_DEVICE);
3391 bzero(&ccb, sizeof(ccb));
3394 * The function code isn't strictly necessary for the
3395 * GETPASSTHRU ioctl.
3397 ccb.ccb_h.func_code = XPT_GDEVLIST;
3400 * These two are necessary for the GETPASSTHRU ioctl to
3403 strlcpy(ccb.cgdl.periph_name, name,
3404 sizeof(ccb.cgdl.periph_name));
3405 ccb.cgdl.unit_number = unit;
3408 * Attempt to get the passthrough device. This ioctl will
3409 * fail if the device name is null, if the device doesn't
3410 * exist, or if the passthrough driver isn't in the kernel.
3412 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3413 warn("Unable to find bus:target:lun for device %s%d",
3419 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3420 const struct cam_status_entry *entry;
3422 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3423 warnx("Unable to find bus:target_lun for device %s%d, "
3424 "CAM status: %s (%#x)", name, unit,
3425 entry ? entry->status_text : "Unknown",
3433 * The kernel fills in the bus/target/lun. We don't
3434 * need the passthrough device name and unit number since
3435 * we aren't going to open it.
3437 bus = ccb.ccb_h.path_id;
3438 target = ccb.ccb_h.target_id;
3439 lun = ccb.ccb_h.target_lun;
3441 arglist |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3446 if ((arglist & CAM_ARG_BUS)
3447 && (arglist & CAM_ARG_TARGET)
3448 && (arglist & CAM_ARG_LUN))
3449 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3451 error = rescan_or_reset_bus(bus, rescan);
3459 rescan_or_reset_bus(path_id_t bus, int rescan)
3461 union ccb *ccb = NULL, *matchccb = NULL;
3462 int fd = -1, retval;
3467 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3468 warnx("error opening transport layer device %s", XPT_DEVICE);
3469 warn("%s", XPT_DEVICE);
3473 ccb = malloc(sizeof(*ccb));
3475 warn("failed to allocate CCB");
3479 bzero(ccb, sizeof(*ccb));
3481 if (bus != CAM_BUS_WILDCARD) {
3482 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3483 ccb->ccb_h.path_id = bus;
3484 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3485 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3486 ccb->crcn.flags = CAM_FLAG_NONE;
3488 /* run this at a low priority */
3489 ccb->ccb_h.pinfo.priority = 5;
3491 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3492 warn("CAMIOCOMMAND ioctl failed");
3497 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3498 fprintf(stdout, "%s of bus %d was successful\n",
3499 rescan ? "Re-scan" : "Reset", bus);
3501 fprintf(stdout, "%s of bus %d returned error %#x\n",
3502 rescan ? "Re-scan" : "Reset", bus,
3503 ccb->ccb_h.status & CAM_STATUS_MASK);
3512 * The right way to handle this is to modify the xpt so that it can
3513 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3514 * that isn't implemented, so instead we enumerate the buses and
3515 * send the rescan or reset to those buses in the case where the
3516 * given bus is -1 (wildcard). We don't send a rescan or reset
3517 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3518 * no-op, sending a rescan to the xpt bus would result in a status of
3521 matchccb = malloc(sizeof(*matchccb));
3522 if (matchccb == NULL) {
3523 warn("failed to allocate CCB");
3527 bzero(matchccb, sizeof(*matchccb));
3528 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3529 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3530 bufsize = sizeof(struct dev_match_result) * 20;
3531 matchccb->cdm.match_buf_len = bufsize;
3532 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3533 if (matchccb->cdm.matches == NULL) {
3534 warnx("can't malloc memory for matches");
3538 matchccb->cdm.num_matches = 0;
3540 matchccb->cdm.num_patterns = 1;
3541 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3543 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3544 matchccb->cdm.pattern_buf_len);
3545 if (matchccb->cdm.patterns == NULL) {
3546 warnx("can't malloc memory for patterns");
3550 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3551 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3556 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3557 warn("CAMIOCOMMAND ioctl failed");
3562 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3563 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3564 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3565 warnx("got CAM error %#x, CDM error %d\n",
3566 matchccb->ccb_h.status, matchccb->cdm.status);
3571 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3572 struct bus_match_result *bus_result;
3574 /* This shouldn't happen. */
3575 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3578 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3581 * We don't want to rescan or reset the xpt bus.
3584 if (bus_result->path_id == CAM_XPT_PATH_ID)
3587 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3589 ccb->ccb_h.path_id = bus_result->path_id;
3590 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3591 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3592 ccb->crcn.flags = CAM_FLAG_NONE;
3594 /* run this at a low priority */
3595 ccb->ccb_h.pinfo.priority = 5;
3597 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3598 warn("CAMIOCOMMAND ioctl failed");
3603 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3604 fprintf(stdout, "%s of bus %d was successful\n",
3605 rescan? "Re-scan" : "Reset",
3606 bus_result->path_id);
3609 * Don't bail out just yet, maybe the other
3610 * rescan or reset commands will complete
3613 fprintf(stderr, "%s of bus %d returned error "
3614 "%#x\n", rescan? "Re-scan" : "Reset",
3615 bus_result->path_id,
3616 ccb->ccb_h.status & CAM_STATUS_MASK);
3620 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3621 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3628 if (matchccb != NULL) {
3629 free(matchccb->cdm.patterns);
3630 free(matchccb->cdm.matches);
3639 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3642 struct cam_device *device;
3647 if (bus == CAM_BUS_WILDCARD) {
3648 warnx("invalid bus number %d", bus);
3652 if (target == CAM_TARGET_WILDCARD) {
3653 warnx("invalid target number %d", target);
3657 if (lun == CAM_LUN_WILDCARD) {
3658 warnx("invalid lun number %jx", (uintmax_t)lun);
3664 bzero(&ccb, sizeof(union ccb));
3667 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3668 warnx("error opening transport layer device %s\n",
3670 warn("%s", XPT_DEVICE);
3674 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3675 if (device == NULL) {
3676 warnx("%s", cam_errbuf);
3681 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3682 ccb.ccb_h.path_id = bus;
3683 ccb.ccb_h.target_id = target;
3684 ccb.ccb_h.target_lun = lun;
3685 ccb.ccb_h.timeout = 5000;
3686 ccb.crcn.flags = CAM_FLAG_NONE;
3688 /* run this at a low priority */
3689 ccb.ccb_h.pinfo.priority = 5;
3692 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3693 warn("CAMIOCOMMAND ioctl failed");
3698 if (cam_send_ccb(device, &ccb) < 0) {
3699 warn("error sending XPT_RESET_DEV CCB");
3700 cam_close_device(device);
3708 cam_close_device(device);
3711 * An error code of CAM_BDR_SENT is normal for a BDR request.
3713 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3715 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3716 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3717 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3720 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3721 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3722 ccb.ccb_h.status & CAM_STATUS_MASK);
3727 #ifndef MINIMALISTIC
3729 static struct scsi_nv defect_list_type_map[] = {
3730 { "block", SRDD10_BLOCK_FORMAT },
3731 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3732 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3733 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3734 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3735 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3739 readdefects(struct cam_device *device, int argc, char **argv,
3740 char *combinedopt, int task_attr, int retry_count, int timeout)
3742 union ccb *ccb = NULL;
3743 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3744 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3745 size_t hdr_size = 0, entry_size = 0;
3748 u_int8_t *defect_list = NULL;
3749 u_int8_t list_format = 0;
3750 int list_type_set = 0;
3751 u_int32_t dlist_length = 0;
3752 u_int32_t returned_length = 0, valid_len = 0;
3753 u_int32_t num_returned = 0, num_valid = 0;
3754 u_int32_t max_possible_size = 0, hdr_max = 0;
3755 u_int32_t starting_offset = 0;
3756 u_int8_t returned_format, returned_type;
3758 int summary = 0, quiet = 0;
3760 int lists_specified = 0;
3761 int get_length = 1, first_pass = 1;
3764 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3768 scsi_nv_status status;
3771 status = scsi_get_nv(defect_list_type_map,
3772 sizeof(defect_list_type_map) /
3773 sizeof(defect_list_type_map[0]), optarg,
3774 &entry_num, SCSI_NV_FLAG_IG_CASE);
3776 if (status == SCSI_NV_FOUND) {
3777 list_format = defect_list_type_map[
3781 warnx("%s: %s %s option %s", __func__,
3782 (status == SCSI_NV_AMBIGUOUS) ?
3783 "ambiguous" : "invalid", "defect list type",
3786 goto defect_bailout;
3791 arglist |= CAM_ARG_GLIST;
3794 arglist |= CAM_ARG_PLIST;
3805 starting_offset = strtoul(optarg, &endptr, 0);
3806 if (*endptr != '\0') {
3808 warnx("invalid starting offset %s", optarg);
3809 goto defect_bailout;
3821 if (list_type_set == 0) {
3823 warnx("no defect list format specified");
3824 goto defect_bailout;
3827 if (arglist & CAM_ARG_PLIST) {
3828 list_format |= SRDD10_PLIST;
3832 if (arglist & CAM_ARG_GLIST) {
3833 list_format |= SRDD10_GLIST;
3838 * This implies a summary, and was the previous behavior.
3840 if (lists_specified == 0)
3843 ccb = cam_getccb(device);
3848 * We start off asking for just the header to determine how much
3849 * defect data is available. Some Hitachi drives return an error
3850 * if you ask for more data than the drive has. Once we know the
3851 * length, we retry the command with the returned length.
3853 if (use_12byte == 0)
3854 dlist_length = sizeof(*hdr10);
3856 dlist_length = sizeof(*hdr12);
3859 if (defect_list != NULL) {
3863 defect_list = malloc(dlist_length);
3864 if (defect_list == NULL) {
3865 warnx("can't malloc memory for defect list");
3867 goto defect_bailout;
3871 bzero(defect_list, dlist_length);
3874 * cam_getccb() zeros the CCB header only. So we need to zero the
3875 * payload portion of the ccb.
3877 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3879 scsi_read_defects(&ccb->csio,
3880 /*retries*/ retry_count,
3882 /*tag_action*/ task_attr,
3883 /*list_format*/ list_format,
3884 /*addr_desc_index*/ starting_offset,
3885 /*data_ptr*/ defect_list,
3886 /*dxfer_len*/ dlist_length,
3887 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3888 /*sense_len*/ SSD_FULL_SIZE,
3889 /*timeout*/ timeout ? timeout : 5000);
3891 /* Disable freezing the device queue */
3892 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3894 if (cam_send_ccb(device, ccb) < 0) {
3895 perror("error reading defect list");
3897 if (arglist & CAM_ARG_VERBOSE) {
3898 cam_error_print(device, ccb, CAM_ESF_ALL,
3899 CAM_EPF_ALL, stderr);
3903 goto defect_bailout;
3906 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3908 if (use_12byte == 0) {
3909 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3910 hdr_size = sizeof(*hdr10);
3911 hdr_max = SRDDH10_MAX_LENGTH;
3913 if (valid_len >= hdr_size) {
3914 returned_length = scsi_2btoul(hdr10->length);
3915 returned_format = hdr10->format;
3917 returned_length = 0;
3918 returned_format = 0;
3921 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3922 hdr_size = sizeof(*hdr12);
3923 hdr_max = SRDDH12_MAX_LENGTH;
3925 if (valid_len >= hdr_size) {
3926 returned_length = scsi_4btoul(hdr12->length);
3927 returned_format = hdr12->format;
3929 returned_length = 0;
3930 returned_format = 0;
3934 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3935 switch (returned_type) {
3936 case SRDD10_BLOCK_FORMAT:
3937 entry_size = sizeof(struct scsi_defect_desc_block);
3939 case SRDD10_LONG_BLOCK_FORMAT:
3940 entry_size = sizeof(struct scsi_defect_desc_long_block);
3942 case SRDD10_EXT_PHYS_FORMAT:
3943 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3944 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3946 case SRDD10_EXT_BFI_FORMAT:
3947 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3948 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3951 warnx("Unknown defect format 0x%x\n", returned_type);
3953 goto defect_bailout;
3957 max_possible_size = (hdr_max / entry_size) * entry_size;
3958 num_returned = returned_length / entry_size;
3959 num_valid = min(returned_length, valid_len - hdr_size);
3960 num_valid /= entry_size;
3962 if (get_length != 0) {
3965 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3966 CAM_SCSI_STATUS_ERROR) {
3967 struct scsi_sense_data *sense;
3968 int error_code, sense_key, asc, ascq;
3970 sense = &ccb->csio.sense_data;
3971 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3972 ccb->csio.sense_resid, &error_code, &sense_key,
3973 &asc, &ascq, /*show_errors*/ 1);
3976 * If the drive is reporting that it just doesn't
3977 * support the defect list format, go ahead and use
3978 * the length it reported. Otherwise, the length
3979 * may not be valid, so use the maximum.
3981 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3982 && (asc == 0x1c) && (ascq == 0x00)
3983 && (returned_length > 0)) {
3984 if ((use_12byte == 0)
3985 && (returned_length >= max_possible_size)) {
3990 dlist_length = returned_length + hdr_size;
3991 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3992 && (asc == 0x1f) && (ascq == 0x00)
3993 && (returned_length > 0)) {
3994 /* Partial defect list transfer */
3996 * Hitachi drives return this error
3997 * along with a partial defect list if they
3998 * have more defects than the 10 byte
3999 * command can support. Retry with the 12
4002 if (use_12byte == 0) {
4007 dlist_length = returned_length + hdr_size;
4008 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
4009 && (asc == 0x24) && (ascq == 0x00)) {
4010 /* Invalid field in CDB */
4012 * SBC-3 says that if the drive has more
4013 * defects than can be reported with the
4014 * 10 byte command, it should return this
4015 * error and no data. Retry with the 12
4018 if (use_12byte == 0) {
4023 dlist_length = returned_length + hdr_size;
4026 * If we got a SCSI error and no valid length,
4027 * just use the 10 byte maximum. The 12
4028 * byte maximum is too large.
4030 if (returned_length == 0)
4031 dlist_length = SRDD10_MAX_LENGTH;
4033 if ((use_12byte == 0)
4034 && (returned_length >=
4035 max_possible_size)) {
4040 dlist_length = returned_length +
4044 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4047 warnx("Error reading defect header");
4048 if (arglist & CAM_ARG_VERBOSE)
4049 cam_error_print(device, ccb, CAM_ESF_ALL,
4050 CAM_EPF_ALL, stderr);
4051 goto defect_bailout;
4053 if ((use_12byte == 0)
4054 && (returned_length >= max_possible_size)) {
4059 dlist_length = returned_length + hdr_size;
4062 fprintf(stdout, "%u", num_returned);
4064 fprintf(stdout, " defect%s",
4065 (num_returned != 1) ? "s" : "");
4067 fprintf(stdout, "\n");
4069 goto defect_bailout;
4073 * We always limit the list length to the 10-byte maximum
4074 * length (0xffff). The reason is that some controllers
4075 * can't handle larger I/Os, and we can transfer the entire
4076 * 10 byte list in one shot. For drives that support the 12
4077 * byte read defects command, we'll step through the list
4078 * by specifying a starting offset. For drives that don't
4079 * support the 12 byte command's starting offset, we'll
4080 * just display the first 64K.
4082 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4088 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4089 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4090 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4091 struct scsi_sense_data *sense;
4092 int error_code, sense_key, asc, ascq;
4094 sense = &ccb->csio.sense_data;
4095 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4096 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4097 &ascq, /*show_errors*/ 1);
4100 * According to the SCSI spec, if the disk doesn't support
4101 * the requested format, it will generally return a sense
4102 * key of RECOVERED ERROR, and an additional sense code
4103 * of "DEFECT LIST NOT FOUND". HGST drives also return
4104 * Primary/Grown defect list not found errors. So just
4105 * check for an ASC of 0x1c.
4107 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4109 const char *format_str;
4111 format_str = scsi_nv_to_str(defect_list_type_map,
4112 sizeof(defect_list_type_map) /
4113 sizeof(defect_list_type_map[0]),
4114 list_format & SRDD10_DLIST_FORMAT_MASK);
4115 warnx("requested defect format %s not available",
4116 format_str ? format_str : "unknown");
4118 format_str = scsi_nv_to_str(defect_list_type_map,
4119 sizeof(defect_list_type_map) /
4120 sizeof(defect_list_type_map[0]), returned_type);
4121 if (format_str != NULL) {
4122 warnx("Device returned %s format",
4126 warnx("Device returned unknown defect"
4127 " data format %#x", returned_type);
4128 goto defect_bailout;
4132 warnx("Error returned from read defect data command");
4133 if (arglist & CAM_ARG_VERBOSE)
4134 cam_error_print(device, ccb, CAM_ESF_ALL,
4135 CAM_EPF_ALL, stderr);
4136 goto defect_bailout;
4138 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4140 warnx("Error returned from read defect data command");
4141 if (arglist & CAM_ARG_VERBOSE)
4142 cam_error_print(device, ccb, CAM_ESF_ALL,
4143 CAM_EPF_ALL, stderr);
4144 goto defect_bailout;
4147 if (first_pass != 0) {
4148 fprintf(stderr, "Got %d defect", num_returned);
4150 if ((lists_specified == 0) || (num_returned == 0)) {
4151 fprintf(stderr, "s.\n");
4152 goto defect_bailout;
4153 } else if (num_returned == 1)
4154 fprintf(stderr, ":\n");
4156 fprintf(stderr, "s:\n");
4162 * XXX KDM I should probably clean up the printout format for the
4165 switch (returned_type) {
4166 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4167 case SRDD10_EXT_PHYS_FORMAT:
4169 struct scsi_defect_desc_phys_sector *dlist;
4171 dlist = (struct scsi_defect_desc_phys_sector *)
4172 (defect_list + hdr_size);
4174 for (i = 0; i < num_valid; i++) {
4177 sector = scsi_4btoul(dlist[i].sector);
4178 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4179 mads = (sector & SDD_EXT_PHYS_MADS) ?
4181 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4183 if (hex_format == 0)
4184 fprintf(stdout, "%d:%d:%d%s",
4185 scsi_3btoul(dlist[i].cylinder),
4187 scsi_4btoul(dlist[i].sector),
4188 mads ? " - " : "\n");
4190 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4191 scsi_3btoul(dlist[i].cylinder),
4193 scsi_4btoul(dlist[i].sector),
4194 mads ? " - " : "\n");
4197 if (num_valid < num_returned) {
4198 starting_offset += num_valid;
4203 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4204 case SRDD10_EXT_BFI_FORMAT:
4206 struct scsi_defect_desc_bytes_from_index *dlist;
4208 dlist = (struct scsi_defect_desc_bytes_from_index *)
4209 (defect_list + hdr_size);
4211 for (i = 0; i < num_valid; i++) {
4214 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4215 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4216 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4217 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4219 if (hex_format == 0)
4220 fprintf(stdout, "%d:%d:%d%s",
4221 scsi_3btoul(dlist[i].cylinder),
4223 scsi_4btoul(dlist[i].bytes_from_index),
4224 mads ? " - " : "\n");
4226 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4227 scsi_3btoul(dlist[i].cylinder),
4229 scsi_4btoul(dlist[i].bytes_from_index),
4230 mads ? " - " : "\n");
4234 if (num_valid < num_returned) {
4235 starting_offset += num_valid;
4240 case SRDDH10_BLOCK_FORMAT:
4242 struct scsi_defect_desc_block *dlist;
4244 dlist = (struct scsi_defect_desc_block *)
4245 (defect_list + hdr_size);
4247 for (i = 0; i < num_valid; i++) {
4248 if (hex_format == 0)
4249 fprintf(stdout, "%u\n",
4250 scsi_4btoul(dlist[i].address));
4252 fprintf(stdout, "0x%x\n",
4253 scsi_4btoul(dlist[i].address));
4256 if (num_valid < num_returned) {
4257 starting_offset += num_valid;
4263 case SRDD10_LONG_BLOCK_FORMAT:
4265 struct scsi_defect_desc_long_block *dlist;
4267 dlist = (struct scsi_defect_desc_long_block *)
4268 (defect_list + hdr_size);
4270 for (i = 0; i < num_valid; i++) {
4271 if (hex_format == 0)
4272 fprintf(stdout, "%ju\n",
4273 (uintmax_t)scsi_8btou64(
4276 fprintf(stdout, "0x%jx\n",
4277 (uintmax_t)scsi_8btou64(
4281 if (num_valid < num_returned) {
4282 starting_offset += num_valid;
4288 fprintf(stderr, "Unknown defect format 0x%x\n",
4295 if (defect_list != NULL)
4303 #endif /* MINIMALISTIC */
4307 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4311 ccb = cam_getccb(device);
4317 #ifndef MINIMALISTIC
4319 mode_sense(struct cam_device *device, int dbd, int pc, int page, int subpage,
4320 int task_attr, int retry_count, int timeout, u_int8_t *data,
4326 ccb = cam_getccb(device);
4329 errx(1, "mode_sense: couldn't allocate CCB");
4331 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4333 scsi_mode_sense_subpage(&ccb->csio,
4334 /* retries */ retry_count,
4336 /* tag_action */ task_attr,
4340 /* subpage */ subpage,
4341 /* param_buf */ data,
4342 /* param_len */ datalen,
4343 /* minimum_cmd_size */ 0,
4344 /* sense_len */ SSD_FULL_SIZE,
4345 /* timeout */ timeout ? timeout : 5000);
4347 if (arglist & CAM_ARG_ERR_RECOVER)
4348 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4350 /* Disable freezing the device queue */
4351 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4353 if (((retval = cam_send_ccb(device, ccb)) < 0)
4354 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4355 if (arglist & CAM_ARG_VERBOSE) {
4356 cam_error_print(device, ccb, CAM_ESF_ALL,
4357 CAM_EPF_ALL, stderr);
4360 cam_close_device(device);
4362 err(1, "error sending mode sense command");
4364 errx(1, "error sending mode sense command");
4371 mode_select(struct cam_device *device, int save_pages, int task_attr,
4372 int retry_count, int timeout, u_int8_t *data, int datalen)
4377 ccb = cam_getccb(device);
4380 errx(1, "mode_select: couldn't allocate CCB");
4382 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4384 scsi_mode_select(&ccb->csio,
4385 /* retries */ retry_count,
4387 /* tag_action */ task_attr,
4388 /* scsi_page_fmt */ 1,
4389 /* save_pages */ save_pages,
4390 /* param_buf */ data,
4391 /* param_len */ datalen,
4392 /* sense_len */ SSD_FULL_SIZE,
4393 /* timeout */ timeout ? timeout : 5000);
4395 if (arglist & CAM_ARG_ERR_RECOVER)
4396 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4398 /* Disable freezing the device queue */
4399 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4401 if (((retval = cam_send_ccb(device, ccb)) < 0)
4402 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4403 if (arglist & CAM_ARG_VERBOSE) {
4404 cam_error_print(device, ccb, CAM_ESF_ALL,
4405 CAM_EPF_ALL, stderr);
4408 cam_close_device(device);
4411 err(1, "error sending mode select command");
4413 errx(1, "error sending mode select command");
4421 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4422 int task_attr, int retry_count, int timeout)
4425 int c, page = -1, subpage = -1, pc = 0;
4426 int binary = 0, dbd = 0, edit = 0, list = 0;
4428 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4443 str_subpage = optarg;
4444 strsep(&str_subpage, ",");
4445 page = strtol(optarg, NULL, 0);
4447 subpage = strtol(str_subpage, NULL, 0);
4451 errx(1, "invalid mode page %d", page);
4453 errx(1, "invalid mode subpage %d", subpage);
4456 pc = strtol(optarg, NULL, 0);
4457 if ((pc < 0) || (pc > 3))
4458 errx(1, "invalid page control field %d", pc);
4465 if (page == -1 && list == 0)
4466 errx(1, "you must specify a mode page!");
4469 mode_list(device, dbd, pc, list > 1, task_attr, retry_count,
4472 mode_edit(device, dbd, pc, page, subpage, edit, binary,
4473 task_attr, retry_count, timeout);
4478 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4479 int task_attr, int retry_count, int timeout)
4482 u_int32_t flags = CAM_DIR_NONE;
4483 u_int8_t *data_ptr = NULL;
4485 u_int8_t atacmd[12];
4486 struct get_hook hook;
4487 int c, data_bytes = 0, valid_bytes;
4493 char *datastr = NULL, *tstr, *resstr = NULL;
4495 int fd_data = 0, fd_res = 0;
4498 ccb = cam_getccb(device);
4501 warnx("scsicmd: error allocating ccb");
4505 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4507 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4511 while (isspace(*tstr) && (*tstr != '\0'))
4513 hook.argc = argc - optind;
4514 hook.argv = argv + optind;
4516 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4519 * Increment optind by the number of arguments the
4520 * encoding routine processed. After each call to
4521 * getopt(3), optind points to the argument that
4522 * getopt should process _next_. In this case,
4523 * that means it points to the first command string
4524 * argument, if there is one. Once we increment
4525 * this, it should point to either the next command
4526 * line argument, or it should be past the end of
4533 while (isspace(*tstr) && (*tstr != '\0'))
4535 hook.argc = argc - optind;
4536 hook.argv = argv + optind;
4538 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4541 * Increment optind by the number of arguments the
4542 * encoding routine processed. After each call to
4543 * getopt(3), optind points to the argument that
4544 * getopt should process _next_. In this case,
4545 * that means it points to the first command string
4546 * argument, if there is one. Once we increment
4547 * this, it should point to either the next command
4548 * line argument, or it should be past the end of
4560 if (arglist & CAM_ARG_CMD_OUT) {
4561 warnx("command must either be "
4562 "read or write, not both");
4564 goto scsicmd_bailout;
4566 arglist |= CAM_ARG_CMD_IN;
4568 data_bytes = strtol(optarg, NULL, 0);
4569 if (data_bytes <= 0) {
4570 warnx("invalid number of input bytes %d",
4573 goto scsicmd_bailout;
4575 hook.argc = argc - optind;
4576 hook.argv = argv + optind;
4579 datastr = cget(&hook, NULL);
4581 * If the user supplied "-" instead of a format, he
4582 * wants the data to be written to stdout.
4584 if ((datastr != NULL)
4585 && (datastr[0] == '-'))
4588 data_ptr = (u_int8_t *)malloc(data_bytes);
4589 if (data_ptr == NULL) {
4590 warnx("can't malloc memory for data_ptr");
4592 goto scsicmd_bailout;
4596 if (arglist & CAM_ARG_CMD_IN) {
4597 warnx("command must either be "
4598 "read or write, not both");
4600 goto scsicmd_bailout;
4602 arglist |= CAM_ARG_CMD_OUT;
4603 flags = CAM_DIR_OUT;
4604 data_bytes = strtol(optarg, NULL, 0);
4605 if (data_bytes <= 0) {
4606 warnx("invalid number of output bytes %d",
4609 goto scsicmd_bailout;
4611 hook.argc = argc - optind;
4612 hook.argv = argv + optind;
4614 datastr = cget(&hook, NULL);
4615 data_ptr = (u_int8_t *)malloc(data_bytes);
4616 if (data_ptr == NULL) {
4617 warnx("can't malloc memory for data_ptr");
4619 goto scsicmd_bailout;
4621 bzero(data_ptr, data_bytes);
4623 * If the user supplied "-" instead of a format, he
4624 * wants the data to be read from stdin.
4626 if ((datastr != NULL)
4627 && (datastr[0] == '-'))
4630 buff_encode_visit(data_ptr, data_bytes, datastr,
4636 hook.argc = argc - optind;
4637 hook.argv = argv + optind;
4639 resstr = cget(&hook, NULL);
4640 if ((resstr != NULL) && (resstr[0] == '-'))
4650 * If fd_data is set, and we're writing to the device, we need to
4651 * read the data the user wants written from stdin.
4653 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4655 int amt_to_read = data_bytes;
4656 u_int8_t *buf_ptr = data_ptr;
4658 for (amt_read = 0; amt_to_read > 0;
4659 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4660 if (amt_read == -1) {
4661 warn("error reading data from stdin");
4663 goto scsicmd_bailout;
4665 amt_to_read -= amt_read;
4666 buf_ptr += amt_read;
4670 if (arglist & CAM_ARG_ERR_RECOVER)
4671 flags |= CAM_PASS_ERR_RECOVER;
4673 /* Disable freezing the device queue */
4674 flags |= CAM_DEV_QFRZDIS;
4678 * This is taken from the SCSI-3 draft spec.
4679 * (T10/1157D revision 0.3)
4680 * The top 3 bits of an opcode are the group code.
4681 * The next 5 bits are the command code.
4682 * Group 0: six byte commands
4683 * Group 1: ten byte commands
4684 * Group 2: ten byte commands
4686 * Group 4: sixteen byte commands
4687 * Group 5: twelve byte commands
4688 * Group 6: vendor specific
4689 * Group 7: vendor specific
4691 switch((cdb[0] >> 5) & 0x7) {
4702 /* computed by buff_encode_visit */
4713 * We should probably use csio_build_visit or something like that
4714 * here, but it's easier to encode arguments as you go. The
4715 * alternative would be skipping the CDB argument and then encoding
4716 * it here, since we've got the data buffer argument by now.
4718 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4720 cam_fill_csio(&ccb->csio,
4721 /*retries*/ retry_count,
4724 /*tag_action*/ task_attr,
4725 /*data_ptr*/ data_ptr,
4726 /*dxfer_len*/ data_bytes,
4727 /*sense_len*/ SSD_FULL_SIZE,
4728 /*cdb_len*/ cdb_len,
4729 /*timeout*/ timeout ? timeout : 5000);
4732 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4734 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4736 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4738 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4740 cam_fill_ataio(&ccb->ataio,
4741 /*retries*/ retry_count,
4745 /*data_ptr*/ data_ptr,
4746 /*dxfer_len*/ data_bytes,
4747 /*timeout*/ timeout ? timeout : 5000);
4750 if (((retval = cam_send_ccb(device, ccb)) < 0)
4751 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4752 const char warnstr[] = "error sending command";
4759 if (arglist & CAM_ARG_VERBOSE) {
4760 cam_error_print(device, ccb, CAM_ESF_ALL,
4761 CAM_EPF_ALL, stderr);
4765 goto scsicmd_bailout;
4768 if (atacmd_len && need_res) {
4770 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4772 fprintf(stdout, "\n");
4775 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4776 ccb->ataio.res.status,
4777 ccb->ataio.res.error,
4778 ccb->ataio.res.lba_low,
4779 ccb->ataio.res.lba_mid,
4780 ccb->ataio.res.lba_high,
4781 ccb->ataio.res.device,
4782 ccb->ataio.res.lba_low_exp,
4783 ccb->ataio.res.lba_mid_exp,
4784 ccb->ataio.res.lba_high_exp,
4785 ccb->ataio.res.sector_count,
4786 ccb->ataio.res.sector_count_exp);
4792 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4794 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4795 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4796 && (arglist & CAM_ARG_CMD_IN)
4797 && (valid_bytes > 0)) {
4799 buff_decode_visit(data_ptr, valid_bytes, datastr,
4801 fprintf(stdout, "\n");
4803 ssize_t amt_written;
4804 int amt_to_write = valid_bytes;
4805 u_int8_t *buf_ptr = data_ptr;
4807 for (amt_written = 0; (amt_to_write > 0) &&
4808 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4809 amt_to_write -= amt_written;
4810 buf_ptr += amt_written;
4812 if (amt_written == -1) {
4813 warn("error writing data to stdout");
4815 goto scsicmd_bailout;
4816 } else if ((amt_written == 0)
4817 && (amt_to_write > 0)) {
4818 warnx("only wrote %u bytes out of %u",
4819 valid_bytes - amt_to_write, valid_bytes);
4826 if ((data_bytes > 0) && (data_ptr != NULL))
4835 camdebug(int argc, char **argv, char *combinedopt)
4838 path_id_t bus = CAM_BUS_WILDCARD;
4839 target_id_t target = CAM_TARGET_WILDCARD;
4840 lun_id_t lun = CAM_LUN_WILDCARD;
4841 char *tstr, *tmpstr = NULL;
4845 bzero(&ccb, sizeof(union ccb));
4847 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4850 arglist |= CAM_ARG_DEBUG_INFO;
4851 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4854 arglist |= CAM_ARG_DEBUG_PERIPH;
4855 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4858 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4859 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4862 arglist |= CAM_ARG_DEBUG_TRACE;
4863 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4866 arglist |= CAM_ARG_DEBUG_XPT;
4867 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4870 arglist |= CAM_ARG_DEBUG_CDB;
4871 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4874 arglist |= CAM_ARG_DEBUG_PROBE;
4875 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4882 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4883 warnx("error opening transport layer device %s", XPT_DEVICE);
4884 warn("%s", XPT_DEVICE);
4891 warnx("you must specify \"off\", \"all\" or a bus,");
4892 warnx("bus:target, or bus:target:lun");
4899 while (isspace(*tstr) && (*tstr != '\0'))
4902 if (strncmp(tstr, "off", 3) == 0) {
4903 ccb.cdbg.flags = CAM_DEBUG_NONE;
4904 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4905 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4906 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4907 } else if (strncmp(tstr, "all", 3) != 0) {
4908 tmpstr = (char *)strtok(tstr, ":");
4909 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4910 bus = strtol(tmpstr, NULL, 0);
4911 arglist |= CAM_ARG_BUS;
4912 tmpstr = (char *)strtok(NULL, ":");
4913 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4914 target = strtol(tmpstr, NULL, 0);
4915 arglist |= CAM_ARG_TARGET;
4916 tmpstr = (char *)strtok(NULL, ":");
4917 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4918 lun = strtol(tmpstr, NULL, 0);
4919 arglist |= CAM_ARG_LUN;
4924 warnx("you must specify \"all\", \"off\", or a bus,");
4925 warnx("bus:target, or bus:target:lun to debug");
4931 ccb.ccb_h.func_code = XPT_DEBUG;
4932 ccb.ccb_h.path_id = bus;
4933 ccb.ccb_h.target_id = target;
4934 ccb.ccb_h.target_lun = lun;
4936 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4937 warn("CAMIOCOMMAND ioctl failed");
4942 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4943 CAM_FUNC_NOTAVAIL) {
4944 warnx("CAM debugging not available");
4945 warnx("you need to put options CAMDEBUG in"
4946 " your kernel config file!");
4948 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4950 warnx("XPT_DEBUG CCB failed with status %#x",
4954 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4956 "Debugging turned off\n");
4959 "Debugging enabled for "
4961 bus, target, (uintmax_t)lun);
4972 tagcontrol(struct cam_device *device, int argc, char **argv,
4982 ccb = cam_getccb(device);
4985 warnx("tagcontrol: error allocating ccb");
4989 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4992 numtags = strtol(optarg, NULL, 0);
4994 warnx("tag count %d is < 0", numtags);
4996 goto tagcontrol_bailout;
5007 cam_path_string(device, pathstr, sizeof(pathstr));
5010 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
5011 ccb->ccb_h.func_code = XPT_REL_SIMQ;
5012 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5013 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5014 ccb->crs.openings = numtags;
5017 if (cam_send_ccb(device, ccb) < 0) {
5018 perror("error sending XPT_REL_SIMQ CCB");
5020 goto tagcontrol_bailout;
5023 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5024 warnx("XPT_REL_SIMQ CCB failed");
5025 cam_error_print(device, ccb, CAM_ESF_ALL,
5026 CAM_EPF_ALL, stderr);
5028 goto tagcontrol_bailout;
5033 fprintf(stdout, "%stagged openings now %d\n",
5034 pathstr, ccb->crs.openings);
5037 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5039 ccb->ccb_h.func_code = XPT_GDEV_STATS;
5041 if (cam_send_ccb(device, ccb) < 0) {
5042 perror("error sending XPT_GDEV_STATS CCB");
5044 goto tagcontrol_bailout;
5047 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5048 warnx("XPT_GDEV_STATS CCB failed");
5049 cam_error_print(device, ccb, CAM_ESF_ALL,
5050 CAM_EPF_ALL, stderr);
5052 goto tagcontrol_bailout;
5055 if (arglist & CAM_ARG_VERBOSE) {
5056 fprintf(stdout, "%s", pathstr);
5057 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5058 fprintf(stdout, "%s", pathstr);
5059 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5060 fprintf(stdout, "%s", pathstr);
5061 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5062 fprintf(stdout, "%s", pathstr);
5063 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5064 fprintf(stdout, "%s", pathstr);
5065 fprintf(stdout, "held %d\n", ccb->cgds.held);
5066 fprintf(stdout, "%s", pathstr);
5067 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5068 fprintf(stdout, "%s", pathstr);
5069 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5072 fprintf(stdout, "%s", pathstr);
5073 fprintf(stdout, "device openings: ");
5075 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5076 ccb->cgds.dev_active);
5086 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5090 cam_path_string(device, pathstr, sizeof(pathstr));
5092 if (cts->transport == XPORT_SPI) {
5093 struct ccb_trans_settings_spi *spi =
5094 &cts->xport_specific.spi;
5096 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5098 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5101 if (spi->sync_offset != 0) {
5104 freq = scsi_calc_syncsrate(spi->sync_period);
5105 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5106 pathstr, freq / 1000, freq % 1000);
5110 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5111 fprintf(stdout, "%soffset: %d\n", pathstr,
5115 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5116 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5117 (0x01 << spi->bus_width) * 8);
5120 if (spi->valid & CTS_SPI_VALID_DISC) {
5121 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5122 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5123 "enabled" : "disabled");
5126 if (cts->transport == XPORT_FC) {
5127 struct ccb_trans_settings_fc *fc =
5128 &cts->xport_specific.fc;
5130 if (fc->valid & CTS_FC_VALID_WWNN)
5131 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5132 (long long) fc->wwnn);
5133 if (fc->valid & CTS_FC_VALID_WWPN)
5134 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5135 (long long) fc->wwpn);
5136 if (fc->valid & CTS_FC_VALID_PORT)
5137 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5138 if (fc->valid & CTS_FC_VALID_SPEED)
5139 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5140 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5142 if (cts->transport == XPORT_SAS) {
5143 struct ccb_trans_settings_sas *sas =
5144 &cts->xport_specific.sas;
5146 if (sas->valid & CTS_SAS_VALID_SPEED)
5147 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5148 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5150 if (cts->transport == XPORT_ATA) {
5151 struct ccb_trans_settings_pata *pata =
5152 &cts->xport_specific.ata;
5154 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5155 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5156 ata_mode2string(pata->mode));
5158 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5159 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5162 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5163 fprintf(stdout, "%sPIO transaction length: %d\n",
5164 pathstr, pata->bytecount);
5167 if (cts->transport == XPORT_SATA) {
5168 struct ccb_trans_settings_sata *sata =
5169 &cts->xport_specific.sata;
5171 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5172 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5175 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5176 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5177 ata_mode2string(sata->mode));
5179 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5180 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5183 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5184 fprintf(stdout, "%sPIO transaction length: %d\n",
5185 pathstr, sata->bytecount);
5187 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5188 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5191 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5192 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5195 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5196 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5200 if (cts->protocol == PROTO_ATA) {
5201 struct ccb_trans_settings_ata *ata=
5202 &cts->proto_specific.ata;
5204 if (ata->valid & CTS_ATA_VALID_TQ) {
5205 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5206 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5207 "enabled" : "disabled");
5210 if (cts->protocol == PROTO_SCSI) {
5211 struct ccb_trans_settings_scsi *scsi=
5212 &cts->proto_specific.scsi;
5214 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5215 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5216 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5217 "enabled" : "disabled");
5221 if (cts->protocol == PROTO_NVME) {
5222 struct ccb_trans_settings_nvme *nvmex =
5223 &cts->xport_specific.nvme;
5225 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5226 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5227 NVME_MAJOR(nvmex->spec),
5228 NVME_MINOR(nvmex->spec));
5230 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5231 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5232 nvmex->lanes, nvmex->max_lanes);
5233 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5234 nvmex->speed, nvmex->max_speed);
5241 * Get a path inquiry CCB for the specified device.
5244 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5249 ccb = cam_getccb(device);
5251 warnx("get_cpi: couldn't allocate CCB");
5254 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5255 ccb->ccb_h.func_code = XPT_PATH_INQ;
5256 if (cam_send_ccb(device, ccb) < 0) {
5257 warn("get_cpi: error sending Path Inquiry CCB");
5258 if (arglist & CAM_ARG_VERBOSE)
5259 cam_error_print(device, ccb, CAM_ESF_ALL,
5260 CAM_EPF_ALL, stderr);
5262 goto get_cpi_bailout;
5264 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5265 if (arglist & CAM_ARG_VERBOSE)
5266 cam_error_print(device, ccb, CAM_ESF_ALL,
5267 CAM_EPF_ALL, stderr);
5269 goto get_cpi_bailout;
5271 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5279 * Get a get device CCB for the specified device.
5282 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5287 ccb = cam_getccb(device);
5289 warnx("get_cgd: couldn't allocate CCB");
5292 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5293 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5294 if (cam_send_ccb(device, ccb) < 0) {
5295 warn("get_cgd: error sending Path Inquiry CCB");
5296 if (arglist & CAM_ARG_VERBOSE)
5297 cam_error_print(device, ccb, CAM_ESF_ALL,
5298 CAM_EPF_ALL, stderr);
5300 goto get_cgd_bailout;
5302 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5303 if (arglist & CAM_ARG_VERBOSE)
5304 cam_error_print(device, ccb, CAM_ESF_ALL,
5305 CAM_EPF_ALL, stderr);
5307 goto get_cgd_bailout;
5309 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5317 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5321 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5322 int timeout, int verbosemode)
5324 union ccb *ccb = NULL;
5325 struct scsi_vpd_supported_page_list sup_pages;
5329 ccb = cam_getccb(dev);
5331 warn("Unable to allocate CCB");
5336 /* cam_getccb cleans up the header, caller has to zero the payload */
5337 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5339 bzero(&sup_pages, sizeof(sup_pages));
5341 scsi_inquiry(&ccb->csio,
5342 /*retries*/ retry_count,
5344 /* tag_action */ MSG_SIMPLE_Q_TAG,
5345 /* inq_buf */ (u_int8_t *)&sup_pages,
5346 /* inq_len */ sizeof(sup_pages),
5348 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5349 /* sense_len */ SSD_FULL_SIZE,
5350 /* timeout */ timeout ? timeout : 5000);
5352 /* Disable freezing the device queue */
5353 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5355 if (retry_count != 0)
5356 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5358 if (cam_send_ccb(dev, ccb) < 0) {
5365 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5366 if (verbosemode != 0)
5367 cam_error_print(dev, ccb, CAM_ESF_ALL,
5368 CAM_EPF_ALL, stderr);
5373 for (i = 0; i < sup_pages.length; i++) {
5374 if (sup_pages.list[i] == page_id) {
5387 * devtype is filled in with the type of device.
5388 * Returns 0 for success, non-zero for failure.
5391 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5392 int verbosemode, camcontrol_devtype *devtype)
5394 struct ccb_getdev cgd;
5397 retval = get_cgd(dev, &cgd);
5401 switch (cgd.protocol) {
5407 *devtype = CC_DT_ATA;
5409 break; /*NOTREACHED*/
5411 *devtype = CC_DT_UNKNOWN;
5413 break; /*NOTREACHED*/
5417 * Check for the ATA Information VPD page (0x89). If this is an
5418 * ATA device behind a SCSI to ATA translation layer, this VPD page
5419 * should be present.
5421 * If that VPD page isn't present, or we get an error back from the
5422 * INQUIRY command, we'll just treat it as a normal SCSI device.
5424 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5425 timeout, verbosemode);
5427 *devtype = CC_DT_ATA_BEHIND_SCSI;
5429 *devtype = CC_DT_SCSI;
5438 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5439 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5440 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5441 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5442 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5443 int is48bit, camcontrol_devtype devtype)
5447 if (devtype == CC_DT_ATA) {
5448 cam_fill_ataio(&ccb->ataio,
5449 /*retries*/ retry_count,
5452 /*tag_action*/ tag_action,
5453 /*data_ptr*/ data_ptr,
5454 /*dxfer_len*/ dxfer_len,
5455 /*timeout*/ timeout);
5456 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5457 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5460 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5463 if (auxiliary != 0) {
5464 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5465 ccb->ataio.aux = auxiliary;
5468 if (ata_flags & AP_FLAG_CHK_COND)
5469 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5471 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5472 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5473 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5474 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5476 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5477 protocol |= AP_EXTEND;
5479 retval = scsi_ata_pass(&ccb->csio,
5480 /*retries*/ retry_count,
5483 /*tag_action*/ tag_action,
5484 /*protocol*/ protocol,
5485 /*ata_flags*/ ata_flags,
5486 /*features*/ features,
5487 /*sector_count*/ sector_count,
5489 /*command*/ command,
5492 /*auxiliary*/ auxiliary,
5494 /*data_ptr*/ data_ptr,
5495 /*dxfer_len*/ dxfer_len,
5496 /*cdb_storage*/ cdb_storage,
5497 /*cdb_storage_len*/ cdb_storage_len,
5498 /*minimum_cmd_size*/ 0,
5499 /*sense_len*/ sense_len,
5500 /*timeout*/ timeout);
5507 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5508 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5512 switch (ccb->ccb_h.func_code) {
5515 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5518 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5519 * or 16 byte, and need to see what
5521 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5522 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5524 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5525 if ((opcode != ATA_PASS_12)
5526 && (opcode != ATA_PASS_16)) {
5528 warnx("%s: unsupported opcode %02x", __func__, opcode);
5532 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5534 /* Note: the _ccb() variant returns 0 for an error */
5541 switch (error_code) {
5542 case SSD_DESC_CURRENT_ERROR:
5543 case SSD_DESC_DEFERRED_ERROR: {
5544 struct scsi_sense_data_desc *sense;
5545 struct scsi_sense_ata_ret_desc *desc;
5548 sense = (struct scsi_sense_data_desc *)
5549 &ccb->csio.sense_data;
5551 desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len -
5552 ccb->csio.sense_resid, SSD_DESC_ATA);
5553 if (desc_ptr == NULL) {
5554 cam_error_print(dev, ccb, CAM_ESF_ALL,
5555 CAM_EPF_ALL, stderr);
5559 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5561 *error = desc->error;
5562 *count = (desc->count_15_8 << 8) |
5564 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5565 ((uint64_t)desc->lba_39_32 << 32) |
5566 ((uint64_t)desc->lba_31_24 << 24) |
5567 (desc->lba_23_16 << 16) |
5568 (desc->lba_15_8 << 8) |
5570 *device = desc->device;
5571 *status = desc->status;
5574 * If the extend bit isn't set, the result is for a
5575 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5576 * command without the extend bit set. This means
5577 * that the device is supposed to return 28-bit
5578 * status. The count field is only 8 bits, and the
5579 * LBA field is only 8 bits.
5581 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5587 case SSD_CURRENT_ERROR:
5588 case SSD_DEFERRED_ERROR: {
5590 struct scsi_sense_data_fixed *sense;
5593 * XXX KDM need to support fixed sense data.
5595 warnx("%s: Fixed sense data not supported yet",
5599 break; /*NOTREACHED*/
5610 struct ata_res *res;
5613 * In this case, we have an ATA command, and we need to
5614 * fill in the requested values from the result register
5617 res = &ccb->ataio.res;
5618 *error = res->error;
5619 *status = res->status;
5620 *device = res->device;
5621 *count = res->sector_count;
5622 *lba = (res->lba_high << 16) |
5623 (res->lba_mid << 8) |
5625 if (res->flags & CAM_ATAIO_48BIT) {
5626 *count |= (res->sector_count_exp << 8);
5627 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5628 ((uint64_t)res->lba_mid_exp << 32) |
5629 ((uint64_t)res->lba_high_exp << 40);
5631 *lba |= (res->device & 0xf) << 24;
5644 cpi_print(struct ccb_pathinq *cpi)
5646 char adapter_str[1024];
5649 snprintf(adapter_str, sizeof(adapter_str),
5650 "%s%d:", cpi->dev_name, cpi->unit_number);
5652 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5655 for (i = 1; i < UINT8_MAX; i = i << 1) {
5658 if ((i & cpi->hba_inquiry) == 0)
5661 fprintf(stdout, "%s supports ", adapter_str);
5665 str = "MDP message";
5668 str = "32 bit wide SCSI";
5671 str = "16 bit wide SCSI";
5674 str = "SDTR message";
5677 str = "linked CDBs";
5680 str = "tag queue messages";
5683 str = "soft reset alternative";
5686 str = "SATA Port Multiplier";
5689 str = "unknown PI bit set";
5692 fprintf(stdout, "%s\n", str);
5695 for (i = 1; i < UINT32_MAX; i = i << 1) {
5698 if ((i & cpi->hba_misc) == 0)
5701 fprintf(stdout, "%s ", adapter_str);
5705 str = "can understand ata_ext requests";
5708 str = "64bit extended LUNs supported";
5711 str = "bus scans from high ID to low ID";
5714 str = "removable devices not included in scan";
5716 case PIM_NOINITIATOR:
5717 str = "initiator role not supported";
5719 case PIM_NOBUSRESET:
5720 str = "user has disabled initial BUS RESET or"
5721 " controller is in target/mixed mode";
5724 str = "do not send 6-byte commands";
5727 str = "scan bus sequentially";
5730 str = "unmapped I/O supported";
5733 str = "does its own scanning";
5736 str = "unknown PIM bit set";
5739 fprintf(stdout, "%s\n", str);
5742 for (i = 1; i < UINT16_MAX; i = i << 1) {
5745 if ((i & cpi->target_sprt) == 0)
5748 fprintf(stdout, "%s supports ", adapter_str);
5751 str = "target mode processor mode";
5754 str = "target mode phase cog. mode";
5756 case PIT_DISCONNECT:
5757 str = "disconnects in target mode";
5760 str = "terminate I/O message in target mode";
5763 str = "group 6 commands in target mode";
5766 str = "group 7 commands in target mode";
5769 str = "unknown PIT bit set";
5773 fprintf(stdout, "%s\n", str);
5775 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5777 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5779 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5781 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5782 adapter_str, cpi->hpath_id);
5783 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5785 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5786 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5787 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5788 adapter_str, cpi->hba_vendor);
5789 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5790 adapter_str, cpi->hba_device);
5791 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5792 adapter_str, cpi->hba_subvendor);
5793 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5794 adapter_str, cpi->hba_subdevice);
5795 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5796 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5797 if (cpi->base_transfer_speed > 1000)
5798 fprintf(stdout, "%d.%03dMB/sec\n",
5799 cpi->base_transfer_speed / 1000,
5800 cpi->base_transfer_speed % 1000);
5802 fprintf(stdout, "%dKB/sec\n",
5803 (cpi->base_transfer_speed % 1000) * 1000);
5804 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5805 adapter_str, cpi->maxio);
5809 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5810 struct ccb_trans_settings *cts)
5816 ccb = cam_getccb(device);
5819 warnx("get_print_cts: error allocating ccb");
5823 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5825 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5827 if (user_settings == 0)
5828 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5830 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5832 if (cam_send_ccb(device, ccb) < 0) {
5833 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5834 if (arglist & CAM_ARG_VERBOSE)
5835 cam_error_print(device, ccb, CAM_ESF_ALL,
5836 CAM_EPF_ALL, stderr);
5838 goto get_print_cts_bailout;
5841 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5842 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5843 if (arglist & CAM_ARG_VERBOSE)
5844 cam_error_print(device, ccb, CAM_ESF_ALL,
5845 CAM_EPF_ALL, stderr);
5847 goto get_print_cts_bailout;
5851 cts_print(device, &ccb->cts);
5854 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5856 get_print_cts_bailout:
5864 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
5865 int timeout, int argc, char **argv, char *combinedopt)
5869 int user_settings = 0;
5871 int disc_enable = -1, tag_enable = -1;
5874 double syncrate = -1;
5877 int change_settings = 0, send_tur = 0;
5878 struct ccb_pathinq cpi;
5880 ccb = cam_getccb(device);
5882 warnx("ratecontrol: error allocating ccb");
5885 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5894 if (strncasecmp(optarg, "enable", 6) == 0)
5896 else if (strncasecmp(optarg, "disable", 7) == 0)
5899 warnx("-D argument \"%s\" is unknown", optarg);
5901 goto ratecontrol_bailout;
5903 change_settings = 1;
5906 mode = ata_string2mode(optarg);
5908 warnx("unknown mode '%s'", optarg);
5910 goto ratecontrol_bailout;
5912 change_settings = 1;
5915 offset = strtol(optarg, NULL, 0);
5917 warnx("offset value %d is < 0", offset);
5919 goto ratecontrol_bailout;
5921 change_settings = 1;
5927 syncrate = atof(optarg);
5929 warnx("sync rate %f is < 0", syncrate);
5931 goto ratecontrol_bailout;
5933 change_settings = 1;
5936 if (strncasecmp(optarg, "enable", 6) == 0)
5938 else if (strncasecmp(optarg, "disable", 7) == 0)
5941 warnx("-T argument \"%s\" is unknown", optarg);
5943 goto ratecontrol_bailout;
5945 change_settings = 1;
5951 bus_width = strtol(optarg, NULL, 0);
5952 if (bus_width < 0) {
5953 warnx("bus width %d is < 0", bus_width);
5955 goto ratecontrol_bailout;
5957 change_settings = 1;
5963 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5965 * Grab path inquiry information, so we can determine whether
5966 * or not the initiator is capable of the things that the user
5969 ccb->ccb_h.func_code = XPT_PATH_INQ;
5970 if (cam_send_ccb(device, ccb) < 0) {
5971 perror("error sending XPT_PATH_INQ CCB");
5972 if (arglist & CAM_ARG_VERBOSE) {
5973 cam_error_print(device, ccb, CAM_ESF_ALL,
5974 CAM_EPF_ALL, stderr);
5977 goto ratecontrol_bailout;
5979 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5980 warnx("XPT_PATH_INQ CCB failed");
5981 if (arglist & CAM_ARG_VERBOSE) {
5982 cam_error_print(device, ccb, CAM_ESF_ALL,
5983 CAM_EPF_ALL, stderr);
5986 goto ratecontrol_bailout;
5988 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5989 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5991 fprintf(stdout, "%s parameters:\n",
5992 user_settings ? "User" : "Current");
5994 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5996 goto ratecontrol_bailout;
5998 if (arglist & CAM_ARG_VERBOSE)
6001 if (change_settings) {
6002 int didsettings = 0;
6003 struct ccb_trans_settings_spi *spi = NULL;
6004 struct ccb_trans_settings_pata *pata = NULL;
6005 struct ccb_trans_settings_sata *sata = NULL;
6006 struct ccb_trans_settings_ata *ata = NULL;
6007 struct ccb_trans_settings_scsi *scsi = NULL;
6009 if (ccb->cts.transport == XPORT_SPI)
6010 spi = &ccb->cts.xport_specific.spi;
6011 if (ccb->cts.transport == XPORT_ATA)
6012 pata = &ccb->cts.xport_specific.ata;
6013 if (ccb->cts.transport == XPORT_SATA)
6014 sata = &ccb->cts.xport_specific.sata;
6015 if (ccb->cts.protocol == PROTO_ATA)
6016 ata = &ccb->cts.proto_specific.ata;
6017 if (ccb->cts.protocol == PROTO_SCSI)
6018 scsi = &ccb->cts.proto_specific.scsi;
6019 ccb->cts.xport_specific.valid = 0;
6020 ccb->cts.proto_specific.valid = 0;
6021 if (spi && disc_enable != -1) {
6022 spi->valid |= CTS_SPI_VALID_DISC;
6023 if (disc_enable == 0)
6024 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6026 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6029 if (tag_enable != -1) {
6030 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6031 warnx("HBA does not support tagged queueing, "
6032 "so you cannot modify tag settings");
6034 goto ratecontrol_bailout;
6037 ata->valid |= CTS_SCSI_VALID_TQ;
6038 if (tag_enable == 0)
6039 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6041 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6044 scsi->valid |= CTS_SCSI_VALID_TQ;
6045 if (tag_enable == 0)
6046 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6048 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6052 if (spi && offset != -1) {
6053 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6054 warnx("HBA is not capable of changing offset");
6056 goto ratecontrol_bailout;
6058 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6059 spi->sync_offset = offset;
6062 if (spi && syncrate != -1) {
6063 int prelim_sync_period;
6065 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6066 warnx("HBA is not capable of changing "
6069 goto ratecontrol_bailout;
6071 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6073 * The sync rate the user gives us is in MHz.
6074 * We need to translate it into KHz for this
6079 * Next, we calculate a "preliminary" sync period
6080 * in tenths of a nanosecond.
6083 prelim_sync_period = 0;
6085 prelim_sync_period = 10000000 / syncrate;
6087 scsi_calc_syncparam(prelim_sync_period);
6090 if (sata && syncrate != -1) {
6091 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6092 warnx("HBA is not capable of changing "
6095 goto ratecontrol_bailout;
6097 if (!user_settings) {
6098 warnx("You can modify only user rate "
6099 "settings for SATA");
6101 goto ratecontrol_bailout;
6103 sata->revision = ata_speed2revision(syncrate * 100);
6104 if (sata->revision < 0) {
6105 warnx("Invalid rate %f", syncrate);
6107 goto ratecontrol_bailout;
6109 sata->valid |= CTS_SATA_VALID_REVISION;
6112 if ((pata || sata) && mode != -1) {
6113 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6114 warnx("HBA is not capable of changing "
6117 goto ratecontrol_bailout;
6119 if (!user_settings) {
6120 warnx("You can modify only user mode "
6121 "settings for ATA/SATA");
6123 goto ratecontrol_bailout;
6127 pata->valid |= CTS_ATA_VALID_MODE;
6130 sata->valid |= CTS_SATA_VALID_MODE;
6135 * The bus_width argument goes like this:
6139 * Therefore, if you shift the number of bits given on the
6140 * command line right by 4, you should get the correct
6143 if (spi && bus_width != -1) {
6145 * We might as well validate things here with a
6146 * decipherable error message, rather than what
6147 * will probably be an indecipherable error message
6148 * by the time it gets back to us.
6150 if ((bus_width == 16)
6151 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6152 warnx("HBA does not support 16 bit bus width");
6154 goto ratecontrol_bailout;
6155 } else if ((bus_width == 32)
6156 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6157 warnx("HBA does not support 32 bit bus width");
6159 goto ratecontrol_bailout;
6160 } else if ((bus_width != 8)
6161 && (bus_width != 16)
6162 && (bus_width != 32)) {
6163 warnx("Invalid bus width %d", bus_width);
6165 goto ratecontrol_bailout;
6167 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6168 spi->bus_width = bus_width >> 4;
6171 if (didsettings == 0) {
6172 goto ratecontrol_bailout;
6174 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6175 if (cam_send_ccb(device, ccb) < 0) {
6176 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
6177 if (arglist & CAM_ARG_VERBOSE) {
6178 cam_error_print(device, ccb, CAM_ESF_ALL,
6179 CAM_EPF_ALL, stderr);
6182 goto ratecontrol_bailout;
6184 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6185 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6186 if (arglist & CAM_ARG_VERBOSE) {
6187 cam_error_print(device, ccb, CAM_ESF_ALL,
6188 CAM_EPF_ALL, stderr);
6191 goto ratecontrol_bailout;
6195 retval = testunitready(device, task_attr, retry_count, timeout,
6196 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6198 * If the TUR didn't succeed, just bail.
6202 fprintf(stderr, "Test Unit Ready failed\n");
6203 goto ratecontrol_bailout;
6206 if ((change_settings || send_tur) && !quiet &&
6207 (ccb->cts.transport == XPORT_ATA ||
6208 ccb->cts.transport == XPORT_SATA || send_tur)) {
6209 fprintf(stdout, "New parameters:\n");
6210 retval = get_print_cts(device, user_settings, 0, NULL);
6213 ratecontrol_bailout:
6219 scsiformat(struct cam_device *device, int argc, char **argv,
6220 char *combinedopt, int task_attr, int retry_count, int timeout)
6224 int ycount = 0, quiet = 0;
6225 int error = 0, retval = 0;
6226 int use_timeout = 10800 * 1000;
6228 struct format_defect_list_header fh;
6229 u_int8_t *data_ptr = NULL;
6230 u_int32_t dxfer_len = 0;
6232 int num_warnings = 0;
6235 ccb = cam_getccb(device);
6238 warnx("scsiformat: error allocating ccb");
6242 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6244 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6265 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6266 "following device:\n");
6268 error = scsidoinquiry(device, argc, argv, combinedopt,
6269 task_attr, retry_count, timeout);
6272 warnx("scsiformat: error sending inquiry");
6273 goto scsiformat_bailout;
6278 if (!get_confirmation()) {
6280 goto scsiformat_bailout;
6285 use_timeout = timeout;
6288 fprintf(stdout, "Current format timeout is %d seconds\n",
6289 use_timeout / 1000);
6293 * If the user hasn't disabled questions and didn't specify a
6294 * timeout on the command line, ask them if they want the current
6298 && (timeout == 0)) {
6300 int new_timeout = 0;
6302 fprintf(stdout, "Enter new timeout in seconds or press\n"
6303 "return to keep the current timeout [%d] ",
6304 use_timeout / 1000);
6306 if (fgets(str, sizeof(str), stdin) != NULL) {
6308 new_timeout = atoi(str);
6311 if (new_timeout != 0) {
6312 use_timeout = new_timeout * 1000;
6313 fprintf(stdout, "Using new timeout value %d\n",
6314 use_timeout / 1000);
6319 * Keep this outside the if block below to silence any unused
6320 * variable warnings.
6322 bzero(&fh, sizeof(fh));
6325 * If we're in immediate mode, we've got to include the format
6328 if (immediate != 0) {
6329 fh.byte2 = FU_DLH_IMMED;
6330 data_ptr = (u_int8_t *)&fh;
6331 dxfer_len = sizeof(fh);
6332 byte2 = FU_FMT_DATA;
6333 } else if (quiet == 0) {
6334 fprintf(stdout, "Formatting...");
6338 scsi_format_unit(&ccb->csio,
6339 /* retries */ retry_count,
6341 /* tag_action */ task_attr,
6344 /* data_ptr */ data_ptr,
6345 /* dxfer_len */ dxfer_len,
6346 /* sense_len */ SSD_FULL_SIZE,
6347 /* timeout */ use_timeout);
6349 /* Disable freezing the device queue */
6350 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6352 if (arglist & CAM_ARG_ERR_RECOVER)
6353 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6355 if (((retval = cam_send_ccb(device, ccb)) < 0)
6356 || ((immediate == 0)
6357 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6358 const char errstr[] = "error sending format command";
6365 if (arglist & CAM_ARG_VERBOSE) {
6366 cam_error_print(device, ccb, CAM_ESF_ALL,
6367 CAM_EPF_ALL, stderr);
6370 goto scsiformat_bailout;
6374 * If we ran in non-immediate mode, we already checked for errors
6375 * above and printed out any necessary information. If we're in
6376 * immediate mode, we need to loop through and get status
6377 * information periodically.
6379 if (immediate == 0) {
6381 fprintf(stdout, "Format Complete\n");
6383 goto scsiformat_bailout;
6390 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6393 * There's really no need to do error recovery or
6394 * retries here, since we're just going to sit in a
6395 * loop and wait for the device to finish formatting.
6397 scsi_test_unit_ready(&ccb->csio,
6400 /* tag_action */ task_attr,
6401 /* sense_len */ SSD_FULL_SIZE,
6402 /* timeout */ 5000);
6404 /* Disable freezing the device queue */
6405 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6407 retval = cam_send_ccb(device, ccb);
6410 * If we get an error from the ioctl, bail out. SCSI
6411 * errors are expected.
6414 warn("error sending CAMIOCOMMAND ioctl");
6415 if (arglist & CAM_ARG_VERBOSE) {
6416 cam_error_print(device, ccb, CAM_ESF_ALL,
6417 CAM_EPF_ALL, stderr);
6420 goto scsiformat_bailout;
6423 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6425 if ((status != CAM_REQ_CMP)
6426 && (status == CAM_SCSI_STATUS_ERROR)
6427 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6428 struct scsi_sense_data *sense;
6429 int error_code, sense_key, asc, ascq;
6431 sense = &ccb->csio.sense_data;
6432 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6433 ccb->csio.sense_resid, &error_code, &sense_key,
6434 &asc, &ascq, /*show_errors*/ 1);
6437 * According to the SCSI-2 and SCSI-3 specs, a
6438 * drive that is in the middle of a format should
6439 * return NOT READY with an ASC of "logical unit
6440 * not ready, format in progress". The sense key
6441 * specific bytes will then be a progress indicator.
6443 if ((sense_key == SSD_KEY_NOT_READY)
6444 && (asc == 0x04) && (ascq == 0x04)) {
6447 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6448 ccb->csio.sense_resid, sks) == 0)
6451 u_int64_t percentage;
6453 val = scsi_2btoul(&sks[1]);
6454 percentage = 10000ull * val;
6457 "\rFormatting: %ju.%02u %% "
6459 (uintmax_t)(percentage /
6461 (unsigned)((percentage /
6465 } else if ((quiet == 0)
6466 && (++num_warnings <= 1)) {
6467 warnx("Unexpected SCSI Sense Key "
6468 "Specific value returned "
6470 scsi_sense_print(device, &ccb->csio,
6472 warnx("Unable to print status "
6473 "information, but format will "
6475 warnx("will exit when format is "
6480 warnx("Unexpected SCSI error during format");
6481 cam_error_print(device, ccb, CAM_ESF_ALL,
6482 CAM_EPF_ALL, stderr);
6484 goto scsiformat_bailout;
6487 } else if (status != CAM_REQ_CMP) {
6488 warnx("Unexpected CAM status %#x", status);
6489 if (arglist & CAM_ARG_VERBOSE)
6490 cam_error_print(device, ccb, CAM_ESF_ALL,
6491 CAM_EPF_ALL, stderr);
6493 goto scsiformat_bailout;
6496 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6499 fprintf(stdout, "\nFormat Complete\n");
6509 scsisanitize(struct cam_device *device, int argc, char **argv,
6510 char *combinedopt, int task_attr, int retry_count, int timeout)
6513 u_int8_t action = 0;
6515 int ycount = 0, quiet = 0;
6516 int error = 0, retval = 0;
6517 int use_timeout = 10800 * 1000;
6523 const char *pattern = NULL;
6524 u_int8_t *data_ptr = NULL;
6525 u_int32_t dxfer_len = 0;
6527 int num_warnings = 0;
6530 ccb = cam_getccb(device);
6533 warnx("scsisanitize: error allocating ccb");
6537 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6539 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6542 if (strcasecmp(optarg, "overwrite") == 0)
6543 action = SSZ_SERVICE_ACTION_OVERWRITE;
6544 else if (strcasecmp(optarg, "block") == 0)
6545 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6546 else if (strcasecmp(optarg, "crypto") == 0)
6547 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6548 else if (strcasecmp(optarg, "exitfailure") == 0)
6549 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6551 warnx("invalid service operation \"%s\"",
6554 goto scsisanitize_bailout;
6558 passes = strtol(optarg, NULL, 0);
6559 if (passes < 1 || passes > 31) {
6560 warnx("invalid passes value %d", passes);
6562 goto scsisanitize_bailout;
6593 warnx("an action is required");
6595 goto scsisanitize_bailout;
6596 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6597 struct scsi_sanitize_parameter_list *pl;
6601 if (pattern == NULL) {
6602 warnx("overwrite action requires -P argument");
6604 goto scsisanitize_bailout;
6606 fd = open(pattern, O_RDONLY);
6608 warn("cannot open pattern file %s", pattern);
6610 goto scsisanitize_bailout;
6612 if (fstat(fd, &sb) < 0) {
6613 warn("cannot stat pattern file %s", pattern);
6615 goto scsisanitize_bailout;
6618 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6619 warnx("pattern file size exceeds maximum value %d",
6620 SSZPL_MAX_PATTERN_LENGTH);
6622 goto scsisanitize_bailout;
6624 dxfer_len = sizeof(*pl) + sz;
6625 data_ptr = calloc(1, dxfer_len);
6626 if (data_ptr == NULL) {
6627 warnx("cannot allocate parameter list buffer");
6629 goto scsisanitize_bailout;
6632 amt = read(fd, data_ptr + sizeof(*pl), sz);
6634 warn("cannot read pattern file");
6636 goto scsisanitize_bailout;
6637 } else if (amt != sz) {
6638 warnx("short pattern file read");
6640 goto scsisanitize_bailout;
6643 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6649 pl->byte1 |= SSZPL_INVERT;
6650 scsi_ulto2b(sz, pl->length);
6656 else if (invert != 0)
6658 else if (pattern != NULL)
6663 warnx("%s argument only valid with overwrite "
6666 goto scsisanitize_bailout;
6671 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6672 "following device:\n");
6674 error = scsidoinquiry(device, argc, argv, combinedopt,
6675 task_attr, retry_count, timeout);
6678 warnx("scsisanitize: error sending inquiry");
6679 goto scsisanitize_bailout;
6684 if (!get_confirmation()) {
6686 goto scsisanitize_bailout;
6691 use_timeout = timeout;
6694 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6695 use_timeout / 1000);
6699 * If the user hasn't disabled questions and didn't specify a
6700 * timeout on the command line, ask them if they want the current
6704 && (timeout == 0)) {
6706 int new_timeout = 0;
6708 fprintf(stdout, "Enter new timeout in seconds or press\n"
6709 "return to keep the current timeout [%d] ",
6710 use_timeout / 1000);
6712 if (fgets(str, sizeof(str), stdin) != NULL) {
6714 new_timeout = atoi(str);
6717 if (new_timeout != 0) {
6718 use_timeout = new_timeout * 1000;
6719 fprintf(stdout, "Using new timeout value %d\n",
6720 use_timeout / 1000);
6726 byte2 |= SSZ_UNRESTRICTED_EXIT;
6730 scsi_sanitize(&ccb->csio,
6731 /* retries */ retry_count,
6733 /* tag_action */ task_attr,
6736 /* data_ptr */ data_ptr,
6737 /* dxfer_len */ dxfer_len,
6738 /* sense_len */ SSD_FULL_SIZE,
6739 /* timeout */ use_timeout);
6741 /* Disable freezing the device queue */
6742 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6744 if (arglist & CAM_ARG_ERR_RECOVER)
6745 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6747 if (cam_send_ccb(device, ccb) < 0) {
6748 warn("error sending sanitize command");
6750 goto scsisanitize_bailout;
6753 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6754 struct scsi_sense_data *sense;
6755 int error_code, sense_key, asc, ascq;
6757 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6758 CAM_SCSI_STATUS_ERROR) {
6759 sense = &ccb->csio.sense_data;
6760 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6761 ccb->csio.sense_resid, &error_code, &sense_key,
6762 &asc, &ascq, /*show_errors*/ 1);
6764 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6765 asc == 0x20 && ascq == 0x00)
6766 warnx("sanitize is not supported by "
6769 warnx("error sanitizing this device");
6771 warnx("error sanitizing this device");
6773 if (arglist & CAM_ARG_VERBOSE) {
6774 cam_error_print(device, ccb, CAM_ESF_ALL,
6775 CAM_EPF_ALL, stderr);
6778 goto scsisanitize_bailout;
6782 * If we ran in non-immediate mode, we already checked for errors
6783 * above and printed out any necessary information. If we're in
6784 * immediate mode, we need to loop through and get status
6785 * information periodically.
6787 if (immediate == 0) {
6789 fprintf(stdout, "Sanitize Complete\n");
6791 goto scsisanitize_bailout;
6798 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6801 * There's really no need to do error recovery or
6802 * retries here, since we're just going to sit in a
6803 * loop and wait for the device to finish sanitizing.
6805 scsi_test_unit_ready(&ccb->csio,
6808 /* tag_action */ task_attr,
6809 /* sense_len */ SSD_FULL_SIZE,
6810 /* timeout */ 5000);
6812 /* Disable freezing the device queue */
6813 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6815 retval = cam_send_ccb(device, ccb);
6818 * If we get an error from the ioctl, bail out. SCSI
6819 * errors are expected.
6822 warn("error sending CAMIOCOMMAND ioctl");
6823 if (arglist & CAM_ARG_VERBOSE) {
6824 cam_error_print(device, ccb, CAM_ESF_ALL,
6825 CAM_EPF_ALL, stderr);
6828 goto scsisanitize_bailout;
6831 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6833 if ((status != CAM_REQ_CMP)
6834 && (status == CAM_SCSI_STATUS_ERROR)
6835 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6836 struct scsi_sense_data *sense;
6837 int error_code, sense_key, asc, ascq;
6839 sense = &ccb->csio.sense_data;
6840 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6841 ccb->csio.sense_resid, &error_code, &sense_key,
6842 &asc, &ascq, /*show_errors*/ 1);
6845 * According to the SCSI-3 spec, a drive that is in the
6846 * middle of a sanitize should return NOT READY with an
6847 * ASC of "logical unit not ready, sanitize in
6848 * progress". The sense key specific bytes will then
6849 * be a progress indicator.
6851 if ((sense_key == SSD_KEY_NOT_READY)
6852 && (asc == 0x04) && (ascq == 0x1b)) {
6855 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6856 ccb->csio.sense_resid, sks) == 0)
6859 u_int64_t percentage;
6861 val = scsi_2btoul(&sks[1]);
6862 percentage = 10000 * val;
6865 "\rSanitizing: %ju.%02u %% "
6867 (uintmax_t)(percentage /
6869 (unsigned)((percentage /
6873 } else if ((quiet == 0)
6874 && (++num_warnings <= 1)) {
6875 warnx("Unexpected SCSI Sense Key "
6876 "Specific value returned "
6877 "during sanitize:");
6878 scsi_sense_print(device, &ccb->csio,
6880 warnx("Unable to print status "
6881 "information, but sanitze will "
6883 warnx("will exit when sanitize is "
6888 warnx("Unexpected SCSI error during sanitize");
6889 cam_error_print(device, ccb, CAM_ESF_ALL,
6890 CAM_EPF_ALL, stderr);
6892 goto scsisanitize_bailout;
6895 } else if (status != CAM_REQ_CMP) {
6896 warnx("Unexpected CAM status %#x", status);
6897 if (arglist & CAM_ARG_VERBOSE)
6898 cam_error_print(device, ccb, CAM_ESF_ALL,
6899 CAM_EPF_ALL, stderr);
6901 goto scsisanitize_bailout;
6903 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6906 fprintf(stdout, "\nSanitize Complete\n");
6908 scsisanitize_bailout:
6911 if (data_ptr != NULL)
6919 scsireportluns(struct cam_device *device, int argc, char **argv,
6920 char *combinedopt, int task_attr, int retry_count, int timeout)
6923 int c, countonly, lunsonly;
6924 struct scsi_report_luns_data *lundata;
6926 uint8_t report_type;
6927 uint32_t list_len, i, j;
6932 report_type = RPL_REPORT_DEFAULT;
6933 ccb = cam_getccb(device);
6936 warnx("%s: error allocating ccb", __func__);
6940 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6945 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6954 if (strcasecmp(optarg, "default") == 0)
6955 report_type = RPL_REPORT_DEFAULT;
6956 else if (strcasecmp(optarg, "wellknown") == 0)
6957 report_type = RPL_REPORT_WELLKNOWN;
6958 else if (strcasecmp(optarg, "all") == 0)
6959 report_type = RPL_REPORT_ALL;
6961 warnx("%s: invalid report type \"%s\"",
6972 if ((countonly != 0)
6973 && (lunsonly != 0)) {
6974 warnx("%s: you can only specify one of -c or -l", __func__);
6979 * According to SPC-4, the allocation length must be at least 16
6980 * bytes -- enough for the header and one LUN.
6982 alloc_len = sizeof(*lundata) + 8;
6986 lundata = malloc(alloc_len);
6988 if (lundata == NULL) {
6989 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6994 scsi_report_luns(&ccb->csio,
6995 /*retries*/ retry_count,
6997 /*tag_action*/ task_attr,
6998 /*select_report*/ report_type,
6999 /*rpl_buf*/ lundata,
7000 /*alloc_len*/ alloc_len,
7001 /*sense_len*/ SSD_FULL_SIZE,
7002 /*timeout*/ timeout ? timeout : 5000);
7004 /* Disable freezing the device queue */
7005 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7007 if (arglist & CAM_ARG_ERR_RECOVER)
7008 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7010 if (cam_send_ccb(device, ccb) < 0) {
7011 warn("error sending REPORT LUNS command");
7013 if (arglist & CAM_ARG_VERBOSE)
7014 cam_error_print(device, ccb, CAM_ESF_ALL,
7015 CAM_EPF_ALL, stderr);
7021 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7022 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7028 list_len = scsi_4btoul(lundata->length);
7031 * If we need to list the LUNs, and our allocation
7032 * length was too short, reallocate and retry.
7034 if ((countonly == 0)
7035 && (list_len > (alloc_len - sizeof(*lundata)))) {
7036 alloc_len = list_len + sizeof(*lundata);
7042 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7043 ((list_len / 8) > 1) ? "s" : "");
7048 for (i = 0; i < (list_len / 8); i++) {
7052 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7054 fprintf(stdout, ",");
7055 switch (lundata->luns[i].lundata[j] &
7056 RPL_LUNDATA_ATYP_MASK) {
7057 case RPL_LUNDATA_ATYP_PERIPH:
7058 if ((lundata->luns[i].lundata[j] &
7059 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7060 fprintf(stdout, "%d:",
7061 lundata->luns[i].lundata[j] &
7062 RPL_LUNDATA_PERIPH_BUS_MASK);
7064 && ((lundata->luns[i].lundata[j+2] &
7065 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7068 fprintf(stdout, "%d",
7069 lundata->luns[i].lundata[j+1]);
7071 case RPL_LUNDATA_ATYP_FLAT: {
7073 tmplun[0] = lundata->luns[i].lundata[j] &
7074 RPL_LUNDATA_FLAT_LUN_MASK;
7075 tmplun[1] = lundata->luns[i].lundata[j+1];
7077 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7081 case RPL_LUNDATA_ATYP_LUN:
7082 fprintf(stdout, "%d:%d:%d",
7083 (lundata->luns[i].lundata[j+1] &
7084 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7085 lundata->luns[i].lundata[j] &
7086 RPL_LUNDATA_LUN_TARG_MASK,
7087 lundata->luns[i].lundata[j+1] &
7088 RPL_LUNDATA_LUN_LUN_MASK);
7090 case RPL_LUNDATA_ATYP_EXTLUN: {
7091 int field_len_code, eam_code;
7093 eam_code = lundata->luns[i].lundata[j] &
7094 RPL_LUNDATA_EXT_EAM_MASK;
7095 field_len_code = (lundata->luns[i].lundata[j] &
7096 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7098 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7099 && (field_len_code == 0x00)) {
7100 fprintf(stdout, "%d",
7101 lundata->luns[i].lundata[j+1]);
7102 } else if ((eam_code ==
7103 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7104 && (field_len_code == 0x03)) {
7108 * This format takes up all 8 bytes.
7109 * If we aren't starting at offset 0,
7113 fprintf(stdout, "Invalid "
7116 "specified format", j);
7120 bzero(tmp_lun, sizeof(tmp_lun));
7121 bcopy(&lundata->luns[i].lundata[j+1],
7122 &tmp_lun[1], sizeof(tmp_lun) - 1);
7123 fprintf(stdout, "%#jx",
7124 (intmax_t)scsi_8btou64(tmp_lun));
7127 fprintf(stderr, "Unknown Extended LUN"
7128 "Address method %#x, length "
7129 "code %#x", eam_code,
7136 fprintf(stderr, "Unknown LUN address method "
7137 "%#x\n", lundata->luns[i].lundata[0] &
7138 RPL_LUNDATA_ATYP_MASK);
7142 * For the flat addressing method, there are no
7143 * other levels after it.
7148 fprintf(stdout, "\n");
7161 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7162 char *combinedopt, int task_attr, int retry_count, int timeout)
7165 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
7166 struct scsi_read_capacity_data rcap;
7167 struct scsi_read_capacity_data_long rcaplong;
7181 ccb = cam_getccb(device);
7184 warnx("%s: error allocating ccb", __func__);
7188 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7190 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7217 if ((blocksizeonly != 0)
7218 && (numblocks != 0)) {
7219 warnx("%s: you can only specify one of -b or -N", __func__);
7224 if ((blocksizeonly != 0)
7225 && (sizeonly != 0)) {
7226 warnx("%s: you can only specify one of -b or -s", __func__);
7233 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7239 && (blocksizeonly != 0)) {
7240 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7245 scsi_read_capacity(&ccb->csio,
7246 /*retries*/ retry_count,
7248 /*tag_action*/ task_attr,
7251 /*timeout*/ timeout ? timeout : 5000);
7253 /* Disable freezing the device queue */
7254 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7256 if (arglist & CAM_ARG_ERR_RECOVER)
7257 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7259 if (cam_send_ccb(device, ccb) < 0) {
7260 warn("error sending READ CAPACITY command");
7262 if (arglist & CAM_ARG_VERBOSE)
7263 cam_error_print(device, ccb, CAM_ESF_ALL,
7264 CAM_EPF_ALL, stderr);
7270 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7271 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7276 maxsector = scsi_4btoul(rcap.addr);
7277 block_len = scsi_4btoul(rcap.length);
7280 * A last block of 2^32-1 means that the true capacity is over 2TB,
7281 * and we need to issue the long READ CAPACITY to get the real
7282 * capacity. Otherwise, we're all set.
7284 if (maxsector != 0xffffffff)
7287 scsi_read_capacity_16(&ccb->csio,
7288 /*retries*/ retry_count,
7290 /*tag_action*/ task_attr,
7294 /*rcap_buf*/ (uint8_t *)&rcaplong,
7295 /*rcap_buf_len*/ sizeof(rcaplong),
7296 /*sense_len*/ SSD_FULL_SIZE,
7297 /*timeout*/ timeout ? timeout : 5000);
7299 /* Disable freezing the device queue */
7300 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7302 if (arglist & CAM_ARG_ERR_RECOVER)
7303 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7305 if (cam_send_ccb(device, ccb) < 0) {
7306 warn("error sending READ CAPACITY (16) command");
7308 if (arglist & CAM_ARG_VERBOSE)
7309 cam_error_print(device, ccb, CAM_ESF_ALL,
7310 CAM_EPF_ALL, stderr);
7316 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7317 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7322 maxsector = scsi_8btou64(rcaplong.addr);
7323 block_len = scsi_4btoul(rcaplong.length);
7326 if (blocksizeonly == 0) {
7328 * Humanize implies !quiet, and also implies numblocks.
7330 if (humanize != 0) {
7335 tmpbytes = (maxsector + 1) * block_len;
7336 ret = humanize_number(tmpstr, sizeof(tmpstr),
7337 tmpbytes, "", HN_AUTOSCALE,
7340 HN_DIVISOR_1000 : 0));
7342 warnx("%s: humanize_number failed!", __func__);
7346 fprintf(stdout, "Device Size: %s%s", tmpstr,
7347 (sizeonly == 0) ? ", " : "\n");
7348 } else if (numblocks != 0) {
7349 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7350 "Blocks: " : "", (uintmax_t)maxsector + 1,
7351 (sizeonly == 0) ? ", " : "\n");
7353 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7354 "Last Block: " : "", (uintmax_t)maxsector,
7355 (sizeonly == 0) ? ", " : "\n");
7359 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7360 "Block Length: " : "", block_len, (quiet == 0) ?
7369 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7370 int retry_count, int timeout)
7374 uint8_t *smp_request = NULL, *smp_response = NULL;
7375 int request_size = 0, response_size = 0;
7376 int fd_request = 0, fd_response = 0;
7377 char *datastr = NULL;
7378 struct get_hook hook;
7383 * Note that at the moment we don't support sending SMP CCBs to
7384 * devices that aren't probed by CAM.
7386 ccb = cam_getccb(device);
7388 warnx("%s: error allocating CCB", __func__);
7392 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7394 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7397 arglist |= CAM_ARG_CMD_IN;
7398 response_size = strtol(optarg, NULL, 0);
7399 if (response_size <= 0) {
7400 warnx("invalid number of response bytes %d",
7403 goto smpcmd_bailout;
7405 hook.argc = argc - optind;
7406 hook.argv = argv + optind;
7409 datastr = cget(&hook, NULL);
7411 * If the user supplied "-" instead of a format, he
7412 * wants the data to be written to stdout.
7414 if ((datastr != NULL)
7415 && (datastr[0] == '-'))
7418 smp_response = (u_int8_t *)malloc(response_size);
7419 if (smp_response == NULL) {
7420 warn("can't malloc memory for SMP response");
7422 goto smpcmd_bailout;
7426 arglist |= CAM_ARG_CMD_OUT;
7427 request_size = strtol(optarg, NULL, 0);
7428 if (request_size <= 0) {
7429 warnx("invalid number of request bytes %d",
7432 goto smpcmd_bailout;
7434 hook.argc = argc - optind;
7435 hook.argv = argv + optind;
7437 datastr = cget(&hook, NULL);
7438 smp_request = (u_int8_t *)malloc(request_size);
7439 if (smp_request == NULL) {
7440 warn("can't malloc memory for SMP request");
7442 goto smpcmd_bailout;
7444 bzero(smp_request, request_size);
7446 * If the user supplied "-" instead of a format, he
7447 * wants the data to be read from stdin.
7449 if ((datastr != NULL)
7450 && (datastr[0] == '-'))
7453 buff_encode_visit(smp_request, request_size,
7464 * If fd_data is set, and we're writing to the device, we need to
7465 * read the data the user wants written from stdin.
7467 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7469 int amt_to_read = request_size;
7470 u_int8_t *buf_ptr = smp_request;
7472 for (amt_read = 0; amt_to_read > 0;
7473 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7474 if (amt_read == -1) {
7475 warn("error reading data from stdin");
7477 goto smpcmd_bailout;
7479 amt_to_read -= amt_read;
7480 buf_ptr += amt_read;
7484 if (((arglist & CAM_ARG_CMD_IN) == 0)
7485 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7486 warnx("%s: need both the request (-r) and response (-R) "
7487 "arguments", __func__);
7489 goto smpcmd_bailout;
7492 flags |= CAM_DEV_QFRZDIS;
7494 cam_fill_smpio(&ccb->smpio,
7495 /*retries*/ retry_count,
7498 /*smp_request*/ smp_request,
7499 /*smp_request_len*/ request_size,
7500 /*smp_response*/ smp_response,
7501 /*smp_response_len*/ response_size,
7502 /*timeout*/ timeout ? timeout : 5000);
7504 ccb->smpio.flags = SMP_FLAG_NONE;
7506 if (((retval = cam_send_ccb(device, ccb)) < 0)
7507 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7508 const char warnstr[] = "error sending command";
7515 if (arglist & CAM_ARG_VERBOSE) {
7516 cam_error_print(device, ccb, CAM_ESF_ALL,
7517 CAM_EPF_ALL, stderr);
7521 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7522 && (response_size > 0)) {
7523 if (fd_response == 0) {
7524 buff_decode_visit(smp_response, response_size,
7525 datastr, arg_put, NULL);
7526 fprintf(stdout, "\n");
7528 ssize_t amt_written;
7529 int amt_to_write = response_size;
7530 u_int8_t *buf_ptr = smp_response;
7532 for (amt_written = 0; (amt_to_write > 0) &&
7533 (amt_written = write(STDOUT_FILENO, buf_ptr,
7534 amt_to_write)) > 0;){
7535 amt_to_write -= amt_written;
7536 buf_ptr += amt_written;
7538 if (amt_written == -1) {
7539 warn("error writing data to stdout");
7541 goto smpcmd_bailout;
7542 } else if ((amt_written == 0)
7543 && (amt_to_write > 0)) {
7544 warnx("only wrote %u bytes out of %u",
7545 response_size - amt_to_write,
7554 if (smp_request != NULL)
7557 if (smp_response != NULL)
7564 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7565 int retry_count, int timeout)
7569 int32_t mmc_opcode = 0, mmc_arg = 0;
7570 int32_t mmc_flags = -1;
7573 int is_bw_4 = 0, is_bw_1 = 0;
7574 int is_highspeed = 0, is_stdspeed = 0;
7575 int is_info_request = 0;
7577 uint8_t mmc_data_byte = 0;
7579 /* For IO_RW_EXTENDED command */
7580 uint8_t *mmc_data = NULL;
7581 struct mmc_data mmc_d;
7582 int mmc_data_len = 0;
7585 * Note that at the moment we don't support sending SMP CCBs to
7586 * devices that aren't probed by CAM.
7588 ccb = cam_getccb(device);
7590 warnx("%s: error allocating CCB", __func__);
7594 bzero(&(&ccb->ccb_h)[1],
7595 sizeof(union ccb) - sizeof(struct ccb_hdr));
7597 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7606 if (!strcmp(optarg, "high"))
7612 is_info_request = 1;
7615 mmc_opcode = strtol(optarg, NULL, 0);
7616 if (mmc_opcode < 0) {
7617 warnx("invalid MMC opcode %d",
7620 goto mmccmd_bailout;
7624 mmc_arg = strtol(optarg, NULL, 0);
7626 warnx("invalid MMC arg %d",
7629 goto mmccmd_bailout;
7633 mmc_flags = strtol(optarg, NULL, 0);
7634 if (mmc_flags < 0) {
7635 warnx("invalid MMC flags %d",
7638 goto mmccmd_bailout;
7642 mmc_data_len = strtol(optarg, NULL, 0);
7643 if (mmc_data_len <= 0) {
7644 warnx("invalid MMC data len %d",
7647 goto mmccmd_bailout;
7654 mmc_data_byte = strtol(optarg, NULL, 0);
7660 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7662 /* If flags are left default, supply the right flags */
7664 switch (mmc_opcode) {
7665 case MMC_GO_IDLE_STATE:
7666 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7668 case IO_SEND_OP_COND:
7669 mmc_flags = MMC_RSP_R4;
7671 case SD_SEND_RELATIVE_ADDR:
7672 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7674 case MMC_SELECT_CARD:
7675 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7676 mmc_arg = mmc_arg << 16;
7678 case SD_IO_RW_DIRECT:
7679 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7680 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7682 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7684 case SD_IO_RW_EXTENDED:
7685 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7686 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7687 int len_arg = mmc_data_len;
7688 if (mmc_data_len == 512)
7692 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7694 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7697 mmc_flags = MMC_RSP_R1;
7701 // Switch bus width instead of sending IO command
7702 if (is_bw_4 || is_bw_1) {
7703 struct ccb_trans_settings_mmc *cts;
7704 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7705 ccb->ccb_h.flags = 0;
7706 cts = &ccb->cts.proto_specific.mmc;
7707 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7708 cts->ios_valid = MMC_BW;
7709 if (((retval = cam_send_ccb(device, ccb)) < 0)
7710 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7711 warn("Error sending command");
7713 printf("Parameters set OK\n");
7719 // Switch bus speed instead of sending IO command
7720 if (is_stdspeed || is_highspeed) {
7721 struct ccb_trans_settings_mmc *cts;
7722 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7723 ccb->ccb_h.flags = 0;
7724 cts = &ccb->cts.proto_specific.mmc;
7725 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
7726 cts->ios_valid = MMC_BT;
7727 if (((retval = cam_send_ccb(device, ccb)) < 0)
7728 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7729 warn("Error sending command");
7731 printf("Speed set OK (HS: %d)\n", is_highspeed);
7737 // Get information about controller and its settings
7738 if (is_info_request) {
7739 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
7740 ccb->ccb_h.flags = 0;
7741 struct ccb_trans_settings_mmc *cts;
7742 cts = &ccb->cts.proto_specific.mmc;
7743 if (((retval = cam_send_ccb(device, ccb)) < 0)
7744 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7745 warn("Error sending command");
7748 printf("Host controller information\n");
7749 printf("Host OCR: 0x%x\n", cts->host_ocr);
7750 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
7751 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
7752 printf("Supported bus width: ");
7753 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
7755 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
7757 printf("\nCurrent settings:\n");
7758 printf("Bus width: ");
7759 switch (cts->ios.bus_width) {
7770 printf("Freq: %d.%03d MHz%s\n",
7771 cts->ios.clock / 1000000,
7772 (cts->ios.clock / 1000) % 1000,
7773 cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : "");
7777 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
7779 if (mmc_data_len > 0) {
7780 flags |= CAM_DIR_IN;
7781 mmc_data = malloc(mmc_data_len);
7782 memset(mmc_data, 0, mmc_data_len);
7783 mmc_d.len = mmc_data_len;
7784 mmc_d.data = mmc_data;
7785 mmc_d.flags = MMC_DATA_READ;
7786 } else flags |= CAM_DIR_NONE;
7788 cam_fill_mmcio(&ccb->mmcio,
7789 /*retries*/ retry_count,
7792 /*mmc_opcode*/ mmc_opcode,
7793 /*mmc_arg*/ mmc_arg,
7794 /*mmc_flags*/ mmc_flags,
7795 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
7796 /*timeout*/ timeout ? timeout : 5000);
7798 if (((retval = cam_send_ccb(device, ccb)) < 0)
7799 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7800 const char warnstr[] = "error sending command";
7807 if (arglist & CAM_ARG_VERBOSE) {
7808 cam_error_print(device, ccb, CAM_ESF_ALL,
7809 CAM_EPF_ALL, stderr);
7813 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
7814 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
7815 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
7816 ccb->mmcio.cmd.resp[1],
7817 ccb->mmcio.cmd.resp[2],
7818 ccb->mmcio.cmd.resp[3]);
7820 switch (mmc_opcode) {
7821 case SD_IO_RW_DIRECT:
7822 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
7823 SD_R5_DATA(ccb->mmcio.cmd.resp),
7824 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
7826 case SD_IO_RW_EXTENDED:
7827 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
7828 hexdump(mmc_data, mmc_data_len, NULL, 0);
7830 case SD_SEND_RELATIVE_ADDR:
7831 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
7834 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
7841 if (mmc_data_len > 0 && mmc_data != NULL)
7848 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7849 char *combinedopt, int retry_count, int timeout)
7852 struct smp_report_general_request *request = NULL;
7853 struct smp_report_general_response *response = NULL;
7854 struct sbuf *sb = NULL;
7856 int c, long_response = 0;
7860 * Note that at the moment we don't support sending SMP CCBs to
7861 * devices that aren't probed by CAM.
7863 ccb = cam_getccb(device);
7865 warnx("%s: error allocating CCB", __func__);
7869 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7871 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7880 request = malloc(sizeof(*request));
7881 if (request == NULL) {
7882 warn("%s: unable to allocate %zd bytes", __func__,
7888 response = malloc(sizeof(*response));
7889 if (response == NULL) {
7890 warn("%s: unable to allocate %zd bytes", __func__,
7897 smp_report_general(&ccb->smpio,
7901 /*request_len*/ sizeof(*request),
7902 (uint8_t *)response,
7903 /*response_len*/ sizeof(*response),
7904 /*long_response*/ long_response,
7907 if (((retval = cam_send_ccb(device, ccb)) < 0)
7908 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7909 const char warnstr[] = "error sending command";
7916 if (arglist & CAM_ARG_VERBOSE) {
7917 cam_error_print(device, ccb, CAM_ESF_ALL,
7918 CAM_EPF_ALL, stderr);
7925 * If the device supports the long response bit, try again and see
7926 * if we can get all of the data.
7928 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7929 && (long_response == 0)) {
7930 ccb->ccb_h.status = CAM_REQ_INPROG;
7931 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7937 * XXX KDM detect and decode SMP errors here.
7939 sb = sbuf_new_auto();
7941 warnx("%s: error allocating sbuf", __func__);
7945 smp_report_general_sbuf(response, sizeof(*response), sb);
7947 if (sbuf_finish(sb) != 0) {
7948 warnx("%s: sbuf_finish", __func__);
7952 printf("%s", sbuf_data(sb));
7958 if (request != NULL)
7961 if (response != NULL)
7970 static struct camcontrol_opts phy_ops[] = {
7971 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7972 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7973 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7974 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7975 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7976 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7977 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7978 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7979 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7984 smpphycontrol(struct cam_device *device, int argc, char **argv,
7985 char *combinedopt, int retry_count, int timeout)
7988 struct smp_phy_control_request *request = NULL;
7989 struct smp_phy_control_response *response = NULL;
7990 int long_response = 0;
7993 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7995 uint64_t attached_dev_name = 0;
7996 int dev_name_set = 0;
7997 uint32_t min_plr = 0, max_plr = 0;
7998 uint32_t pp_timeout_val = 0;
7999 int slumber_partial = 0;
8000 int set_pp_timeout_val = 0;
8004 * Note that at the moment we don't support sending SMP CCBs to
8005 * devices that aren't probed by CAM.
8007 ccb = cam_getccb(device);
8009 warnx("%s: error allocating CCB", __func__);
8013 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8015 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8023 if (strcasecmp(optarg, "enable") == 0)
8025 else if (strcasecmp(optarg, "disable") == 0)
8028 warnx("%s: Invalid argument %s", __func__,
8035 slumber_partial |= enable <<
8036 SMP_PC_SAS_SLUMBER_SHIFT;
8039 slumber_partial |= enable <<
8040 SMP_PC_SAS_PARTIAL_SHIFT;
8043 slumber_partial |= enable <<
8044 SMP_PC_SATA_SLUMBER_SHIFT;
8047 slumber_partial |= enable <<
8048 SMP_PC_SATA_PARTIAL_SHIFT;
8051 warnx("%s: programmer error", __func__);
8054 break; /*NOTREACHED*/
8059 attached_dev_name = (uintmax_t)strtoumax(optarg,
8068 * We don't do extensive checking here, so this
8069 * will continue to work when new speeds come out.
8071 min_plr = strtoul(optarg, NULL, 0);
8073 || (min_plr > 0xf)) {
8074 warnx("%s: invalid link rate %x",
8082 * We don't do extensive checking here, so this
8083 * will continue to work when new speeds come out.
8085 max_plr = strtoul(optarg, NULL, 0);
8087 || (max_plr > 0xf)) {
8088 warnx("%s: invalid link rate %x",
8095 camcontrol_optret optreturn;
8096 cam_argmask argnums;
8099 if (phy_op_set != 0) {
8100 warnx("%s: only one phy operation argument "
8101 "(-o) allowed", __func__);
8109 * Allow the user to specify the phy operation
8110 * numerically, as well as with a name. This will
8111 * future-proof it a bit, so options that are added
8112 * in future specs can be used.
8114 if (isdigit(optarg[0])) {
8115 phy_operation = strtoul(optarg, NULL, 0);
8116 if ((phy_operation == 0)
8117 || (phy_operation > 0xff)) {
8118 warnx("%s: invalid phy operation %#x",
8119 __func__, phy_operation);
8125 optreturn = getoption(phy_ops, optarg, &phy_operation,
8128 if (optreturn == CC_OR_AMBIGUOUS) {
8129 warnx("%s: ambiguous option %s", __func__,
8134 } else if (optreturn == CC_OR_NOT_FOUND) {
8135 warnx("%s: option %s not found", __func__,
8147 pp_timeout_val = strtoul(optarg, NULL, 0);
8148 if (pp_timeout_val > 15) {
8149 warnx("%s: invalid partial pathway timeout "
8150 "value %u, need a value less than 16",
8151 __func__, pp_timeout_val);
8155 set_pp_timeout_val = 1;
8163 warnx("%s: a PHY (-p phy) argument is required",__func__);
8168 if (((dev_name_set != 0)
8169 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8170 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8171 && (dev_name_set == 0))) {
8172 warnx("%s: -d name and -o setdevname arguments both "
8173 "required to set device name", __func__);
8178 request = malloc(sizeof(*request));
8179 if (request == NULL) {
8180 warn("%s: unable to allocate %zd bytes", __func__,
8186 response = malloc(sizeof(*response));
8187 if (response == NULL) {
8188 warn("%s: unable to allocate %zd bytes", __func__,
8194 smp_phy_control(&ccb->smpio,
8199 (uint8_t *)response,
8202 /*expected_exp_change_count*/ 0,
8205 (set_pp_timeout_val != 0) ? 1 : 0,
8213 if (((retval = cam_send_ccb(device, ccb)) < 0)
8214 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8215 const char warnstr[] = "error sending command";
8222 if (arglist & CAM_ARG_VERBOSE) {
8224 * Use CAM_EPF_NORMAL so we only get one line of
8225 * SMP command decoding.
8227 cam_error_print(device, ccb, CAM_ESF_ALL,
8228 CAM_EPF_NORMAL, stderr);
8234 /* XXX KDM print out something here for success? */
8239 if (request != NULL)
8242 if (response != NULL)
8249 smpmaninfo(struct cam_device *device, int argc, char **argv,
8250 char *combinedopt, int retry_count, int timeout)
8253 struct smp_report_manuf_info_request request;
8254 struct smp_report_manuf_info_response response;
8255 struct sbuf *sb = NULL;
8256 int long_response = 0;
8261 * Note that at the moment we don't support sending SMP CCBs to
8262 * devices that aren't probed by CAM.
8264 ccb = cam_getccb(device);
8266 warnx("%s: error allocating CCB", __func__);
8270 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8272 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8281 bzero(&request, sizeof(request));
8282 bzero(&response, sizeof(response));
8284 smp_report_manuf_info(&ccb->smpio,
8289 (uint8_t *)&response,
8294 if (((retval = cam_send_ccb(device, ccb)) < 0)
8295 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8296 const char warnstr[] = "error sending command";
8303 if (arglist & CAM_ARG_VERBOSE) {
8304 cam_error_print(device, ccb, CAM_ESF_ALL,
8305 CAM_EPF_ALL, stderr);
8311 sb = sbuf_new_auto();
8313 warnx("%s: error allocating sbuf", __func__);
8317 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8319 if (sbuf_finish(sb) != 0) {
8320 warnx("%s: sbuf_finish", __func__);
8324 printf("%s", sbuf_data(sb));
8338 getdevid(struct cam_devitem *item)
8341 union ccb *ccb = NULL;
8343 struct cam_device *dev;
8345 dev = cam_open_btl(item->dev_match.path_id,
8346 item->dev_match.target_id,
8347 item->dev_match.target_lun, O_RDWR, NULL);
8350 warnx("%s", cam_errbuf);
8355 item->device_id_len = 0;
8357 ccb = cam_getccb(dev);
8359 warnx("%s: error allocating CCB", __func__);
8364 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8367 * On the first try, we just probe for the size of the data, and
8368 * then allocate that much memory and try again.
8371 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8372 ccb->ccb_h.flags = CAM_DIR_IN;
8373 ccb->cdai.flags = CDAI_FLAG_NONE;
8374 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8375 ccb->cdai.bufsiz = item->device_id_len;
8376 if (item->device_id_len != 0)
8377 ccb->cdai.buf = (uint8_t *)item->device_id;
8379 if (cam_send_ccb(dev, ccb) < 0) {
8380 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8385 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8386 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8391 if (item->device_id_len == 0) {
8393 * This is our first time through. Allocate the buffer,
8394 * and then go back to get the data.
8396 if (ccb->cdai.provsiz == 0) {
8397 warnx("%s: invalid .provsiz field returned with "
8398 "XPT_GDEV_ADVINFO CCB", __func__);
8402 item->device_id_len = ccb->cdai.provsiz;
8403 item->device_id = malloc(item->device_id_len);
8404 if (item->device_id == NULL) {
8405 warn("%s: unable to allocate %d bytes", __func__,
8406 item->device_id_len);
8410 ccb->ccb_h.status = CAM_REQ_INPROG;
8416 cam_close_device(dev);
8425 * XXX KDM merge this code with getdevtree()?
8428 buildbusdevlist(struct cam_devlist *devlist)
8431 int bufsize, fd = -1;
8432 struct dev_match_pattern *patterns;
8433 struct cam_devitem *item = NULL;
8434 int skip_device = 0;
8437 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8438 warn("couldn't open %s", XPT_DEVICE);
8442 bzero(&ccb, sizeof(union ccb));
8444 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8445 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8446 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8448 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8449 bufsize = sizeof(struct dev_match_result) * 100;
8450 ccb.cdm.match_buf_len = bufsize;
8451 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8452 if (ccb.cdm.matches == NULL) {
8453 warnx("can't malloc memory for matches");
8457 ccb.cdm.num_matches = 0;
8458 ccb.cdm.num_patterns = 2;
8459 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8460 ccb.cdm.num_patterns;
8462 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8463 if (patterns == NULL) {
8464 warnx("can't malloc memory for patterns");
8469 ccb.cdm.patterns = patterns;
8470 bzero(patterns, ccb.cdm.pattern_buf_len);
8472 patterns[0].type = DEV_MATCH_DEVICE;
8473 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8474 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8475 patterns[1].type = DEV_MATCH_PERIPH;
8476 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8477 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8480 * We do the ioctl multiple times if necessary, in case there are
8481 * more than 100 nodes in the EDT.
8486 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8487 warn("error sending CAMIOCOMMAND ioctl");
8492 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8493 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8494 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8495 warnx("got CAM error %#x, CDM error %d\n",
8496 ccb.ccb_h.status, ccb.cdm.status);
8501 for (i = 0; i < ccb.cdm.num_matches; i++) {
8502 switch (ccb.cdm.matches[i].type) {
8503 case DEV_MATCH_DEVICE: {
8504 struct device_match_result *dev_result;
8507 &ccb.cdm.matches[i].result.device_result;
8509 if (dev_result->flags &
8510 DEV_RESULT_UNCONFIGURED) {
8516 item = malloc(sizeof(*item));
8518 warn("%s: unable to allocate %zd bytes",
8519 __func__, sizeof(*item));
8523 bzero(item, sizeof(*item));
8524 bcopy(dev_result, &item->dev_match,
8525 sizeof(*dev_result));
8526 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8529 if (getdevid(item) != 0) {
8535 case DEV_MATCH_PERIPH: {
8536 struct periph_match_result *periph_result;
8539 &ccb.cdm.matches[i].result.periph_result;
8541 if (skip_device != 0)
8543 item->num_periphs++;
8544 item->periph_matches = realloc(
8545 item->periph_matches,
8547 sizeof(struct periph_match_result));
8548 if (item->periph_matches == NULL) {
8549 warn("%s: error allocating periph "
8554 bcopy(periph_result, &item->periph_matches[
8555 item->num_periphs - 1],
8556 sizeof(*periph_result));
8560 fprintf(stderr, "%s: unexpected match "
8561 "type %d\n", __func__,
8562 ccb.cdm.matches[i].type);
8565 break; /*NOTREACHED*/
8568 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8569 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8577 free(ccb.cdm.matches);
8580 freebusdevlist(devlist);
8586 freebusdevlist(struct cam_devlist *devlist)
8588 struct cam_devitem *item, *item2;
8590 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8591 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8593 free(item->device_id);
8594 free(item->periph_matches);
8599 static struct cam_devitem *
8600 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8602 struct cam_devitem *item;
8604 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8605 struct scsi_vpd_id_descriptor *idd;
8608 * XXX KDM look for LUN IDs as well?
8610 idd = scsi_get_devid(item->device_id,
8611 item->device_id_len,
8612 scsi_devid_is_sas_target);
8616 if (scsi_8btou64(idd->identifier) == sasaddr)
8624 smpphylist(struct cam_device *device, int argc, char **argv,
8625 char *combinedopt, int retry_count, int timeout)
8627 struct smp_report_general_request *rgrequest = NULL;
8628 struct smp_report_general_response *rgresponse = NULL;
8629 struct smp_discover_request *disrequest = NULL;
8630 struct smp_discover_response *disresponse = NULL;
8631 struct cam_devlist devlist;
8633 int long_response = 0;
8640 * Note that at the moment we don't support sending SMP CCBs to
8641 * devices that aren't probed by CAM.
8643 ccb = cam_getccb(device);
8645 warnx("%s: error allocating CCB", __func__);
8649 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8650 STAILQ_INIT(&devlist.dev_queue);
8652 rgrequest = malloc(sizeof(*rgrequest));
8653 if (rgrequest == NULL) {
8654 warn("%s: unable to allocate %zd bytes", __func__,
8655 sizeof(*rgrequest));
8660 rgresponse = malloc(sizeof(*rgresponse));
8661 if (rgresponse == NULL) {
8662 warn("%s: unable to allocate %zd bytes", __func__,
8663 sizeof(*rgresponse));
8668 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8681 smp_report_general(&ccb->smpio,
8685 /*request_len*/ sizeof(*rgrequest),
8686 (uint8_t *)rgresponse,
8687 /*response_len*/ sizeof(*rgresponse),
8688 /*long_response*/ long_response,
8691 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8693 if (((retval = cam_send_ccb(device, ccb)) < 0)
8694 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8695 const char warnstr[] = "error sending command";
8702 if (arglist & CAM_ARG_VERBOSE) {
8703 cam_error_print(device, ccb, CAM_ESF_ALL,
8704 CAM_EPF_ALL, stderr);
8710 num_phys = rgresponse->num_phys;
8712 if (num_phys == 0) {
8714 fprintf(stdout, "%s: No Phys reported\n", __func__);
8719 devlist.path_id = device->path_id;
8721 retval = buildbusdevlist(&devlist);
8726 fprintf(stdout, "%d PHYs:\n", num_phys);
8727 fprintf(stdout, "PHY Attached SAS Address\n");
8730 disrequest = malloc(sizeof(*disrequest));
8731 if (disrequest == NULL) {
8732 warn("%s: unable to allocate %zd bytes", __func__,
8733 sizeof(*disrequest));
8738 disresponse = malloc(sizeof(*disresponse));
8739 if (disresponse == NULL) {
8740 warn("%s: unable to allocate %zd bytes", __func__,
8741 sizeof(*disresponse));
8746 for (i = 0; i < num_phys; i++) {
8747 struct cam_devitem *item;
8748 struct device_match_result *dev_match;
8749 char vendor[16], product[48], revision[16];
8753 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8755 ccb->ccb_h.status = CAM_REQ_INPROG;
8756 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8758 smp_discover(&ccb->smpio,
8762 sizeof(*disrequest),
8763 (uint8_t *)disresponse,
8764 sizeof(*disresponse),
8766 /*ignore_zone_group*/ 0,
8770 if (((retval = cam_send_ccb(device, ccb)) < 0)
8771 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
8772 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
8773 const char warnstr[] = "error sending command";
8780 if (arglist & CAM_ARG_VERBOSE) {
8781 cam_error_print(device, ccb, CAM_ESF_ALL,
8782 CAM_EPF_ALL, stderr);
8788 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
8790 fprintf(stdout, "%3d <vacant>\n", i);
8794 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
8797 item = findsasdevice(&devlist,
8798 scsi_8btou64(disresponse->attached_sas_address));
8802 || (item != NULL)) {
8803 fprintf(stdout, "%3d 0x%016jx", i,
8804 (uintmax_t)scsi_8btou64(
8805 disresponse->attached_sas_address));
8807 fprintf(stdout, "\n");
8810 } else if (quiet != 0)
8813 dev_match = &item->dev_match;
8815 if (dev_match->protocol == PROTO_SCSI) {
8816 cam_strvis(vendor, dev_match->inq_data.vendor,
8817 sizeof(dev_match->inq_data.vendor),
8819 cam_strvis(product, dev_match->inq_data.product,
8820 sizeof(dev_match->inq_data.product),
8822 cam_strvis(revision, dev_match->inq_data.revision,
8823 sizeof(dev_match->inq_data.revision),
8825 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8827 } else if ((dev_match->protocol == PROTO_ATA)
8828 || (dev_match->protocol == PROTO_SATAPM)) {
8829 cam_strvis(product, dev_match->ident_data.model,
8830 sizeof(dev_match->ident_data.model),
8832 cam_strvis(revision, dev_match->ident_data.revision,
8833 sizeof(dev_match->ident_data.revision),
8835 sprintf(tmpstr, "<%s %s>", product, revision);
8837 sprintf(tmpstr, "<>");
8839 fprintf(stdout, " %-33s ", tmpstr);
8842 * If we have 0 periphs, that's a bug...
8844 if (item->num_periphs == 0) {
8845 fprintf(stdout, "\n");
8849 fprintf(stdout, "(");
8850 for (j = 0; j < item->num_periphs; j++) {
8852 fprintf(stdout, ",");
8854 fprintf(stdout, "%s%d",
8855 item->periph_matches[j].periph_name,
8856 item->periph_matches[j].unit_number);
8859 fprintf(stdout, ")\n");
8873 freebusdevlist(&devlist);
8879 atapm(struct cam_device *device, int argc, char **argv,
8880 char *combinedopt, int retry_count, int timeout)
8888 ccb = cam_getccb(device);
8891 warnx("%s: error allocating ccb", __func__);
8895 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8904 if (strcmp(argv[1], "idle") == 0) {
8906 cmd = ATA_IDLE_IMMEDIATE;
8909 } else if (strcmp(argv[1], "standby") == 0) {
8911 cmd = ATA_STANDBY_IMMEDIATE;
8913 cmd = ATA_STANDBY_CMD;
8921 else if (t <= (240 * 5))
8923 else if (t <= (252 * 5))
8924 /* special encoding for 21 minutes */
8926 else if (t <= (11 * 30 * 60))
8927 sc = (t - 1) / (30 * 60) + 241;
8931 retval = ata_do_28bit_cmd(device,
8933 /*retries*/retry_count,
8934 /*flags*/CAM_DIR_NONE,
8935 /*protocol*/AP_PROTO_NON_DATA,
8936 /*tag_action*/MSG_SIMPLE_Q_TAG,
8943 /*timeout*/timeout ? timeout : 30 * 1000,
8951 ataaxm(struct cam_device *device, int argc, char **argv,
8952 char *combinedopt, int retry_count, int timeout)
8960 ccb = cam_getccb(device);
8963 warnx("%s: error allocating ccb", __func__);
8967 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8977 if (strcmp(argv[1], "apm") == 0) {
8993 retval = ata_do_28bit_cmd(device,
8995 /*retries*/retry_count,
8996 /*flags*/CAM_DIR_NONE,
8997 /*protocol*/AP_PROTO_NON_DATA,
8998 /*tag_action*/MSG_SIMPLE_Q_TAG,
8999 /*command*/ATA_SETFEATURES,
9005 /*timeout*/timeout ? timeout : 30 * 1000,
9013 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9014 int show_sa_errors, int sa_set, int service_action,
9015 int timeout_desc, int task_attr, int retry_count, int timeout,
9016 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9018 union ccb *ccb = NULL;
9019 uint8_t *buf = NULL;
9020 uint32_t alloc_len = 0, num_opcodes;
9021 uint32_t valid_len = 0;
9022 uint32_t avail_len = 0;
9023 struct scsi_report_supported_opcodes_all *all_hdr;
9024 struct scsi_report_supported_opcodes_one *one;
9029 * Make it clear that we haven't yet allocated or filled anything.
9034 ccb = cam_getccb(device);
9036 warnx("couldn't allocate CCB");
9041 /* cam_getccb cleans up the header, caller has to zero the payload */
9042 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9044 if (opcode_set != 0) {
9045 options |= RSO_OPTIONS_OC;
9047 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9050 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9051 sizeof(struct scsi_report_supported_opcodes_descr));
9054 if (timeout_desc != 0) {
9055 options |= RSO_RCTD;
9056 alloc_len += num_opcodes *
9057 sizeof(struct scsi_report_supported_opcodes_timeout);
9061 options |= RSO_OPTIONS_OC_SA;
9062 if (show_sa_errors != 0)
9063 options &= ~RSO_OPTIONS_OC;
9072 buf = malloc(alloc_len);
9074 warn("Unable to allocate %u bytes", alloc_len);
9078 bzero(buf, alloc_len);
9080 scsi_report_supported_opcodes(&ccb->csio,
9081 /*retries*/ retry_count,
9083 /*tag_action*/ task_attr,
9084 /*options*/ options,
9085 /*req_opcode*/ opcode,
9086 /*req_service_action*/ service_action,
9088 /*dxfer_len*/ alloc_len,
9089 /*sense_len*/ SSD_FULL_SIZE,
9090 /*timeout*/ timeout ? timeout : 10000);
9092 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9094 if (retry_count != 0)
9095 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9097 if (cam_send_ccb(device, ccb) < 0) {
9098 perror("error sending REPORT SUPPORTED OPERATION CODES");
9103 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9104 if (verbosemode != 0)
9105 cam_error_print(device, ccb, CAM_ESF_ALL,
9106 CAM_EPF_ALL, stderr);
9111 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9113 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9114 && (valid_len >= sizeof(*all_hdr))) {
9115 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9116 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9117 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9118 && (valid_len >= sizeof(*one))) {
9119 uint32_t cdb_length;
9121 one = (struct scsi_report_supported_opcodes_one *)buf;
9122 cdb_length = scsi_2btoul(one->cdb_length);
9123 avail_len = sizeof(*one) + cdb_length;
9124 if (one->support & RSO_ONE_CTDP) {
9125 struct scsi_report_supported_opcodes_timeout *td;
9127 td = (struct scsi_report_supported_opcodes_timeout *)
9129 if (valid_len >= (avail_len + sizeof(td->length))) {
9130 avail_len += scsi_2btoul(td->length) +
9133 avail_len += sizeof(*td);
9139 * avail_len could be zero if we didn't get enough data back from
9140 * thet target to determine
9142 if ((avail_len != 0)
9143 && (avail_len > valid_len)) {
9144 alloc_len = avail_len;
9148 *fill_len = valid_len;
9160 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9161 int req_sa, uint8_t *buf, uint32_t valid_len)
9163 struct scsi_report_supported_opcodes_one *one;
9164 struct scsi_report_supported_opcodes_timeout *td;
9165 uint32_t cdb_len = 0, td_len = 0;
9166 const char *op_desc = NULL;
9170 one = (struct scsi_report_supported_opcodes_one *)buf;
9173 * If we don't have the full single opcode descriptor, no point in
9176 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9178 warnx("Only %u bytes returned, not enough to verify support",
9184 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9186 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9189 printf(", SA 0x%x", req_sa);
9192 switch (one->support & RSO_ONE_SUP_MASK) {
9193 case RSO_ONE_SUP_UNAVAIL:
9194 printf("No command support information currently available\n");
9196 case RSO_ONE_SUP_NOT_SUP:
9197 printf("Command not supported\n");
9200 break; /*NOTREACHED*/
9201 case RSO_ONE_SUP_AVAIL:
9202 printf("Command is supported, complies with a SCSI standard\n");
9204 case RSO_ONE_SUP_VENDOR:
9205 printf("Command is supported, vendor-specific "
9206 "implementation\n");
9209 printf("Unknown command support flags 0x%#x\n",
9210 one->support & RSO_ONE_SUP_MASK);
9215 * If we don't have the CDB length, it isn't exactly an error, the
9216 * command probably isn't supported.
9218 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9222 cdb_len = scsi_2btoul(one->cdb_length);
9225 * If our valid data doesn't include the full reported length,
9226 * return. The caller should have detected this and adjusted his
9227 * allocation length to get all of the available data.
9229 if (valid_len < sizeof(*one) + cdb_len) {
9235 * If all we have is the opcode, there is no point in printing out
9243 printf("CDB usage bitmap:");
9244 for (i = 0; i < cdb_len; i++) {
9245 printf(" %02x", one->cdb_usage[i]);
9250 * If we don't have a timeout descriptor, we're done.
9252 if ((one->support & RSO_ONE_CTDP) == 0)
9256 * If we don't have enough valid length to include the timeout
9257 * descriptor length, we're done.
9259 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9262 td = (struct scsi_report_supported_opcodes_timeout *)
9263 &buf[sizeof(*one) + cdb_len];
9264 td_len = scsi_2btoul(td->length);
9265 td_len += sizeof(td->length);
9268 * If we don't have the full timeout descriptor, we're done.
9270 if (td_len < sizeof(*td))
9274 * If we don't have enough valid length to contain the full timeout
9275 * descriptor, we're done.
9277 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9280 printf("Timeout information:\n");
9281 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9282 printf("Nominal timeout: %u seconds\n",
9283 scsi_4btoul(td->nominal_time));
9284 printf("Recommended timeout: %u seconds\n",
9285 scsi_4btoul(td->recommended_time));
9292 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9295 struct scsi_report_supported_opcodes_all *hdr;
9296 struct scsi_report_supported_opcodes_descr *desc;
9297 uint32_t avail_len = 0, used_len = 0;
9301 if (valid_len < sizeof(*hdr)) {
9302 warnx("%s: not enough returned data (%u bytes) opcode list",
9303 __func__, valid_len);
9307 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9308 avail_len = scsi_4btoul(hdr->length);
9309 avail_len += sizeof(hdr->length);
9311 * Take the lesser of the amount of data the drive claims is
9312 * available, and the amount of data the HBA says was returned.
9314 avail_len = MIN(avail_len, valid_len);
9316 used_len = sizeof(hdr->length);
9318 printf("%-6s %4s %8s ",
9319 "Opcode", "SA", "CDB len" );
9322 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9323 printf(" Description\n");
9325 while ((avail_len - used_len) > sizeof(*desc)) {
9326 struct scsi_report_supported_opcodes_timeout *td;
9328 const char *op_desc = NULL;
9330 cur_ptr = &buf[used_len];
9331 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9333 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9334 if (op_desc == NULL)
9335 op_desc = "UNKNOWN";
9337 printf("0x%02x %#4x %8u ", desc->opcode,
9338 scsi_2btoul(desc->service_action),
9339 scsi_2btoul(desc->cdb_length));
9341 used_len += sizeof(*desc);
9343 if ((desc->flags & RSO_CTDP) == 0) {
9344 printf(" %s\n", op_desc);
9349 * If we don't have enough space to fit a timeout
9350 * descriptor, then we're done.
9352 if (avail_len - used_len < sizeof(*td)) {
9353 used_len = avail_len;
9354 printf(" %s\n", op_desc);
9357 cur_ptr = &buf[used_len];
9358 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9359 td_len = scsi_2btoul(td->length);
9360 td_len += sizeof(td->length);
9364 * If the given timeout descriptor length is less than what
9365 * we understand, skip it.
9367 if (td_len < sizeof(*td)) {
9368 printf(" %s\n", op_desc);
9372 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9373 scsi_4btoul(td->nominal_time),
9374 scsi_4btoul(td->recommended_time), op_desc);
9381 scsiopcodes(struct cam_device *device, int argc, char **argv,
9382 char *combinedopt, int task_attr, int retry_count, int timeout,
9386 uint32_t opcode = 0, service_action = 0;
9387 int td_set = 0, opcode_set = 0, sa_set = 0;
9388 int show_sa_errors = 1;
9389 uint32_t valid_len = 0;
9390 uint8_t *buf = NULL;
9394 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9400 opcode = strtoul(optarg, &endptr, 0);
9401 if (*endptr != '\0') {
9402 warnx("Invalid opcode \"%s\", must be a number",
9407 if (opcode > 0xff) {
9408 warnx("Invalid opcode 0x%#x, must be between"
9409 "0 and 0xff inclusive", opcode);
9416 service_action = strtoul(optarg, &endptr, 0);
9417 if (*endptr != '\0') {
9418 warnx("Invalid service action \"%s\", must "
9419 "be a number", optarg);
9423 if (service_action > 0xffff) {
9424 warnx("Invalid service action 0x%#x, must "
9425 "be between 0 and 0xffff inclusive",
9440 && (opcode_set == 0)) {
9441 warnx("You must specify an opcode with -o if a service "
9446 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9447 sa_set, service_action, td_set, task_attr,
9448 retry_count, timeout, verbosemode, &valid_len,
9453 if ((opcode_set != 0)
9455 retval = scsiprintoneopcode(device, opcode, sa_set,
9456 service_action, buf, valid_len);
9458 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9467 #endif /* MINIMALISTIC */
9470 scsireprobe(struct cam_device *device)
9475 ccb = cam_getccb(device);
9478 warnx("%s: error allocating ccb", __func__);
9482 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9484 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9486 if (cam_send_ccb(device, ccb) < 0) {
9487 warn("error sending XPT_REPROBE_LUN CCB");
9492 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9493 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9505 usage(int printlong)
9508 fprintf(printlong ? stdout : stderr,
9509 "usage: camcontrol <command> [device id][generic args][command args]\n"
9510 " camcontrol devlist [-b] [-v]\n"
9511 #ifndef MINIMALISTIC
9512 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9513 " camcontrol tur [dev_id][generic args]\n"
9514 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9515 " camcontrol identify [dev_id][generic args] [-v]\n"
9516 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9517 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9519 " camcontrol start [dev_id][generic args]\n"
9520 " camcontrol stop [dev_id][generic args]\n"
9521 " camcontrol load [dev_id][generic args]\n"
9522 " camcontrol eject [dev_id][generic args]\n"
9523 " camcontrol reprobe [dev_id][generic args]\n"
9524 #endif /* MINIMALISTIC */
9525 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9526 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9527 #ifndef MINIMALISTIC
9528 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9529 " [-q][-s][-S offset][-X]\n"
9530 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9531 " [-P pagectl][-e | -b][-d]\n"
9532 " camcontrol cmd [dev_id][generic args]\n"
9533 " <-a cmd [args] | -c cmd [args]>\n"
9534 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9535 " camcontrol smpcmd [dev_id][generic args]\n"
9536 " <-r len fmt [args]> <-R len fmt [args]>\n"
9537 " camcontrol smprg [dev_id][generic args][-l]\n"
9538 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9539 " [-o operation][-d name][-m rate][-M rate]\n"
9540 " [-T pp_timeout][-a enable|disable]\n"
9541 " [-A enable|disable][-s enable|disable]\n"
9542 " [-S enable|disable]\n"
9543 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9544 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9545 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9546 " <all|bus[:target[:lun]]|off>\n"
9547 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9548 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9549 " [-D <enable|disable>][-M mode][-O offset]\n"
9550 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9551 " [-U][-W bus_width]\n"
9552 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9553 " camcontrol sanitize [dev_id][generic args]\n"
9554 " [-a overwrite|block|crypto|exitfailure]\n"
9555 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9557 " camcontrol idle [dev_id][generic args][-t time]\n"
9558 " camcontrol standby [dev_id][generic args][-t time]\n"
9559 " camcontrol sleep [dev_id][generic args]\n"
9560 " camcontrol apm [dev_id][generic args][-l level]\n"
9561 " camcontrol aam [dev_id][generic args][-l level]\n"
9562 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9564 " camcontrol security [dev_id][generic args]\n"
9565 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9566 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9567 " [-U <user|master>] [-y]\n"
9568 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9569 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9570 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9571 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9572 " [-s scope][-S][-T type][-U]\n"
9573 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9574 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9575 " [-p part][-s start][-T type][-V vol]\n"
9576 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9578 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9579 " [-o rep_opts] [-P print_opts]\n"
9580 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9581 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9582 " [-S power_src] [-T timer]\n"
9583 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9584 " <-s <-f format -T time | -U >>\n"
9586 #endif /* MINIMALISTIC */
9587 " camcontrol help\n");
9590 #ifndef MINIMALISTIC
9592 "Specify one of the following options:\n"
9593 "devlist list all CAM devices\n"
9594 "periphlist list all CAM peripheral drivers attached to a device\n"
9595 "tur send a test unit ready to the named device\n"
9596 "inquiry send a SCSI inquiry command to the named device\n"
9597 "identify send a ATA identify command to the named device\n"
9598 "reportluns send a SCSI report luns command to the device\n"
9599 "readcap send a SCSI read capacity command to the device\n"
9600 "start send a Start Unit command to the device\n"
9601 "stop send a Stop Unit command to the device\n"
9602 "load send a Start Unit command to the device with the load bit set\n"
9603 "eject send a Stop Unit command to the device with the eject bit set\n"
9604 "reprobe update capacity information of the given device\n"
9605 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9606 "reset reset all buses, the given bus, bus:target:lun or device\n"
9607 "defects read the defect list of the specified device\n"
9608 "modepage display or edit (-e) the given mode page\n"
9609 "cmd send the given SCSI command, may need -i or -o as well\n"
9610 "smpcmd send the given SMP command, requires -o and -i\n"
9611 "smprg send the SMP Report General command\n"
9612 "smppc send the SMP PHY Control command, requires -p\n"
9613 "smpphylist display phys attached to a SAS expander\n"
9614 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9615 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9616 "tags report or set the number of transaction slots for a device\n"
9617 "negotiate report or set device negotiation parameters\n"
9618 "format send the SCSI FORMAT UNIT command to the named device\n"
9619 "sanitize send the SCSI SANITIZE command to the named device\n"
9620 "idle send the ATA IDLE command to the named device\n"
9621 "standby send the ATA STANDBY command to the named device\n"
9622 "sleep send the ATA SLEEP command to the named device\n"
9623 "fwdownload program firmware of the named device with the given image\n"
9624 "security report or send ATA security commands to the named device\n"
9625 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9626 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9627 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9628 "zone manage Zoned Block (Shingled) devices\n"
9629 "epc send ATA Extended Power Conditions commands\n"
9630 "timestamp report or set the device's timestamp\n"
9631 "help this message\n"
9632 "Device Identifiers:\n"
9633 "bus:target specify the bus and target, lun defaults to 0\n"
9634 "bus:target:lun specify the bus, target and lun\n"
9635 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
9636 "Generic arguments:\n"
9637 "-v be verbose, print out sense information\n"
9638 "-t timeout command timeout in seconds, overrides default timeout\n"
9639 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
9640 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
9641 "-E have the kernel attempt to perform SCSI error recovery\n"
9642 "-C count specify the SCSI command retry count (needs -E to work)\n"
9643 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
9644 "modepage arguments:\n"
9645 "-l list all available mode pages\n"
9646 "-m page specify the mode page to view or edit\n"
9647 "-e edit the specified mode page\n"
9648 "-b force view to binary mode\n"
9649 "-d disable block descriptors for mode sense\n"
9650 "-P pgctl page control field 0-3\n"
9651 "defects arguments:\n"
9652 "-f format specify defect list format (block, bfi or phys)\n"
9653 "-G get the grown defect list\n"
9654 "-P get the permanent defect list\n"
9655 "inquiry arguments:\n"
9656 "-D get the standard inquiry data\n"
9657 "-S get the serial number\n"
9658 "-R get the transfer rate, etc.\n"
9659 "reportluns arguments:\n"
9660 "-c only report a count of available LUNs\n"
9661 "-l only print out luns, and not a count\n"
9662 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
9663 "readcap arguments\n"
9664 "-b only report the blocksize\n"
9665 "-h human readable device size, base 2\n"
9666 "-H human readable device size, base 10\n"
9667 "-N print the number of blocks instead of last block\n"
9668 "-q quiet, print numbers only\n"
9669 "-s only report the last block/device size\n"
9671 "-c cdb [args] specify the SCSI CDB\n"
9672 "-i len fmt specify input data and input data format\n"
9673 "-o len fmt [args] specify output data and output data fmt\n"
9674 "smpcmd arguments:\n"
9675 "-r len fmt [args] specify the SMP command to be sent\n"
9676 "-R len fmt [args] specify SMP response format\n"
9677 "smprg arguments:\n"
9678 "-l specify the long response format\n"
9679 "smppc arguments:\n"
9680 "-p phy specify the PHY to operate on\n"
9681 "-l specify the long request/response format\n"
9682 "-o operation specify the phy control operation\n"
9683 "-d name set the attached device name\n"
9684 "-m rate set the minimum physical link rate\n"
9685 "-M rate set the maximum physical link rate\n"
9686 "-T pp_timeout set the partial pathway timeout value\n"
9687 "-a enable|disable enable or disable SATA slumber\n"
9688 "-A enable|disable enable or disable SATA partial phy power\n"
9689 "-s enable|disable enable or disable SAS slumber\n"
9690 "-S enable|disable enable or disable SAS partial phy power\n"
9691 "smpphylist arguments:\n"
9692 "-l specify the long response format\n"
9693 "-q only print phys with attached devices\n"
9694 "smpmaninfo arguments:\n"
9695 "-l specify the long response format\n"
9696 "debug arguments:\n"
9697 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
9698 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
9699 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
9700 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
9702 "-N tags specify the number of tags to use for this device\n"
9703 "-q be quiet, don't report the number of tags\n"
9704 "-v report a number of tag-related parameters\n"
9705 "negotiate arguments:\n"
9706 "-a send a test unit ready after negotiation\n"
9707 "-c report/set current negotiation settings\n"
9708 "-D <arg> \"enable\" or \"disable\" disconnection\n"
9709 "-M mode set ATA mode\n"
9710 "-O offset set command delay offset\n"
9711 "-q be quiet, don't report anything\n"
9712 "-R syncrate synchronization rate in MHz\n"
9713 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
9714 "-U report/set user negotiation settings\n"
9715 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
9716 "-v also print a Path Inquiry CCB for the controller\n"
9717 "format arguments:\n"
9718 "-q be quiet, don't print status messages\n"
9719 "-r run in report only mode\n"
9720 "-w don't send immediate format command\n"
9721 "-y don't ask any questions\n"
9722 "sanitize arguments:\n"
9723 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
9724 "-c passes overwrite passes to perform (1 to 31)\n"
9725 "-I invert overwrite pattern after each pass\n"
9726 "-P pattern path to overwrite pattern file\n"
9727 "-q be quiet, don't print status messages\n"
9728 "-r run in report only mode\n"
9729 "-U run operation in unrestricted completion exit mode\n"
9730 "-w don't send immediate sanitize command\n"
9731 "-y don't ask any questions\n"
9732 "idle/standby arguments:\n"
9733 "-t <arg> number of seconds before respective state.\n"
9734 "fwdownload arguments:\n"
9735 "-f fw_image path to firmware image file\n"
9736 "-q don't print informational messages, only errors\n"
9737 "-s run in simulation mode\n"
9738 "-v print info for every firmware segment sent to device\n"
9739 "-y don't ask any questions\n"
9740 "security arguments:\n"
9741 "-d pwd disable security using the given password for the selected\n"
9743 "-e pwd erase the device using the given pwd for the selected user\n"
9744 "-f freeze the security configuration of the specified device\n"
9745 "-h pwd enhanced erase the device using the given pwd for the\n"
9747 "-k pwd unlock the device using the given pwd for the selected\n"
9749 "-l <high|maximum> specifies which security level to set: high or maximum\n"
9750 "-q be quiet, do not print any status messages\n"
9751 "-s pwd password the device (enable security) using the given\n"
9752 " pwd for the selected user\n"
9753 "-T timeout overrides the timeout (seconds) used for erase operation\n"
9754 "-U <user|master> specifies which user to set: user or master\n"
9755 "-y don't ask any questions\n"
9757 "-f freeze the HPA configuration of the device\n"
9758 "-l lock the HPA configuration of the device\n"
9759 "-P make the HPA max sectors persist\n"
9760 "-p pwd Set the HPA configuration password required for unlock\n"
9762 "-q be quiet, do not print any status messages\n"
9763 "-s sectors configures the maximum user accessible sectors of the\n"
9765 "-U pwd unlock the HPA configuration of the device\n"
9766 "-y don't ask any questions\n"
9767 "persist arguments:\n"
9768 "-i action specify read_keys, read_reservation, report_cap, or\n"
9769 " read_full_status\n"
9770 "-o action specify register, register_ignore, reserve, release,\n"
9771 " clear, preempt, preempt_abort, register_move, replace_lost\n"
9772 "-a set the All Target Ports (ALL_TG_PT) bit\n"
9773 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
9774 "-k key specify the Reservation Key\n"
9775 "-K sa_key specify the Service Action Reservation Key\n"
9776 "-p set the Activate Persist Through Power Loss bit\n"
9777 "-R rtp specify the Relative Target Port\n"
9778 "-s scope specify the scope: lun, extent, element or a number\n"
9779 "-S specify Transport ID for register, requires -I\n"
9780 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
9781 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
9782 "-U unregister the current initiator for register_move\n"
9783 "attrib arguments:\n"
9784 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
9786 "-w attr specify an attribute to write, one -w argument per attr\n"
9787 "-a attr_num only display this attribute number\n"
9788 "-c get cached attributes\n"
9789 "-e elem_addr request attributes for the given element in a changer\n"
9790 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
9791 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
9792 " field_none, field_desc, field_num, field_size, field_rw\n"
9793 "-p partition request attributes for the given partition\n"
9794 "-s start_attr request attributes starting at the given number\n"
9795 "-T elem_type specify the element type (used with -e)\n"
9796 "-V logical_vol specify the logical volume ID\n"
9797 "opcodes arguments:\n"
9798 "-o opcode specify the individual opcode to list\n"
9799 "-s service_action specify the service action for the opcode\n"
9800 "-N do not return SCSI error for unsupported SA\n"
9801 "-T request nominal and recommended timeout values\n"
9803 "-c cmd required: rz, open, close, finish, or rwp\n"
9804 "-a apply the action to all zones\n"
9805 "-l LBA specify the zone starting LBA\n"
9806 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
9807 " closed, full, ro, offline, reset, nonseq, nonwp\n"
9808 "-P print_opt report zones printing: normal, summary, script\n"
9810 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
9811 " source, status, list\n"
9812 "-d disable power mode (timer, state)\n"
9813 "-D delayed entry (goto)\n"
9814 "-e enable power mode (timer, state)\n"
9815 "-H hold power mode (goto)\n"
9816 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
9818 "-P only display power mode (status)\n"
9819 "-r rst_src restore settings from: default, saved (restore)\n"
9820 "-s save mode (timer, state, restore)\n"
9821 "-S power_src set power source: battery, nonbattery (source)\n"
9822 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
9823 "timestamp arguments:\n"
9824 "-r report the timestamp of the device\n"
9825 "-f format report the timestamp of the device with the given\n"
9826 " strftime(3) format string\n"
9827 "-m report the timestamp of the device as milliseconds since\n"
9828 " January 1st, 1970\n"
9829 "-U report the time with UTC instead of the local time zone\n"
9830 "-s set the timestamp of the device\n"
9831 "-f format the format of the time string passed into strptime(3)\n"
9832 "-T time the time value passed into strptime(3)\n"
9833 "-U set the timestamp of the device to UTC time\n"
9835 #endif /* MINIMALISTIC */
9839 main(int argc, char **argv)
9842 char *device = NULL;
9844 struct cam_device *cam_dev = NULL;
9845 int timeout = 0, retry_count = 1;
9846 camcontrol_optret optreturn;
9848 const char *mainopt = "C:En:Q:t:u:v";
9849 const char *subopt = NULL;
9850 char combinedopt[256];
9851 int error = 0, optstart = 2;
9852 int task_attr = MSG_SIMPLE_Q_TAG;
9854 #ifndef MINIMALISTIC
9858 #endif /* MINIMALISTIC */
9860 cmdlist = CAM_CMD_NONE;
9861 arglist = CAM_ARG_NONE;
9869 * Get the base option.
9871 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
9873 if (optreturn == CC_OR_AMBIGUOUS) {
9874 warnx("ambiguous option %s", argv[1]);
9877 } else if (optreturn == CC_OR_NOT_FOUND) {
9878 warnx("option %s not found", argv[1]);
9884 * Ahh, getopt(3) is a pain.
9886 * This is a gross hack. There really aren't many other good
9887 * options (excuse the pun) for parsing options in a situation like
9888 * this. getopt is kinda braindead, so you end up having to run
9889 * through the options twice, and give each invocation of getopt
9890 * the option string for the other invocation.
9892 * You would think that you could just have two groups of options.
9893 * The first group would get parsed by the first invocation of
9894 * getopt, and the second group would get parsed by the second
9895 * invocation of getopt. It doesn't quite work out that way. When
9896 * the first invocation of getopt finishes, it leaves optind pointing
9897 * to the argument _after_ the first argument in the second group.
9898 * So when the second invocation of getopt comes around, it doesn't
9899 * recognize the first argument it gets and then bails out.
9901 * A nice alternative would be to have a flag for getopt that says
9902 * "just keep parsing arguments even when you encounter an unknown
9903 * argument", but there isn't one. So there's no real clean way to
9904 * easily parse two sets of arguments without having one invocation
9905 * of getopt know about the other.
9907 * Without this hack, the first invocation of getopt would work as
9908 * long as the generic arguments are first, but the second invocation
9909 * (in the subfunction) would fail in one of two ways. In the case
9910 * where you don't set optreset, it would fail because optind may be
9911 * pointing to the argument after the one it should be pointing at.
9912 * In the case where you do set optreset, and reset optind, it would
9913 * fail because getopt would run into the first set of options, which
9914 * it doesn't understand.
9916 * All of this would "sort of" work if you could somehow figure out
9917 * whether optind had been incremented one option too far. The
9918 * mechanics of that, however, are more daunting than just giving
9919 * both invocations all of the expect options for either invocation.
9921 * Needless to say, I wouldn't mind if someone invented a better
9922 * (non-GPL!) command line parsing interface than getopt. I
9923 * wouldn't mind if someone added more knobs to getopt to make it
9924 * work better. Who knows, I may talk myself into doing it someday,
9925 * if the standards weenies let me. As it is, it just leads to
9926 * hackery like this and causes people to avoid it in some cases.
9928 * KDM, September 8th, 1998
9931 sprintf(combinedopt, "%s%s", mainopt, subopt);
9933 sprintf(combinedopt, "%s", mainopt);
9936 * For these options we do not parse optional device arguments and
9937 * we do not open a passthrough device.
9939 if ((cmdlist == CAM_CMD_RESCAN)
9940 || (cmdlist == CAM_CMD_RESET)
9941 || (cmdlist == CAM_CMD_DEVTREE)
9942 || (cmdlist == CAM_CMD_USAGE)
9943 || (cmdlist == CAM_CMD_DEBUG))
9946 #ifndef MINIMALISTIC
9948 && (argc > 2 && argv[2][0] != '-')) {
9952 if (isdigit(argv[2][0])) {
9953 /* device specified as bus:target[:lun] */
9954 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9956 errx(1, "numeric device specification must "
9957 "be either bus:target, or "
9959 /* default to 0 if lun was not specified */
9960 if ((arglist & CAM_ARG_LUN) == 0) {
9962 arglist |= CAM_ARG_LUN;
9966 if (cam_get_device(argv[2], name, sizeof name, &unit)
9968 errx(1, "%s", cam_errbuf);
9969 device = strdup(name);
9970 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
9974 #endif /* MINIMALISTIC */
9976 * Start getopt processing at argv[2/3], since we've already
9977 * accepted argv[1..2] as the command name, and as a possible
9983 * Now we run through the argument list looking for generic
9984 * options, and ignoring options that possibly belong to
9987 while ((c = getopt(argc, argv, combinedopt))!= -1){
9990 retry_count = strtol(optarg, NULL, 0);
9991 if (retry_count < 0)
9992 errx(1, "retry count %d is < 0",
9994 arglist |= CAM_ARG_RETRIES;
9997 arglist |= CAM_ARG_ERR_RECOVER;
10000 arglist |= CAM_ARG_DEVICE;
10002 while (isspace(*tstr) && (*tstr != '\0'))
10004 device = (char *)strdup(tstr);
10008 int table_entry = 0;
10011 while (isspace(*tstr) && (*tstr != '\0'))
10013 if (isdigit(*tstr)) {
10014 task_attr = strtol(tstr, &endptr, 0);
10015 if (*endptr != '\0') {
10016 errx(1, "Invalid queue option "
10021 scsi_nv_status status;
10023 table_size = sizeof(task_attrs) /
10024 sizeof(task_attrs[0]);
10025 status = scsi_get_nv(task_attrs,
10026 table_size, tstr, &table_entry,
10027 SCSI_NV_FLAG_IG_CASE);
10028 if (status == SCSI_NV_FOUND)
10029 task_attr = task_attrs[
10030 table_entry].value;
10032 errx(1, "%s option %s",
10033 (status == SCSI_NV_AMBIGUOUS)?
10034 "ambiguous" : "invalid",
10041 timeout = strtol(optarg, NULL, 0);
10043 errx(1, "invalid timeout %d", timeout);
10044 /* Convert the timeout from seconds to ms */
10046 arglist |= CAM_ARG_TIMEOUT;
10049 arglist |= CAM_ARG_UNIT;
10050 unit = strtol(optarg, NULL, 0);
10053 arglist |= CAM_ARG_VERBOSE;
10060 #ifndef MINIMALISTIC
10062 * For most commands we'll want to open the passthrough device
10063 * associated with the specified device. In the case of the rescan
10064 * commands, we don't use a passthrough device at all, just the
10065 * transport layer device.
10067 if (devopen == 1) {
10068 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10069 && (((arglist & CAM_ARG_DEVICE) == 0)
10070 || ((arglist & CAM_ARG_UNIT) == 0))) {
10071 errx(1, "subcommand \"%s\" requires a valid device "
10072 "identifier", argv[1]);
10075 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10076 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10077 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10079 errx(1,"%s", cam_errbuf);
10081 #endif /* MINIMALISTIC */
10084 * Reset optind to 2, and reset getopt, so these routines can parse
10085 * the arguments again.
10091 #ifndef MINIMALISTIC
10092 case CAM_CMD_DEVLIST:
10093 error = getdevlist(cam_dev);
10096 error = atahpa(cam_dev, retry_count, timeout,
10097 argc, argv, combinedopt);
10099 #endif /* MINIMALISTIC */
10100 case CAM_CMD_DEVTREE:
10101 error = getdevtree(argc, argv, combinedopt);
10103 #ifndef MINIMALISTIC
10105 error = testunitready(cam_dev, task_attr, retry_count,
10108 case CAM_CMD_INQUIRY:
10109 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10110 task_attr, retry_count, timeout);
10112 case CAM_CMD_IDENTIFY:
10113 error = identify(cam_dev, retry_count, timeout);
10115 case CAM_CMD_STARTSTOP:
10116 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10117 arglist & CAM_ARG_EJECT, task_attr,
10118 retry_count, timeout);
10120 #endif /* MINIMALISTIC */
10121 case CAM_CMD_RESCAN:
10122 error = dorescan_or_reset(argc, argv, 1);
10124 case CAM_CMD_RESET:
10125 error = dorescan_or_reset(argc, argv, 0);
10127 #ifndef MINIMALISTIC
10128 case CAM_CMD_READ_DEFECTS:
10129 error = readdefects(cam_dev, argc, argv, combinedopt,
10130 task_attr, retry_count, timeout);
10132 case CAM_CMD_MODE_PAGE:
10133 modepage(cam_dev, argc, argv, combinedopt,
10134 task_attr, retry_count, timeout);
10136 case CAM_CMD_SCSI_CMD:
10137 error = scsicmd(cam_dev, argc, argv, combinedopt,
10138 task_attr, retry_count, timeout);
10140 case CAM_CMD_MMCSD_CMD:
10141 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10142 retry_count, timeout);
10144 case CAM_CMD_SMP_CMD:
10145 error = smpcmd(cam_dev, argc, argv, combinedopt,
10146 retry_count, timeout);
10148 case CAM_CMD_SMP_RG:
10149 error = smpreportgeneral(cam_dev, argc, argv,
10150 combinedopt, retry_count,
10153 case CAM_CMD_SMP_PC:
10154 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10155 retry_count, timeout);
10157 case CAM_CMD_SMP_PHYLIST:
10158 error = smpphylist(cam_dev, argc, argv, combinedopt,
10159 retry_count, timeout);
10161 case CAM_CMD_SMP_MANINFO:
10162 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10163 retry_count, timeout);
10165 case CAM_CMD_DEBUG:
10166 error = camdebug(argc, argv, combinedopt);
10169 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10172 error = ratecontrol(cam_dev, task_attr, retry_count,
10173 timeout, argc, argv, combinedopt);
10175 case CAM_CMD_FORMAT:
10176 error = scsiformat(cam_dev, argc, argv,
10177 combinedopt, task_attr, retry_count,
10180 case CAM_CMD_REPORTLUNS:
10181 error = scsireportluns(cam_dev, argc, argv,
10182 combinedopt, task_attr,
10183 retry_count, timeout);
10185 case CAM_CMD_READCAP:
10186 error = scsireadcapacity(cam_dev, argc, argv,
10187 combinedopt, task_attr,
10188 retry_count, timeout);
10191 case CAM_CMD_STANDBY:
10192 case CAM_CMD_SLEEP:
10193 error = atapm(cam_dev, argc, argv,
10194 combinedopt, retry_count, timeout);
10198 error = ataaxm(cam_dev, argc, argv,
10199 combinedopt, retry_count, timeout);
10201 case CAM_CMD_SECURITY:
10202 error = atasecurity(cam_dev, retry_count, timeout,
10203 argc, argv, combinedopt);
10205 case CAM_CMD_DOWNLOAD_FW:
10206 error = fwdownload(cam_dev, argc, argv, combinedopt,
10207 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10210 case CAM_CMD_SANITIZE:
10211 error = scsisanitize(cam_dev, argc, argv,
10212 combinedopt, task_attr,
10213 retry_count, timeout);
10215 case CAM_CMD_PERSIST:
10216 error = scsipersist(cam_dev, argc, argv, combinedopt,
10217 task_attr, retry_count, timeout,
10218 arglist & CAM_ARG_VERBOSE,
10219 arglist & CAM_ARG_ERR_RECOVER);
10221 case CAM_CMD_ATTRIB:
10222 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10223 task_attr, retry_count, timeout,
10224 arglist & CAM_ARG_VERBOSE,
10225 arglist & CAM_ARG_ERR_RECOVER);
10227 case CAM_CMD_OPCODES:
10228 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10229 task_attr, retry_count, timeout,
10230 arglist & CAM_ARG_VERBOSE);
10232 case CAM_CMD_REPROBE:
10233 error = scsireprobe(cam_dev);
10236 error = zone(cam_dev, argc, argv, combinedopt,
10237 task_attr, retry_count, timeout,
10238 arglist & CAM_ARG_VERBOSE);
10241 error = epc(cam_dev, argc, argv, combinedopt,
10242 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10244 case CAM_CMD_TIMESTAMP:
10245 error = timestamp(cam_dev, argc, argv, combinedopt,
10246 task_attr, retry_count, timeout,
10247 arglist & CAM_ARG_VERBOSE);
10249 #endif /* MINIMALISTIC */
10250 case CAM_CMD_USAGE:
10259 if (cam_dev != NULL)
10260 cam_close_device(cam_dev);