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,
2295 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
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,
2315 /*sector_count*/(u_int8_t)
2316 sizeof(struct ata_params),
2317 /*data_ptr*/(u_int8_t *)ptr,
2318 /*dxfer_len*/sizeof(struct ata_params),
2319 /*timeout*/timeout ? timeout : 30 * 1000,
2329 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2330 ptr[i] = le16toh(ptr[i]);
2335 if (arglist & CAM_ARG_VERBOSE) {
2336 fprintf(stdout, "%s%d: Raw identify data:\n",
2337 device->device_name, device->dev_unit_num);
2338 dump_data(ptr, sizeof(struct ata_params));
2341 /* check for invalid (all zero) response */
2343 warnx("Invalid identify response detected");
2348 ident_buf = (struct ata_params *)ptr;
2349 if (strncmp(ident_buf->model, "FX", 2) &&
2350 strncmp(ident_buf->model, "NEC", 3) &&
2351 strncmp(ident_buf->model, "Pioneer", 7) &&
2352 strncmp(ident_buf->model, "SHARP", 5)) {
2353 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2354 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2355 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2356 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2358 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2359 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2360 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2361 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2362 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2363 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2364 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2365 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2366 sizeof(ident_buf->media_serial));
2368 *ident_bufp = ident_buf;
2375 ataidentify(struct cam_device *device, int retry_count, int timeout)
2378 struct ata_params *ident_buf;
2381 if ((ccb = cam_getccb(device)) == NULL) {
2382 warnx("couldn't allocate CCB");
2386 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2391 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2392 if (ata_read_native_max(device, retry_count, timeout, ccb,
2393 ident_buf, &hpasize) != 0) {
2401 printf("%s%d: ", device->device_name, device->dev_unit_num);
2402 ata_print_ident(ident_buf);
2403 camxferrate(device);
2404 atacapprint(ident_buf);
2405 atahpa_print(ident_buf, hpasize, 0);
2415 nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused)
2417 struct nvme_controller_data cdata;
2419 if (nvme_get_cdata(device, &cdata))
2421 nvme_print_controller(&cdata);
2428 identify(struct cam_device *device, int retry_count, int timeout)
2431 struct ccb_pathinq cpi;
2433 if (get_cpi(device, &cpi) != 0) {
2434 warnx("couldn't get CPI");
2438 if (cpi.protocol == PROTO_NVME) {
2439 return (nvmeidentify(device, retry_count, timeout));
2442 return (ataidentify(device, retry_count, timeout));
2444 #endif /* MINIMALISTIC */
2447 #ifndef MINIMALISTIC
2449 ATA_SECURITY_ACTION_PRINT,
2450 ATA_SECURITY_ACTION_FREEZE,
2451 ATA_SECURITY_ACTION_UNLOCK,
2452 ATA_SECURITY_ACTION_DISABLE,
2453 ATA_SECURITY_ACTION_ERASE,
2454 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2455 ATA_SECURITY_ACTION_SET_PASSWORD
2459 atasecurity_print_time(u_int16_t tw)
2463 printf("unspecified");
2465 printf("> 508 min");
2467 printf("%i min", 2 * tw);
2471 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2475 return 2 * 3600 * 1000; /* default: two hours */
2476 else if (timeout > 255)
2477 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2479 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2484 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2488 bzero(&cmd, sizeof(cmd));
2489 cmd.command = command;
2490 printf("Issuing %s", ata_op_string(&cmd));
2493 char pass[sizeof(pwd->password)+1];
2495 /* pwd->password may not be null terminated */
2496 pass[sizeof(pwd->password)] = '\0';
2497 strncpy(pass, pwd->password, sizeof(pwd->password));
2498 printf(" password='%s', user='%s'",
2500 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2503 if (command == ATA_SECURITY_SET_PASSWORD) {
2504 printf(", mode='%s'",
2505 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2506 "maximum" : "high");
2514 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2515 int retry_count, u_int32_t timeout, int quiet)
2519 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2521 return ata_do_28bit_cmd(device,
2524 /*flags*/CAM_DIR_NONE,
2525 /*protocol*/AP_PROTO_NON_DATA,
2526 /*tag_action*/MSG_SIMPLE_Q_TAG,
2527 /*command*/ATA_SECURITY_FREEZE_LOCK,
2538 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2539 int retry_count, u_int32_t timeout,
2540 struct ata_security_password *pwd, int quiet)
2544 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2546 return ata_do_28bit_cmd(device,
2549 /*flags*/CAM_DIR_OUT,
2550 /*protocol*/AP_PROTO_PIO_OUT,
2551 /*tag_action*/MSG_SIMPLE_Q_TAG,
2552 /*command*/ATA_SECURITY_UNLOCK,
2556 /*data_ptr*/(u_int8_t *)pwd,
2557 /*dxfer_len*/sizeof(*pwd),
2563 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2564 int retry_count, u_int32_t timeout,
2565 struct ata_security_password *pwd, int quiet)
2569 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2570 return ata_do_28bit_cmd(device,
2573 /*flags*/CAM_DIR_OUT,
2574 /*protocol*/AP_PROTO_PIO_OUT,
2575 /*tag_action*/MSG_SIMPLE_Q_TAG,
2576 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2580 /*data_ptr*/(u_int8_t *)pwd,
2581 /*dxfer_len*/sizeof(*pwd),
2588 atasecurity_erase_confirm(struct cam_device *device,
2589 struct ata_params* ident_buf)
2592 printf("\nYou are about to ERASE ALL DATA from the following"
2593 " device:\n%s%d,%s%d: ", device->device_name,
2594 device->dev_unit_num, device->given_dev_name,
2595 device->given_unit_number);
2596 ata_print_ident(ident_buf);
2600 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2602 if (fgets(str, sizeof(str), stdin) != NULL) {
2603 if (strncasecmp(str, "yes", 3) == 0) {
2605 } else if (strncasecmp(str, "no", 2) == 0) {
2608 printf("Please answer \"yes\" or "
2619 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2620 int retry_count, u_int32_t timeout,
2621 u_int32_t erase_timeout,
2622 struct ata_security_password *pwd, int quiet)
2627 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2629 error = ata_do_28bit_cmd(device,
2632 /*flags*/CAM_DIR_NONE,
2633 /*protocol*/AP_PROTO_NON_DATA,
2634 /*tag_action*/MSG_SIMPLE_Q_TAG,
2635 /*command*/ATA_SECURITY_ERASE_PREPARE,
2648 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2650 error = ata_do_28bit_cmd(device,
2653 /*flags*/CAM_DIR_OUT,
2654 /*protocol*/AP_PROTO_PIO_OUT,
2655 /*tag_action*/MSG_SIMPLE_Q_TAG,
2656 /*command*/ATA_SECURITY_ERASE_UNIT,
2660 /*data_ptr*/(u_int8_t *)pwd,
2661 /*dxfer_len*/sizeof(*pwd),
2662 /*timeout*/erase_timeout,
2665 if (error == 0 && quiet == 0)
2666 printf("\nErase Complete\n");
2672 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2673 int retry_count, u_int32_t timeout,
2674 struct ata_security_password *pwd, int quiet)
2678 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2680 return ata_do_28bit_cmd(device,
2683 /*flags*/CAM_DIR_OUT,
2684 /*protocol*/AP_PROTO_PIO_OUT,
2685 /*tag_action*/MSG_SIMPLE_Q_TAG,
2686 /*command*/ATA_SECURITY_SET_PASSWORD,
2690 /*data_ptr*/(u_int8_t *)pwd,
2691 /*dxfer_len*/sizeof(*pwd),
2697 atasecurity_print(struct ata_params *parm)
2700 printf("\nSecurity Option Value\n");
2701 if (arglist & CAM_ARG_VERBOSE) {
2702 printf("status %04x\n",
2703 parm->security_status);
2705 printf("supported %s\n",
2706 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2707 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2709 printf("enabled %s\n",
2710 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2711 printf("drive locked %s\n",
2712 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2713 printf("security config frozen %s\n",
2714 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2715 printf("count expired %s\n",
2716 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2717 printf("security level %s\n",
2718 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2719 printf("enhanced erase supported %s\n",
2720 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2721 printf("erase time ");
2722 atasecurity_print_time(parm->erase_time);
2724 printf("enhanced erase time ");
2725 atasecurity_print_time(parm->enhanced_erase_time);
2727 printf("master password rev %04x%s\n",
2728 parm->master_passwd_revision,
2729 parm->master_passwd_revision == 0x0000 ||
2730 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2734 * Validates and copies the password in optarg to the passed buffer.
2735 * If the password in optarg is the same length as the buffer then
2736 * the data will still be copied but no null termination will occur.
2739 ata_getpwd(u_int8_t *passwd, int max, char opt)
2743 len = strlen(optarg);
2745 warnx("-%c password is too long", opt);
2747 } else if (len == 0) {
2748 warnx("-%c password is missing", opt);
2750 } else if (optarg[0] == '-'){
2751 warnx("-%c password starts with '-' (generic arg?)", opt);
2753 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2754 warnx("-%c password conflicts with existing password from -%c",
2759 /* Callers pass in a buffer which does NOT need to be terminated */
2760 strncpy(passwd, optarg, max);
2767 ATA_HPA_ACTION_PRINT,
2768 ATA_HPA_ACTION_SET_MAX,
2769 ATA_HPA_ACTION_SET_PWD,
2770 ATA_HPA_ACTION_LOCK,
2771 ATA_HPA_ACTION_UNLOCK,
2772 ATA_HPA_ACTION_FREEZE_LOCK
2776 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2777 u_int64_t maxsize, int persist)
2779 printf("\nYou are about to configure HPA to limit the user accessible\n"
2780 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2781 persist ? "persistently" : "temporarily",
2782 device->device_name, device->dev_unit_num,
2783 device->given_dev_name, device->given_unit_number);
2784 ata_print_ident(ident_buf);
2788 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2790 if (NULL != fgets(str, sizeof(str), stdin)) {
2791 if (0 == strncasecmp(str, "yes", 3)) {
2793 } else if (0 == strncasecmp(str, "no", 2)) {
2796 printf("Please answer \"yes\" or "
2807 atahpa(struct cam_device *device, int retry_count, int timeout,
2808 int argc, char **argv, char *combinedopt)
2811 struct ata_params *ident_buf;
2812 struct ccb_getdev cgd;
2813 struct ata_set_max_pwd pwd;
2814 int error, confirm, quiet, c, action, actions, persist;
2815 int security, is48bit, pwdsize;
2816 u_int64_t hpasize, maxsize;
2825 memset(&pwd, 0, sizeof(pwd));
2827 /* default action is to print hpa information */
2828 action = ATA_HPA_ACTION_PRINT;
2829 pwdsize = sizeof(pwd.password);
2831 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2834 action = ATA_HPA_ACTION_SET_MAX;
2835 maxsize = strtoumax(optarg, NULL, 0);
2840 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2842 action = ATA_HPA_ACTION_SET_PWD;
2848 action = ATA_HPA_ACTION_LOCK;
2854 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2856 action = ATA_HPA_ACTION_UNLOCK;
2862 action = ATA_HPA_ACTION_FREEZE_LOCK;
2882 warnx("too many hpa actions specified");
2886 if (get_cgd(device, &cgd) != 0) {
2887 warnx("couldn't get CGD");
2891 ccb = cam_getccb(device);
2893 warnx("couldn't allocate CCB");
2897 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2904 printf("%s%d: ", device->device_name, device->dev_unit_num);
2905 ata_print_ident(ident_buf);
2906 camxferrate(device);
2909 if (action == ATA_HPA_ACTION_PRINT) {
2910 error = ata_read_native_max(device, retry_count, timeout, ccb,
2911 ident_buf, &hpasize);
2913 atahpa_print(ident_buf, hpasize, 1);
2920 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2921 warnx("HPA is not supported by this device");
2927 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2928 warnx("HPA Security is not supported by this device");
2934 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2937 * The ATA spec requires:
2938 * 1. Read native max addr is called directly before set max addr
2939 * 2. Read native max addr is NOT called before any other set max call
2942 case ATA_HPA_ACTION_SET_MAX:
2944 atahpa_set_confirm(device, ident_buf, maxsize,
2951 error = ata_read_native_max(device, retry_count, timeout,
2952 ccb, ident_buf, &hpasize);
2954 error = atahpa_set_max(device, retry_count, timeout,
2955 ccb, is48bit, maxsize, persist);
2957 /* redo identify to get new lba values */
2958 error = ata_do_identify(device, retry_count,
2961 atahpa_print(ident_buf, hpasize, 1);
2966 case ATA_HPA_ACTION_SET_PWD:
2967 error = atahpa_password(device, retry_count, timeout,
2968 ccb, is48bit, &pwd);
2970 printf("HPA password has been set\n");
2973 case ATA_HPA_ACTION_LOCK:
2974 error = atahpa_lock(device, retry_count, timeout,
2977 printf("HPA has been locked\n");
2980 case ATA_HPA_ACTION_UNLOCK:
2981 error = atahpa_unlock(device, retry_count, timeout,
2982 ccb, is48bit, &pwd);
2984 printf("HPA has been unlocked\n");
2987 case ATA_HPA_ACTION_FREEZE_LOCK:
2988 error = atahpa_freeze_lock(device, retry_count, timeout,
2991 printf("HPA has been frozen\n");
2995 errx(1, "Option currently not supported");
3005 atasecurity(struct cam_device *device, int retry_count, int timeout,
3006 int argc, char **argv, char *combinedopt)
3009 struct ata_params *ident_buf;
3010 int error, confirm, quiet, c, action, actions, setpwd;
3011 int security_enabled, erase_timeout, pwdsize;
3012 struct ata_security_password pwd;
3020 memset(&pwd, 0, sizeof(pwd));
3022 /* default action is to print security information */
3023 action = ATA_SECURITY_ACTION_PRINT;
3025 /* user is master by default as its safer that way */
3026 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3027 pwdsize = sizeof(pwd.password);
3029 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3032 action = ATA_SECURITY_ACTION_FREEZE;
3037 if (strcasecmp(optarg, "user") == 0) {
3038 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
3039 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
3040 } else if (strcasecmp(optarg, "master") == 0) {
3041 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3042 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
3044 warnx("-U argument '%s' is invalid (must be "
3045 "'user' or 'master')", optarg);
3051 if (strcasecmp(optarg, "high") == 0) {
3052 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3053 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3054 } else if (strcasecmp(optarg, "maximum") == 0) {
3055 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3056 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3058 warnx("-l argument '%s' is unknown (must be "
3059 "'high' or 'maximum')", optarg);
3065 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3067 action = ATA_SECURITY_ACTION_UNLOCK;
3072 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3074 action = ATA_SECURITY_ACTION_DISABLE;
3079 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3081 action = ATA_SECURITY_ACTION_ERASE;
3086 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3088 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3089 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3094 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3097 if (action == ATA_SECURITY_ACTION_PRINT)
3098 action = ATA_SECURITY_ACTION_SET_PASSWORD;
3100 * Don't increment action as this can be combined
3101 * with other actions.
3114 erase_timeout = atoi(optarg) * 1000;
3120 warnx("too many security actions specified");
3124 if ((ccb = cam_getccb(device)) == NULL) {
3125 warnx("couldn't allocate CCB");
3129 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3136 printf("%s%d: ", device->device_name, device->dev_unit_num);
3137 ata_print_ident(ident_buf);
3138 camxferrate(device);
3141 if (action == ATA_SECURITY_ACTION_PRINT) {
3142 atasecurity_print(ident_buf);
3148 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3149 warnx("Security not supported");
3155 /* default timeout 15 seconds the same as linux hdparm */
3156 timeout = timeout ? timeout : 15 * 1000;
3158 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3160 /* first set the password if requested */
3162 /* confirm we can erase before setting the password if erasing */
3164 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3165 action == ATA_SECURITY_ACTION_ERASE) &&
3166 atasecurity_erase_confirm(device, ident_buf) == 0) {
3172 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3173 pwd.revision = ident_buf->master_passwd_revision;
3174 if (pwd.revision != 0 && pwd.revision != 0xfff &&
3175 --pwd.revision == 0) {
3176 pwd.revision = 0xfffe;
3179 error = atasecurity_set_password(device, ccb, retry_count,
3180 timeout, &pwd, quiet);
3186 security_enabled = 1;
3190 case ATA_SECURITY_ACTION_FREEZE:
3191 error = atasecurity_freeze(device, ccb, retry_count,
3195 case ATA_SECURITY_ACTION_UNLOCK:
3196 if (security_enabled) {
3197 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3198 error = atasecurity_unlock(device, ccb,
3199 retry_count, timeout, &pwd, quiet);
3201 warnx("Can't unlock, drive is not locked");
3205 warnx("Can't unlock, security is disabled");
3210 case ATA_SECURITY_ACTION_DISABLE:
3211 if (security_enabled) {
3212 /* First unlock the drive if its locked */
3213 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3214 error = atasecurity_unlock(device, ccb,
3222 error = atasecurity_disable(device,
3230 warnx("Can't disable security (already disabled)");
3235 case ATA_SECURITY_ACTION_ERASE:
3236 if (security_enabled) {
3237 if (erase_timeout == 0) {
3238 erase_timeout = atasecurity_erase_timeout_msecs(
3239 ident_buf->erase_time);
3242 error = atasecurity_erase(device, ccb, retry_count,
3243 timeout, erase_timeout, &pwd, quiet);
3245 warnx("Can't secure erase (security is disabled)");
3250 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3251 if (security_enabled) {
3252 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3253 if (erase_timeout == 0) {
3255 atasecurity_erase_timeout_msecs(
3256 ident_buf->enhanced_erase_time);
3259 error = atasecurity_erase(device, ccb,
3260 retry_count, timeout,
3261 erase_timeout, &pwd,
3264 warnx("Enhanced erase is not supported");
3268 warnx("Can't secure erase (enhanced), "
3269 "(security is disabled)");
3280 #endif /* MINIMALISTIC */
3283 * Parse out a bus, or a bus, target and lun in the following
3289 * Returns the number of parsed components, or 0.
3292 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3293 cam_argmask *arglst)
3298 while (isspace(*tstr) && (*tstr != '\0'))
3301 tmpstr = (char *)strtok(tstr, ":");
3302 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3303 *bus = strtol(tmpstr, NULL, 0);
3304 *arglst |= CAM_ARG_BUS;
3306 tmpstr = (char *)strtok(NULL, ":");
3307 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3308 *target = strtol(tmpstr, NULL, 0);
3309 *arglst |= CAM_ARG_TARGET;
3311 tmpstr = (char *)strtok(NULL, ":");
3312 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3313 *lun = strtol(tmpstr, NULL, 0);
3314 *arglst |= CAM_ARG_LUN;
3324 dorescan_or_reset(int argc, char **argv, int rescan)
3326 static const char must[] =
3327 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3329 path_id_t bus = CAM_BUS_WILDCARD;
3330 target_id_t target = CAM_TARGET_WILDCARD;
3331 lun_id_t lun = CAM_LUN_WILDCARD;
3335 warnx(must, rescan? "rescan" : "reset");
3339 tstr = argv[optind];
3340 while (isspace(*tstr) && (*tstr != '\0'))
3342 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3343 arglist |= CAM_ARG_BUS;
3344 else if (isdigit(*tstr)) {
3345 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3346 if (rv != 1 && rv != 3) {
3347 warnx(must, rescan? "rescan" : "reset");
3357 * Note that resetting or rescanning a device used to
3358 * require a bus or bus:target:lun. This is because the
3359 * device in question may not exist and you're trying to
3360 * get the controller to rescan to find it. It may also be
3361 * because the device is hung / unresponsive, and opening
3362 * an unresponsive device is not desireable.
3364 * It can be more convenient to reference a device by
3365 * peripheral name and unit number, though, and it is
3366 * possible to get the bus:target:lun for devices that
3367 * currently exist in the EDT. So this can work for
3368 * devices that we want to reset, or devices that exist
3369 * that we want to rescan, but not devices that do not
3372 * So, we are careful here to look up the bus/target/lun
3373 * for the device the user wants to operate on, specified
3374 * by peripheral instance (e.g. da0, pass32) without
3375 * actually opening that device. The process is similar to
3376 * what cam_lookup_pass() does, except that we don't
3377 * actually open the passthrough driver instance in the end.
3380 if (cam_get_device(tstr, name, sizeof(name), &unit) == -1) {
3381 warnx("%s", cam_errbuf);
3386 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3387 warn("Unable to open %s", XPT_DEVICE);
3392 bzero(&ccb, sizeof(ccb));
3395 * The function code isn't strictly necessary for the
3396 * GETPASSTHRU ioctl.
3398 ccb.ccb_h.func_code = XPT_GDEVLIST;
3401 * These two are necessary for the GETPASSTHRU ioctl to
3404 strlcpy(ccb.cgdl.periph_name, name,
3405 sizeof(ccb.cgdl.periph_name));
3406 ccb.cgdl.unit_number = unit;
3409 * Attempt to get the passthrough device. This ioctl will
3410 * fail if the device name is null, if the device doesn't
3411 * exist, or if the passthrough driver isn't in the kernel.
3413 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3414 warn("Unable to find bus:target:lun for device %s%d",
3420 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3421 const struct cam_status_entry *entry;
3423 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3424 warnx("Unable to find bus:target_lun for device %s%d, "
3425 "CAM status: %s (%#x)", name, unit,
3426 entry ? entry->status_text : "Unknown",
3434 * The kernel fills in the bus/target/lun. We don't
3435 * need the passthrough device name and unit number since
3436 * we aren't going to open it.
3438 bus = ccb.ccb_h.path_id;
3439 target = ccb.ccb_h.target_id;
3440 lun = ccb.ccb_h.target_lun;
3442 arglist |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3447 if ((arglist & CAM_ARG_BUS)
3448 && (arglist & CAM_ARG_TARGET)
3449 && (arglist & CAM_ARG_LUN))
3450 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3452 error = rescan_or_reset_bus(bus, rescan);
3460 rescan_or_reset_bus(path_id_t bus, int rescan)
3462 union ccb *ccb = NULL, *matchccb = NULL;
3463 int fd = -1, retval;
3468 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3469 warnx("error opening transport layer device %s", XPT_DEVICE);
3470 warn("%s", XPT_DEVICE);
3474 ccb = malloc(sizeof(*ccb));
3476 warn("failed to allocate CCB");
3480 bzero(ccb, sizeof(*ccb));
3482 if (bus != CAM_BUS_WILDCARD) {
3483 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3484 ccb->ccb_h.path_id = bus;
3485 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3486 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3487 ccb->crcn.flags = CAM_FLAG_NONE;
3489 /* run this at a low priority */
3490 ccb->ccb_h.pinfo.priority = 5;
3492 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3493 warn("CAMIOCOMMAND ioctl failed");
3498 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3499 fprintf(stdout, "%s of bus %d was successful\n",
3500 rescan ? "Re-scan" : "Reset", bus);
3502 fprintf(stdout, "%s of bus %d returned error %#x\n",
3503 rescan ? "Re-scan" : "Reset", bus,
3504 ccb->ccb_h.status & CAM_STATUS_MASK);
3513 * The right way to handle this is to modify the xpt so that it can
3514 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3515 * that isn't implemented, so instead we enumerate the buses and
3516 * send the rescan or reset to those buses in the case where the
3517 * given bus is -1 (wildcard). We don't send a rescan or reset
3518 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3519 * no-op, sending a rescan to the xpt bus would result in a status of
3522 matchccb = malloc(sizeof(*matchccb));
3523 if (matchccb == NULL) {
3524 warn("failed to allocate CCB");
3528 bzero(matchccb, sizeof(*matchccb));
3529 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3530 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3531 bufsize = sizeof(struct dev_match_result) * 20;
3532 matchccb->cdm.match_buf_len = bufsize;
3533 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3534 if (matchccb->cdm.matches == NULL) {
3535 warnx("can't malloc memory for matches");
3539 matchccb->cdm.num_matches = 0;
3541 matchccb->cdm.num_patterns = 1;
3542 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3544 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3545 matchccb->cdm.pattern_buf_len);
3546 if (matchccb->cdm.patterns == NULL) {
3547 warnx("can't malloc memory for patterns");
3551 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3552 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3557 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3558 warn("CAMIOCOMMAND ioctl failed");
3563 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3564 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3565 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3566 warnx("got CAM error %#x, CDM error %d\n",
3567 matchccb->ccb_h.status, matchccb->cdm.status);
3572 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3573 struct bus_match_result *bus_result;
3575 /* This shouldn't happen. */
3576 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3579 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3582 * We don't want to rescan or reset the xpt bus.
3585 if (bus_result->path_id == CAM_XPT_PATH_ID)
3588 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3590 ccb->ccb_h.path_id = bus_result->path_id;
3591 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3592 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3593 ccb->crcn.flags = CAM_FLAG_NONE;
3595 /* run this at a low priority */
3596 ccb->ccb_h.pinfo.priority = 5;
3598 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3599 warn("CAMIOCOMMAND ioctl failed");
3604 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3605 fprintf(stdout, "%s of bus %d was successful\n",
3606 rescan? "Re-scan" : "Reset",
3607 bus_result->path_id);
3610 * Don't bail out just yet, maybe the other
3611 * rescan or reset commands will complete
3614 fprintf(stderr, "%s of bus %d returned error "
3615 "%#x\n", rescan? "Re-scan" : "Reset",
3616 bus_result->path_id,
3617 ccb->ccb_h.status & CAM_STATUS_MASK);
3621 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3622 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3629 if (matchccb != NULL) {
3630 free(matchccb->cdm.patterns);
3631 free(matchccb->cdm.matches);
3640 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3643 struct cam_device *device;
3648 if (bus == CAM_BUS_WILDCARD) {
3649 warnx("invalid bus number %d", bus);
3653 if (target == CAM_TARGET_WILDCARD) {
3654 warnx("invalid target number %d", target);
3658 if (lun == CAM_LUN_WILDCARD) {
3659 warnx("invalid lun number %jx", (uintmax_t)lun);
3665 bzero(&ccb, sizeof(union ccb));
3668 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3669 warnx("error opening transport layer device %s\n",
3671 warn("%s", XPT_DEVICE);
3675 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3676 if (device == NULL) {
3677 warnx("%s", cam_errbuf);
3682 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3683 ccb.ccb_h.path_id = bus;
3684 ccb.ccb_h.target_id = target;
3685 ccb.ccb_h.target_lun = lun;
3686 ccb.ccb_h.timeout = 5000;
3687 ccb.crcn.flags = CAM_FLAG_NONE;
3689 /* run this at a low priority */
3690 ccb.ccb_h.pinfo.priority = 5;
3693 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3694 warn("CAMIOCOMMAND ioctl failed");
3699 if (cam_send_ccb(device, &ccb) < 0) {
3700 warn("error sending XPT_RESET_DEV CCB");
3701 cam_close_device(device);
3709 cam_close_device(device);
3712 * An error code of CAM_BDR_SENT is normal for a BDR request.
3714 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3716 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3717 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3718 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3721 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3722 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3723 ccb.ccb_h.status & CAM_STATUS_MASK);
3728 #ifndef MINIMALISTIC
3730 static struct scsi_nv defect_list_type_map[] = {
3731 { "block", SRDD10_BLOCK_FORMAT },
3732 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3733 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3734 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3735 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3736 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3740 readdefects(struct cam_device *device, int argc, char **argv,
3741 char *combinedopt, int task_attr, int retry_count, int timeout)
3743 union ccb *ccb = NULL;
3744 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3745 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3746 size_t hdr_size = 0, entry_size = 0;
3749 u_int8_t *defect_list = NULL;
3750 u_int8_t list_format = 0;
3751 int list_type_set = 0;
3752 u_int32_t dlist_length = 0;
3753 u_int32_t returned_length = 0, valid_len = 0;
3754 u_int32_t num_returned = 0, num_valid = 0;
3755 u_int32_t max_possible_size = 0, hdr_max = 0;
3756 u_int32_t starting_offset = 0;
3757 u_int8_t returned_format, returned_type;
3759 int summary = 0, quiet = 0;
3761 int lists_specified = 0;
3762 int get_length = 1, first_pass = 1;
3765 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3769 scsi_nv_status status;
3772 status = scsi_get_nv(defect_list_type_map,
3773 sizeof(defect_list_type_map) /
3774 sizeof(defect_list_type_map[0]), optarg,
3775 &entry_num, SCSI_NV_FLAG_IG_CASE);
3777 if (status == SCSI_NV_FOUND) {
3778 list_format = defect_list_type_map[
3782 warnx("%s: %s %s option %s", __func__,
3783 (status == SCSI_NV_AMBIGUOUS) ?
3784 "ambiguous" : "invalid", "defect list type",
3787 goto defect_bailout;
3792 arglist |= CAM_ARG_GLIST;
3795 arglist |= CAM_ARG_PLIST;
3806 starting_offset = strtoul(optarg, &endptr, 0);
3807 if (*endptr != '\0') {
3809 warnx("invalid starting offset %s", optarg);
3810 goto defect_bailout;
3822 if (list_type_set == 0) {
3824 warnx("no defect list format specified");
3825 goto defect_bailout;
3828 if (arglist & CAM_ARG_PLIST) {
3829 list_format |= SRDD10_PLIST;
3833 if (arglist & CAM_ARG_GLIST) {
3834 list_format |= SRDD10_GLIST;
3839 * This implies a summary, and was the previous behavior.
3841 if (lists_specified == 0)
3844 ccb = cam_getccb(device);
3849 * We start off asking for just the header to determine how much
3850 * defect data is available. Some Hitachi drives return an error
3851 * if you ask for more data than the drive has. Once we know the
3852 * length, we retry the command with the returned length.
3854 if (use_12byte == 0)
3855 dlist_length = sizeof(*hdr10);
3857 dlist_length = sizeof(*hdr12);
3860 if (defect_list != NULL) {
3864 defect_list = malloc(dlist_length);
3865 if (defect_list == NULL) {
3866 warnx("can't malloc memory for defect list");
3868 goto defect_bailout;
3872 bzero(defect_list, dlist_length);
3875 * cam_getccb() zeros the CCB header only. So we need to zero the
3876 * payload portion of the ccb.
3878 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3880 scsi_read_defects(&ccb->csio,
3881 /*retries*/ retry_count,
3883 /*tag_action*/ task_attr,
3884 /*list_format*/ list_format,
3885 /*addr_desc_index*/ starting_offset,
3886 /*data_ptr*/ defect_list,
3887 /*dxfer_len*/ dlist_length,
3888 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3889 /*sense_len*/ SSD_FULL_SIZE,
3890 /*timeout*/ timeout ? timeout : 5000);
3892 /* Disable freezing the device queue */
3893 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3895 if (cam_send_ccb(device, ccb) < 0) {
3896 perror("error reading defect list");
3898 if (arglist & CAM_ARG_VERBOSE) {
3899 cam_error_print(device, ccb, CAM_ESF_ALL,
3900 CAM_EPF_ALL, stderr);
3904 goto defect_bailout;
3907 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3909 if (use_12byte == 0) {
3910 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3911 hdr_size = sizeof(*hdr10);
3912 hdr_max = SRDDH10_MAX_LENGTH;
3914 if (valid_len >= hdr_size) {
3915 returned_length = scsi_2btoul(hdr10->length);
3916 returned_format = hdr10->format;
3918 returned_length = 0;
3919 returned_format = 0;
3922 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3923 hdr_size = sizeof(*hdr12);
3924 hdr_max = SRDDH12_MAX_LENGTH;
3926 if (valid_len >= hdr_size) {
3927 returned_length = scsi_4btoul(hdr12->length);
3928 returned_format = hdr12->format;
3930 returned_length = 0;
3931 returned_format = 0;
3935 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3936 switch (returned_type) {
3937 case SRDD10_BLOCK_FORMAT:
3938 entry_size = sizeof(struct scsi_defect_desc_block);
3940 case SRDD10_LONG_BLOCK_FORMAT:
3941 entry_size = sizeof(struct scsi_defect_desc_long_block);
3943 case SRDD10_EXT_PHYS_FORMAT:
3944 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3945 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3947 case SRDD10_EXT_BFI_FORMAT:
3948 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3949 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3952 warnx("Unknown defect format 0x%x\n", returned_type);
3954 goto defect_bailout;
3958 max_possible_size = (hdr_max / entry_size) * entry_size;
3959 num_returned = returned_length / entry_size;
3960 num_valid = min(returned_length, valid_len - hdr_size);
3961 num_valid /= entry_size;
3963 if (get_length != 0) {
3966 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3967 CAM_SCSI_STATUS_ERROR) {
3968 struct scsi_sense_data *sense;
3969 int error_code, sense_key, asc, ascq;
3971 sense = &ccb->csio.sense_data;
3972 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3973 ccb->csio.sense_resid, &error_code, &sense_key,
3974 &asc, &ascq, /*show_errors*/ 1);
3977 * If the drive is reporting that it just doesn't
3978 * support the defect list format, go ahead and use
3979 * the length it reported. Otherwise, the length
3980 * may not be valid, so use the maximum.
3982 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3983 && (asc == 0x1c) && (ascq == 0x00)
3984 && (returned_length > 0)) {
3985 if ((use_12byte == 0)
3986 && (returned_length >= max_possible_size)) {
3991 dlist_length = returned_length + hdr_size;
3992 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3993 && (asc == 0x1f) && (ascq == 0x00)
3994 && (returned_length > 0)) {
3995 /* Partial defect list transfer */
3997 * Hitachi drives return this error
3998 * along with a partial defect list if they
3999 * have more defects than the 10 byte
4000 * command can support. Retry with the 12
4003 if (use_12byte == 0) {
4008 dlist_length = returned_length + hdr_size;
4009 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
4010 && (asc == 0x24) && (ascq == 0x00)) {
4011 /* Invalid field in CDB */
4013 * SBC-3 says that if the drive has more
4014 * defects than can be reported with the
4015 * 10 byte command, it should return this
4016 * error and no data. Retry with the 12
4019 if (use_12byte == 0) {
4024 dlist_length = returned_length + hdr_size;
4027 * If we got a SCSI error and no valid length,
4028 * just use the 10 byte maximum. The 12
4029 * byte maximum is too large.
4031 if (returned_length == 0)
4032 dlist_length = SRDD10_MAX_LENGTH;
4034 if ((use_12byte == 0)
4035 && (returned_length >=
4036 max_possible_size)) {
4041 dlist_length = returned_length +
4045 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4048 warnx("Error reading defect header");
4049 if (arglist & CAM_ARG_VERBOSE)
4050 cam_error_print(device, ccb, CAM_ESF_ALL,
4051 CAM_EPF_ALL, stderr);
4052 goto defect_bailout;
4054 if ((use_12byte == 0)
4055 && (returned_length >= max_possible_size)) {
4060 dlist_length = returned_length + hdr_size;
4063 fprintf(stdout, "%u", num_returned);
4065 fprintf(stdout, " defect%s",
4066 (num_returned != 1) ? "s" : "");
4068 fprintf(stdout, "\n");
4070 goto defect_bailout;
4074 * We always limit the list length to the 10-byte maximum
4075 * length (0xffff). The reason is that some controllers
4076 * can't handle larger I/Os, and we can transfer the entire
4077 * 10 byte list in one shot. For drives that support the 12
4078 * byte read defects command, we'll step through the list
4079 * by specifying a starting offset. For drives that don't
4080 * support the 12 byte command's starting offset, we'll
4081 * just display the first 64K.
4083 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4089 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4090 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4091 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4092 struct scsi_sense_data *sense;
4093 int error_code, sense_key, asc, ascq;
4095 sense = &ccb->csio.sense_data;
4096 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4097 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4098 &ascq, /*show_errors*/ 1);
4101 * According to the SCSI spec, if the disk doesn't support
4102 * the requested format, it will generally return a sense
4103 * key of RECOVERED ERROR, and an additional sense code
4104 * of "DEFECT LIST NOT FOUND". HGST drives also return
4105 * Primary/Grown defect list not found errors. So just
4106 * check for an ASC of 0x1c.
4108 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4110 const char *format_str;
4112 format_str = scsi_nv_to_str(defect_list_type_map,
4113 sizeof(defect_list_type_map) /
4114 sizeof(defect_list_type_map[0]),
4115 list_format & SRDD10_DLIST_FORMAT_MASK);
4116 warnx("requested defect format %s not available",
4117 format_str ? format_str : "unknown");
4119 format_str = scsi_nv_to_str(defect_list_type_map,
4120 sizeof(defect_list_type_map) /
4121 sizeof(defect_list_type_map[0]), returned_type);
4122 if (format_str != NULL) {
4123 warnx("Device returned %s format",
4127 warnx("Device returned unknown defect"
4128 " data format %#x", returned_type);
4129 goto defect_bailout;
4133 warnx("Error returned from read defect data command");
4134 if (arglist & CAM_ARG_VERBOSE)
4135 cam_error_print(device, ccb, CAM_ESF_ALL,
4136 CAM_EPF_ALL, stderr);
4137 goto defect_bailout;
4139 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4141 warnx("Error returned from read defect data command");
4142 if (arglist & CAM_ARG_VERBOSE)
4143 cam_error_print(device, ccb, CAM_ESF_ALL,
4144 CAM_EPF_ALL, stderr);
4145 goto defect_bailout;
4148 if (first_pass != 0) {
4149 fprintf(stderr, "Got %d defect", num_returned);
4151 if ((lists_specified == 0) || (num_returned == 0)) {
4152 fprintf(stderr, "s.\n");
4153 goto defect_bailout;
4154 } else if (num_returned == 1)
4155 fprintf(stderr, ":\n");
4157 fprintf(stderr, "s:\n");
4163 * XXX KDM I should probably clean up the printout format for the
4166 switch (returned_type) {
4167 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4168 case SRDD10_EXT_PHYS_FORMAT:
4170 struct scsi_defect_desc_phys_sector *dlist;
4172 dlist = (struct scsi_defect_desc_phys_sector *)
4173 (defect_list + hdr_size);
4175 for (i = 0; i < num_valid; i++) {
4178 sector = scsi_4btoul(dlist[i].sector);
4179 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4180 mads = (sector & SDD_EXT_PHYS_MADS) ?
4182 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4184 if (hex_format == 0)
4185 fprintf(stdout, "%d:%d:%d%s",
4186 scsi_3btoul(dlist[i].cylinder),
4188 scsi_4btoul(dlist[i].sector),
4189 mads ? " - " : "\n");
4191 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4192 scsi_3btoul(dlist[i].cylinder),
4194 scsi_4btoul(dlist[i].sector),
4195 mads ? " - " : "\n");
4198 if (num_valid < num_returned) {
4199 starting_offset += num_valid;
4204 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4205 case SRDD10_EXT_BFI_FORMAT:
4207 struct scsi_defect_desc_bytes_from_index *dlist;
4209 dlist = (struct scsi_defect_desc_bytes_from_index *)
4210 (defect_list + hdr_size);
4212 for (i = 0; i < num_valid; i++) {
4215 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4216 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4217 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4218 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4220 if (hex_format == 0)
4221 fprintf(stdout, "%d:%d:%d%s",
4222 scsi_3btoul(dlist[i].cylinder),
4224 scsi_4btoul(dlist[i].bytes_from_index),
4225 mads ? " - " : "\n");
4227 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4228 scsi_3btoul(dlist[i].cylinder),
4230 scsi_4btoul(dlist[i].bytes_from_index),
4231 mads ? " - " : "\n");
4235 if (num_valid < num_returned) {
4236 starting_offset += num_valid;
4241 case SRDDH10_BLOCK_FORMAT:
4243 struct scsi_defect_desc_block *dlist;
4245 dlist = (struct scsi_defect_desc_block *)
4246 (defect_list + hdr_size);
4248 for (i = 0; i < num_valid; i++) {
4249 if (hex_format == 0)
4250 fprintf(stdout, "%u\n",
4251 scsi_4btoul(dlist[i].address));
4253 fprintf(stdout, "0x%x\n",
4254 scsi_4btoul(dlist[i].address));
4257 if (num_valid < num_returned) {
4258 starting_offset += num_valid;
4264 case SRDD10_LONG_BLOCK_FORMAT:
4266 struct scsi_defect_desc_long_block *dlist;
4268 dlist = (struct scsi_defect_desc_long_block *)
4269 (defect_list + hdr_size);
4271 for (i = 0; i < num_valid; i++) {
4272 if (hex_format == 0)
4273 fprintf(stdout, "%ju\n",
4274 (uintmax_t)scsi_8btou64(
4277 fprintf(stdout, "0x%jx\n",
4278 (uintmax_t)scsi_8btou64(
4282 if (num_valid < num_returned) {
4283 starting_offset += num_valid;
4289 fprintf(stderr, "Unknown defect format 0x%x\n",
4296 if (defect_list != NULL)
4304 #endif /* MINIMALISTIC */
4308 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4312 ccb = cam_getccb(device);
4318 #ifndef MINIMALISTIC
4320 mode_sense(struct cam_device *device, int dbd, int pc, int page, int subpage,
4321 int task_attr, int retry_count, int timeout, u_int8_t *data,
4327 ccb = cam_getccb(device);
4330 errx(1, "mode_sense: couldn't allocate CCB");
4332 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4334 scsi_mode_sense_subpage(&ccb->csio,
4335 /* retries */ retry_count,
4337 /* tag_action */ task_attr,
4341 /* subpage */ subpage,
4342 /* param_buf */ data,
4343 /* param_len */ datalen,
4344 /* minimum_cmd_size */ 0,
4345 /* sense_len */ SSD_FULL_SIZE,
4346 /* timeout */ timeout ? timeout : 5000);
4348 if (arglist & CAM_ARG_ERR_RECOVER)
4349 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4351 /* Disable freezing the device queue */
4352 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4354 if (((retval = cam_send_ccb(device, ccb)) < 0)
4355 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4356 if (arglist & CAM_ARG_VERBOSE) {
4357 cam_error_print(device, ccb, CAM_ESF_ALL,
4358 CAM_EPF_ALL, stderr);
4361 cam_close_device(device);
4363 err(1, "error sending mode sense command");
4365 errx(1, "error sending mode sense command");
4372 mode_select(struct cam_device *device, int save_pages, int task_attr,
4373 int retry_count, int timeout, u_int8_t *data, int datalen)
4378 ccb = cam_getccb(device);
4381 errx(1, "mode_select: couldn't allocate CCB");
4383 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4385 scsi_mode_select(&ccb->csio,
4386 /* retries */ retry_count,
4388 /* tag_action */ task_attr,
4389 /* scsi_page_fmt */ 1,
4390 /* save_pages */ save_pages,
4391 /* param_buf */ data,
4392 /* param_len */ datalen,
4393 /* sense_len */ SSD_FULL_SIZE,
4394 /* timeout */ timeout ? timeout : 5000);
4396 if (arglist & CAM_ARG_ERR_RECOVER)
4397 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4399 /* Disable freezing the device queue */
4400 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4402 if (((retval = cam_send_ccb(device, ccb)) < 0)
4403 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4404 if (arglist & CAM_ARG_VERBOSE) {
4405 cam_error_print(device, ccb, CAM_ESF_ALL,
4406 CAM_EPF_ALL, stderr);
4409 cam_close_device(device);
4412 err(1, "error sending mode select command");
4414 errx(1, "error sending mode select command");
4422 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4423 int task_attr, int retry_count, int timeout)
4426 int c, page = -1, subpage = -1, pc = 0;
4427 int binary = 0, dbd = 0, edit = 0, list = 0;
4429 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4444 str_subpage = optarg;
4445 strsep(&str_subpage, ",");
4446 page = strtol(optarg, NULL, 0);
4448 subpage = strtol(str_subpage, NULL, 0);
4452 errx(1, "invalid mode page %d", page);
4454 errx(1, "invalid mode subpage %d", subpage);
4457 pc = strtol(optarg, NULL, 0);
4458 if ((pc < 0) || (pc > 3))
4459 errx(1, "invalid page control field %d", pc);
4466 if (page == -1 && list == 0)
4467 errx(1, "you must specify a mode page!");
4470 mode_list(device, dbd, pc, list > 1, task_attr, retry_count,
4473 mode_edit(device, dbd, pc, page, subpage, edit, binary,
4474 task_attr, retry_count, timeout);
4479 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4480 int task_attr, int retry_count, int timeout)
4483 u_int32_t flags = CAM_DIR_NONE;
4484 u_int8_t *data_ptr = NULL;
4486 u_int8_t atacmd[12];
4487 struct get_hook hook;
4488 int c, data_bytes = 0, valid_bytes;
4494 char *datastr = NULL, *tstr, *resstr = NULL;
4496 int fd_data = 0, fd_res = 0;
4499 ccb = cam_getccb(device);
4502 warnx("scsicmd: error allocating ccb");
4506 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4508 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4512 while (isspace(*tstr) && (*tstr != '\0'))
4514 hook.argc = argc - optind;
4515 hook.argv = argv + optind;
4517 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4520 * Increment optind by the number of arguments the
4521 * encoding routine processed. After each call to
4522 * getopt(3), optind points to the argument that
4523 * getopt should process _next_. In this case,
4524 * that means it points to the first command string
4525 * argument, if there is one. Once we increment
4526 * this, it should point to either the next command
4527 * line argument, or it should be past the end of
4534 while (isspace(*tstr) && (*tstr != '\0'))
4536 hook.argc = argc - optind;
4537 hook.argv = argv + optind;
4539 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4542 * Increment optind by the number of arguments the
4543 * encoding routine processed. After each call to
4544 * getopt(3), optind points to the argument that
4545 * getopt should process _next_. In this case,
4546 * that means it points to the first command string
4547 * argument, if there is one. Once we increment
4548 * this, it should point to either the next command
4549 * line argument, or it should be past the end of
4561 if (arglist & CAM_ARG_CMD_OUT) {
4562 warnx("command must either be "
4563 "read or write, not both");
4565 goto scsicmd_bailout;
4567 arglist |= CAM_ARG_CMD_IN;
4569 data_bytes = strtol(optarg, NULL, 0);
4570 if (data_bytes <= 0) {
4571 warnx("invalid number of input bytes %d",
4574 goto scsicmd_bailout;
4576 hook.argc = argc - optind;
4577 hook.argv = argv + optind;
4580 datastr = cget(&hook, NULL);
4582 * If the user supplied "-" instead of a format, he
4583 * wants the data to be written to stdout.
4585 if ((datastr != NULL)
4586 && (datastr[0] == '-'))
4589 data_ptr = (u_int8_t *)malloc(data_bytes);
4590 if (data_ptr == NULL) {
4591 warnx("can't malloc memory for data_ptr");
4593 goto scsicmd_bailout;
4597 if (arglist & CAM_ARG_CMD_IN) {
4598 warnx("command must either be "
4599 "read or write, not both");
4601 goto scsicmd_bailout;
4603 arglist |= CAM_ARG_CMD_OUT;
4604 flags = CAM_DIR_OUT;
4605 data_bytes = strtol(optarg, NULL, 0);
4606 if (data_bytes <= 0) {
4607 warnx("invalid number of output bytes %d",
4610 goto scsicmd_bailout;
4612 hook.argc = argc - optind;
4613 hook.argv = argv + optind;
4615 datastr = cget(&hook, NULL);
4616 data_ptr = (u_int8_t *)malloc(data_bytes);
4617 if (data_ptr == NULL) {
4618 warnx("can't malloc memory for data_ptr");
4620 goto scsicmd_bailout;
4622 bzero(data_ptr, data_bytes);
4624 * If the user supplied "-" instead of a format, he
4625 * wants the data to be read from stdin.
4627 if ((datastr != NULL)
4628 && (datastr[0] == '-'))
4631 buff_encode_visit(data_ptr, data_bytes, datastr,
4637 hook.argc = argc - optind;
4638 hook.argv = argv + optind;
4640 resstr = cget(&hook, NULL);
4641 if ((resstr != NULL) && (resstr[0] == '-'))
4651 * If fd_data is set, and we're writing to the device, we need to
4652 * read the data the user wants written from stdin.
4654 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4656 int amt_to_read = data_bytes;
4657 u_int8_t *buf_ptr = data_ptr;
4659 for (amt_read = 0; amt_to_read > 0;
4660 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4661 if (amt_read == -1) {
4662 warn("error reading data from stdin");
4664 goto scsicmd_bailout;
4666 amt_to_read -= amt_read;
4667 buf_ptr += amt_read;
4671 if (arglist & CAM_ARG_ERR_RECOVER)
4672 flags |= CAM_PASS_ERR_RECOVER;
4674 /* Disable freezing the device queue */
4675 flags |= CAM_DEV_QFRZDIS;
4679 * This is taken from the SCSI-3 draft spec.
4680 * (T10/1157D revision 0.3)
4681 * The top 3 bits of an opcode are the group code.
4682 * The next 5 bits are the command code.
4683 * Group 0: six byte commands
4684 * Group 1: ten byte commands
4685 * Group 2: ten byte commands
4687 * Group 4: sixteen byte commands
4688 * Group 5: twelve byte commands
4689 * Group 6: vendor specific
4690 * Group 7: vendor specific
4692 switch((cdb[0] >> 5) & 0x7) {
4703 /* computed by buff_encode_visit */
4714 * We should probably use csio_build_visit or something like that
4715 * here, but it's easier to encode arguments as you go. The
4716 * alternative would be skipping the CDB argument and then encoding
4717 * it here, since we've got the data buffer argument by now.
4719 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4721 cam_fill_csio(&ccb->csio,
4722 /*retries*/ retry_count,
4725 /*tag_action*/ task_attr,
4726 /*data_ptr*/ data_ptr,
4727 /*dxfer_len*/ data_bytes,
4728 /*sense_len*/ SSD_FULL_SIZE,
4729 /*cdb_len*/ cdb_len,
4730 /*timeout*/ timeout ? timeout : 5000);
4733 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4735 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4737 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4739 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4741 cam_fill_ataio(&ccb->ataio,
4742 /*retries*/ retry_count,
4746 /*data_ptr*/ data_ptr,
4747 /*dxfer_len*/ data_bytes,
4748 /*timeout*/ timeout ? timeout : 5000);
4751 if (((retval = cam_send_ccb(device, ccb)) < 0)
4752 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4753 const char warnstr[] = "error sending command";
4760 if (arglist & CAM_ARG_VERBOSE) {
4761 cam_error_print(device, ccb, CAM_ESF_ALL,
4762 CAM_EPF_ALL, stderr);
4766 goto scsicmd_bailout;
4769 if (atacmd_len && need_res) {
4771 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4773 fprintf(stdout, "\n");
4776 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4777 ccb->ataio.res.status,
4778 ccb->ataio.res.error,
4779 ccb->ataio.res.lba_low,
4780 ccb->ataio.res.lba_mid,
4781 ccb->ataio.res.lba_high,
4782 ccb->ataio.res.device,
4783 ccb->ataio.res.lba_low_exp,
4784 ccb->ataio.res.lba_mid_exp,
4785 ccb->ataio.res.lba_high_exp,
4786 ccb->ataio.res.sector_count,
4787 ccb->ataio.res.sector_count_exp);
4793 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4795 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4796 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4797 && (arglist & CAM_ARG_CMD_IN)
4798 && (valid_bytes > 0)) {
4800 buff_decode_visit(data_ptr, valid_bytes, datastr,
4802 fprintf(stdout, "\n");
4804 ssize_t amt_written;
4805 int amt_to_write = valid_bytes;
4806 u_int8_t *buf_ptr = data_ptr;
4808 for (amt_written = 0; (amt_to_write > 0) &&
4809 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4810 amt_to_write -= amt_written;
4811 buf_ptr += amt_written;
4813 if (amt_written == -1) {
4814 warn("error writing data to stdout");
4816 goto scsicmd_bailout;
4817 } else if ((amt_written == 0)
4818 && (amt_to_write > 0)) {
4819 warnx("only wrote %u bytes out of %u",
4820 valid_bytes - amt_to_write, valid_bytes);
4827 if ((data_bytes > 0) && (data_ptr != NULL))
4836 camdebug(int argc, char **argv, char *combinedopt)
4839 path_id_t bus = CAM_BUS_WILDCARD;
4840 target_id_t target = CAM_TARGET_WILDCARD;
4841 lun_id_t lun = CAM_LUN_WILDCARD;
4842 char *tstr, *tmpstr = NULL;
4846 bzero(&ccb, sizeof(union ccb));
4848 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4851 arglist |= CAM_ARG_DEBUG_INFO;
4852 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4855 arglist |= CAM_ARG_DEBUG_PERIPH;
4856 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4859 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4860 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4863 arglist |= CAM_ARG_DEBUG_TRACE;
4864 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4867 arglist |= CAM_ARG_DEBUG_XPT;
4868 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4871 arglist |= CAM_ARG_DEBUG_CDB;
4872 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4875 arglist |= CAM_ARG_DEBUG_PROBE;
4876 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4883 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4884 warnx("error opening transport layer device %s", XPT_DEVICE);
4885 warn("%s", XPT_DEVICE);
4892 warnx("you must specify \"off\", \"all\" or a bus,");
4893 warnx("bus:target, or bus:target:lun");
4900 while (isspace(*tstr) && (*tstr != '\0'))
4903 if (strncmp(tstr, "off", 3) == 0) {
4904 ccb.cdbg.flags = CAM_DEBUG_NONE;
4905 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4906 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4907 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4908 } else if (strncmp(tstr, "all", 3) != 0) {
4909 tmpstr = (char *)strtok(tstr, ":");
4910 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4911 bus = strtol(tmpstr, NULL, 0);
4912 arglist |= CAM_ARG_BUS;
4913 tmpstr = (char *)strtok(NULL, ":");
4914 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4915 target = strtol(tmpstr, NULL, 0);
4916 arglist |= CAM_ARG_TARGET;
4917 tmpstr = (char *)strtok(NULL, ":");
4918 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4919 lun = strtol(tmpstr, NULL, 0);
4920 arglist |= CAM_ARG_LUN;
4925 warnx("you must specify \"all\", \"off\", or a bus,");
4926 warnx("bus:target, or bus:target:lun to debug");
4932 ccb.ccb_h.func_code = XPT_DEBUG;
4933 ccb.ccb_h.path_id = bus;
4934 ccb.ccb_h.target_id = target;
4935 ccb.ccb_h.target_lun = lun;
4937 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4938 warn("CAMIOCOMMAND ioctl failed");
4943 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4944 CAM_FUNC_NOTAVAIL) {
4945 warnx("CAM debugging not available");
4946 warnx("you need to put options CAMDEBUG in"
4947 " your kernel config file!");
4949 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4951 warnx("XPT_DEBUG CCB failed with status %#x",
4955 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4957 "Debugging turned off\n");
4960 "Debugging enabled for "
4962 bus, target, (uintmax_t)lun);
4973 tagcontrol(struct cam_device *device, int argc, char **argv,
4983 ccb = cam_getccb(device);
4986 warnx("tagcontrol: error allocating ccb");
4990 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4993 numtags = strtol(optarg, NULL, 0);
4995 warnx("tag count %d is < 0", numtags);
4997 goto tagcontrol_bailout;
5008 cam_path_string(device, pathstr, sizeof(pathstr));
5011 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
5012 ccb->ccb_h.func_code = XPT_REL_SIMQ;
5013 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5014 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5015 ccb->crs.openings = numtags;
5018 if (cam_send_ccb(device, ccb) < 0) {
5019 perror("error sending XPT_REL_SIMQ CCB");
5021 goto tagcontrol_bailout;
5024 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5025 warnx("XPT_REL_SIMQ CCB failed");
5026 cam_error_print(device, ccb, CAM_ESF_ALL,
5027 CAM_EPF_ALL, stderr);
5029 goto tagcontrol_bailout;
5034 fprintf(stdout, "%stagged openings now %d\n",
5035 pathstr, ccb->crs.openings);
5038 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5040 ccb->ccb_h.func_code = XPT_GDEV_STATS;
5042 if (cam_send_ccb(device, ccb) < 0) {
5043 perror("error sending XPT_GDEV_STATS CCB");
5045 goto tagcontrol_bailout;
5048 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5049 warnx("XPT_GDEV_STATS CCB failed");
5050 cam_error_print(device, ccb, CAM_ESF_ALL,
5051 CAM_EPF_ALL, stderr);
5053 goto tagcontrol_bailout;
5056 if (arglist & CAM_ARG_VERBOSE) {
5057 fprintf(stdout, "%s", pathstr);
5058 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5059 fprintf(stdout, "%s", pathstr);
5060 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5061 fprintf(stdout, "%s", pathstr);
5062 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5063 fprintf(stdout, "%s", pathstr);
5064 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5065 fprintf(stdout, "%s", pathstr);
5066 fprintf(stdout, "held %d\n", ccb->cgds.held);
5067 fprintf(stdout, "%s", pathstr);
5068 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5069 fprintf(stdout, "%s", pathstr);
5070 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5073 fprintf(stdout, "%s", pathstr);
5074 fprintf(stdout, "device openings: ");
5076 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5077 ccb->cgds.dev_active);
5087 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5091 cam_path_string(device, pathstr, sizeof(pathstr));
5093 if (cts->transport == XPORT_SPI) {
5094 struct ccb_trans_settings_spi *spi =
5095 &cts->xport_specific.spi;
5097 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5099 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5102 if (spi->sync_offset != 0) {
5105 freq = scsi_calc_syncsrate(spi->sync_period);
5106 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5107 pathstr, freq / 1000, freq % 1000);
5111 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5112 fprintf(stdout, "%soffset: %d\n", pathstr,
5116 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5117 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5118 (0x01 << spi->bus_width) * 8);
5121 if (spi->valid & CTS_SPI_VALID_DISC) {
5122 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5123 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5124 "enabled" : "disabled");
5127 if (cts->transport == XPORT_FC) {
5128 struct ccb_trans_settings_fc *fc =
5129 &cts->xport_specific.fc;
5131 if (fc->valid & CTS_FC_VALID_WWNN)
5132 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5133 (long long) fc->wwnn);
5134 if (fc->valid & CTS_FC_VALID_WWPN)
5135 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5136 (long long) fc->wwpn);
5137 if (fc->valid & CTS_FC_VALID_PORT)
5138 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5139 if (fc->valid & CTS_FC_VALID_SPEED)
5140 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5141 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5143 if (cts->transport == XPORT_SAS) {
5144 struct ccb_trans_settings_sas *sas =
5145 &cts->xport_specific.sas;
5147 if (sas->valid & CTS_SAS_VALID_SPEED)
5148 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5149 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5151 if (cts->transport == XPORT_ATA) {
5152 struct ccb_trans_settings_pata *pata =
5153 &cts->xport_specific.ata;
5155 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5156 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5157 ata_mode2string(pata->mode));
5159 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5160 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5163 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5164 fprintf(stdout, "%sPIO transaction length: %d\n",
5165 pathstr, pata->bytecount);
5168 if (cts->transport == XPORT_SATA) {
5169 struct ccb_trans_settings_sata *sata =
5170 &cts->xport_specific.sata;
5172 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5173 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5176 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5177 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5178 ata_mode2string(sata->mode));
5180 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5181 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5184 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5185 fprintf(stdout, "%sPIO transaction length: %d\n",
5186 pathstr, sata->bytecount);
5188 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5189 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5192 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5193 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5196 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5197 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5201 if (cts->protocol == PROTO_ATA) {
5202 struct ccb_trans_settings_ata *ata=
5203 &cts->proto_specific.ata;
5205 if (ata->valid & CTS_ATA_VALID_TQ) {
5206 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5207 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5208 "enabled" : "disabled");
5211 if (cts->protocol == PROTO_SCSI) {
5212 struct ccb_trans_settings_scsi *scsi=
5213 &cts->proto_specific.scsi;
5215 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5216 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5217 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5218 "enabled" : "disabled");
5222 if (cts->protocol == PROTO_NVME) {
5223 struct ccb_trans_settings_nvme *nvmex =
5224 &cts->xport_specific.nvme;
5226 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5227 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5228 NVME_MAJOR(nvmex->spec),
5229 NVME_MINOR(nvmex->spec));
5231 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5232 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5233 nvmex->lanes, nvmex->max_lanes);
5234 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5235 nvmex->speed, nvmex->max_speed);
5242 * Get a path inquiry CCB for the specified device.
5245 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5250 ccb = cam_getccb(device);
5252 warnx("get_cpi: couldn't allocate CCB");
5255 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5256 ccb->ccb_h.func_code = XPT_PATH_INQ;
5257 if (cam_send_ccb(device, ccb) < 0) {
5258 warn("get_cpi: error sending Path Inquiry CCB");
5259 if (arglist & CAM_ARG_VERBOSE)
5260 cam_error_print(device, ccb, CAM_ESF_ALL,
5261 CAM_EPF_ALL, stderr);
5263 goto get_cpi_bailout;
5265 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5266 if (arglist & CAM_ARG_VERBOSE)
5267 cam_error_print(device, ccb, CAM_ESF_ALL,
5268 CAM_EPF_ALL, stderr);
5270 goto get_cpi_bailout;
5272 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5280 * Get a get device CCB for the specified device.
5283 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5288 ccb = cam_getccb(device);
5290 warnx("get_cgd: couldn't allocate CCB");
5293 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5294 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5295 if (cam_send_ccb(device, ccb) < 0) {
5296 warn("get_cgd: error sending Path Inquiry CCB");
5297 if (arglist & CAM_ARG_VERBOSE)
5298 cam_error_print(device, ccb, CAM_ESF_ALL,
5299 CAM_EPF_ALL, stderr);
5301 goto get_cgd_bailout;
5303 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5304 if (arglist & CAM_ARG_VERBOSE)
5305 cam_error_print(device, ccb, CAM_ESF_ALL,
5306 CAM_EPF_ALL, stderr);
5308 goto get_cgd_bailout;
5310 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5318 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5322 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5323 int timeout, int verbosemode)
5325 union ccb *ccb = NULL;
5326 struct scsi_vpd_supported_page_list sup_pages;
5330 ccb = cam_getccb(dev);
5332 warn("Unable to allocate CCB");
5337 /* cam_getccb cleans up the header, caller has to zero the payload */
5338 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5340 bzero(&sup_pages, sizeof(sup_pages));
5342 scsi_inquiry(&ccb->csio,
5343 /*retries*/ retry_count,
5345 /* tag_action */ MSG_SIMPLE_Q_TAG,
5346 /* inq_buf */ (u_int8_t *)&sup_pages,
5347 /* inq_len */ sizeof(sup_pages),
5349 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5350 /* sense_len */ SSD_FULL_SIZE,
5351 /* timeout */ timeout ? timeout : 5000);
5353 /* Disable freezing the device queue */
5354 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5356 if (retry_count != 0)
5357 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5359 if (cam_send_ccb(dev, ccb) < 0) {
5366 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5367 if (verbosemode != 0)
5368 cam_error_print(dev, ccb, CAM_ESF_ALL,
5369 CAM_EPF_ALL, stderr);
5374 for (i = 0; i < sup_pages.length; i++) {
5375 if (sup_pages.list[i] == page_id) {
5388 * devtype is filled in with the type of device.
5389 * Returns 0 for success, non-zero for failure.
5392 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5393 int verbosemode, camcontrol_devtype *devtype)
5395 struct ccb_getdev cgd;
5398 retval = get_cgd(dev, &cgd);
5402 switch (cgd.protocol) {
5408 *devtype = CC_DT_ATA;
5410 break; /*NOTREACHED*/
5412 *devtype = CC_DT_UNKNOWN;
5414 break; /*NOTREACHED*/
5418 * Check for the ATA Information VPD page (0x89). If this is an
5419 * ATA device behind a SCSI to ATA translation layer, this VPD page
5420 * should be present.
5422 * If that VPD page isn't present, or we get an error back from the
5423 * INQUIRY command, we'll just treat it as a normal SCSI device.
5425 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5426 timeout, verbosemode);
5428 *devtype = CC_DT_ATA_BEHIND_SCSI;
5430 *devtype = CC_DT_SCSI;
5439 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5440 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5441 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5442 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5443 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5444 int is48bit, camcontrol_devtype devtype)
5448 if (devtype == CC_DT_ATA) {
5449 cam_fill_ataio(&ccb->ataio,
5450 /*retries*/ retry_count,
5453 /*tag_action*/ tag_action,
5454 /*data_ptr*/ data_ptr,
5455 /*dxfer_len*/ dxfer_len,
5456 /*timeout*/ timeout);
5457 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5458 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5461 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5464 if (auxiliary != 0) {
5465 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5466 ccb->ataio.aux = auxiliary;
5469 if (ata_flags & AP_FLAG_CHK_COND)
5470 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5472 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5473 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5474 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5475 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5477 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5478 protocol |= AP_EXTEND;
5480 retval = scsi_ata_pass(&ccb->csio,
5481 /*retries*/ retry_count,
5484 /*tag_action*/ tag_action,
5485 /*protocol*/ protocol,
5486 /*ata_flags*/ ata_flags,
5487 /*features*/ features,
5488 /*sector_count*/ sector_count,
5490 /*command*/ command,
5493 /*auxiliary*/ auxiliary,
5495 /*data_ptr*/ data_ptr,
5496 /*dxfer_len*/ dxfer_len,
5497 /*cdb_storage*/ cdb_storage,
5498 /*cdb_storage_len*/ cdb_storage_len,
5499 /*minimum_cmd_size*/ 0,
5500 /*sense_len*/ sense_len,
5501 /*timeout*/ timeout);
5508 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5509 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5513 switch (ccb->ccb_h.func_code) {
5516 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5519 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5520 * or 16 byte, and need to see what
5522 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5523 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5525 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5526 if ((opcode != ATA_PASS_12)
5527 && (opcode != ATA_PASS_16)) {
5529 warnx("%s: unsupported opcode %02x", __func__, opcode);
5533 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5535 /* Note: the _ccb() variant returns 0 for an error */
5542 switch (error_code) {
5543 case SSD_DESC_CURRENT_ERROR:
5544 case SSD_DESC_DEFERRED_ERROR: {
5545 struct scsi_sense_data_desc *sense;
5546 struct scsi_sense_ata_ret_desc *desc;
5549 sense = (struct scsi_sense_data_desc *)
5550 &ccb->csio.sense_data;
5552 desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len -
5553 ccb->csio.sense_resid, SSD_DESC_ATA);
5554 if (desc_ptr == NULL) {
5555 cam_error_print(dev, ccb, CAM_ESF_ALL,
5556 CAM_EPF_ALL, stderr);
5560 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5562 *error = desc->error;
5563 *count = (desc->count_15_8 << 8) |
5565 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5566 ((uint64_t)desc->lba_39_32 << 32) |
5567 ((uint64_t)desc->lba_31_24 << 24) |
5568 (desc->lba_23_16 << 16) |
5569 (desc->lba_15_8 << 8) |
5571 *device = desc->device;
5572 *status = desc->status;
5575 * If the extend bit isn't set, the result is for a
5576 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5577 * command without the extend bit set. This means
5578 * that the device is supposed to return 28-bit
5579 * status. The count field is only 8 bits, and the
5580 * LBA field is only 8 bits.
5582 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5588 case SSD_CURRENT_ERROR:
5589 case SSD_DEFERRED_ERROR: {
5591 struct scsi_sense_data_fixed *sense;
5594 * XXX KDM need to support fixed sense data.
5596 warnx("%s: Fixed sense data not supported yet",
5600 break; /*NOTREACHED*/
5611 struct ata_res *res;
5614 * In this case, we have an ATA command, and we need to
5615 * fill in the requested values from the result register
5618 res = &ccb->ataio.res;
5619 *error = res->error;
5620 *status = res->status;
5621 *device = res->device;
5622 *count = res->sector_count;
5623 *lba = (res->lba_high << 16) |
5624 (res->lba_mid << 8) |
5626 if (res->flags & CAM_ATAIO_48BIT) {
5627 *count |= (res->sector_count_exp << 8);
5628 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5629 ((uint64_t)res->lba_mid_exp << 32) |
5630 ((uint64_t)res->lba_high_exp << 40);
5632 *lba |= (res->device & 0xf) << 24;
5645 cpi_print(struct ccb_pathinq *cpi)
5647 char adapter_str[1024];
5650 snprintf(adapter_str, sizeof(adapter_str),
5651 "%s%d:", cpi->dev_name, cpi->unit_number);
5653 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5656 for (i = 1; i < UINT8_MAX; i = i << 1) {
5659 if ((i & cpi->hba_inquiry) == 0)
5662 fprintf(stdout, "%s supports ", adapter_str);
5666 str = "MDP message";
5669 str = "32 bit wide SCSI";
5672 str = "16 bit wide SCSI";
5675 str = "SDTR message";
5678 str = "linked CDBs";
5681 str = "tag queue messages";
5684 str = "soft reset alternative";
5687 str = "SATA Port Multiplier";
5690 str = "unknown PI bit set";
5693 fprintf(stdout, "%s\n", str);
5696 for (i = 1; i < UINT32_MAX; i = i << 1) {
5699 if ((i & cpi->hba_misc) == 0)
5702 fprintf(stdout, "%s ", adapter_str);
5706 str = "can understand ata_ext requests";
5709 str = "64bit extended LUNs supported";
5712 str = "bus scans from high ID to low ID";
5715 str = "removable devices not included in scan";
5717 case PIM_NOINITIATOR:
5718 str = "initiator role not supported";
5720 case PIM_NOBUSRESET:
5721 str = "user has disabled initial BUS RESET or"
5722 " controller is in target/mixed mode";
5725 str = "do not send 6-byte commands";
5728 str = "scan bus sequentially";
5731 str = "unmapped I/O supported";
5734 str = "does its own scanning";
5737 str = "unknown PIM bit set";
5740 fprintf(stdout, "%s\n", str);
5743 for (i = 1; i < UINT16_MAX; i = i << 1) {
5746 if ((i & cpi->target_sprt) == 0)
5749 fprintf(stdout, "%s supports ", adapter_str);
5752 str = "target mode processor mode";
5755 str = "target mode phase cog. mode";
5757 case PIT_DISCONNECT:
5758 str = "disconnects in target mode";
5761 str = "terminate I/O message in target mode";
5764 str = "group 6 commands in target mode";
5767 str = "group 7 commands in target mode";
5770 str = "unknown PIT bit set";
5774 fprintf(stdout, "%s\n", str);
5776 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5778 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5780 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5782 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5783 adapter_str, cpi->hpath_id);
5784 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5786 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5787 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5788 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5789 adapter_str, cpi->hba_vendor);
5790 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5791 adapter_str, cpi->hba_device);
5792 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5793 adapter_str, cpi->hba_subvendor);
5794 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5795 adapter_str, cpi->hba_subdevice);
5796 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5797 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5798 if (cpi->base_transfer_speed > 1000)
5799 fprintf(stdout, "%d.%03dMB/sec\n",
5800 cpi->base_transfer_speed / 1000,
5801 cpi->base_transfer_speed % 1000);
5803 fprintf(stdout, "%dKB/sec\n",
5804 (cpi->base_transfer_speed % 1000) * 1000);
5805 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5806 adapter_str, cpi->maxio);
5810 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5811 struct ccb_trans_settings *cts)
5817 ccb = cam_getccb(device);
5820 warnx("get_print_cts: error allocating ccb");
5824 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5826 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5828 if (user_settings == 0)
5829 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5831 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5833 if (cam_send_ccb(device, ccb) < 0) {
5834 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5835 if (arglist & CAM_ARG_VERBOSE)
5836 cam_error_print(device, ccb, CAM_ESF_ALL,
5837 CAM_EPF_ALL, stderr);
5839 goto get_print_cts_bailout;
5842 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5843 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5844 if (arglist & CAM_ARG_VERBOSE)
5845 cam_error_print(device, ccb, CAM_ESF_ALL,
5846 CAM_EPF_ALL, stderr);
5848 goto get_print_cts_bailout;
5852 cts_print(device, &ccb->cts);
5855 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5857 get_print_cts_bailout:
5865 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
5866 int timeout, int argc, char **argv, char *combinedopt)
5870 int user_settings = 0;
5872 int disc_enable = -1, tag_enable = -1;
5875 double syncrate = -1;
5878 int change_settings = 0, send_tur = 0;
5879 struct ccb_pathinq cpi;
5881 ccb = cam_getccb(device);
5883 warnx("ratecontrol: error allocating ccb");
5886 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5895 if (strncasecmp(optarg, "enable", 6) == 0)
5897 else if (strncasecmp(optarg, "disable", 7) == 0)
5900 warnx("-D argument \"%s\" is unknown", optarg);
5902 goto ratecontrol_bailout;
5904 change_settings = 1;
5907 mode = ata_string2mode(optarg);
5909 warnx("unknown mode '%s'", optarg);
5911 goto ratecontrol_bailout;
5913 change_settings = 1;
5916 offset = strtol(optarg, NULL, 0);
5918 warnx("offset value %d is < 0", offset);
5920 goto ratecontrol_bailout;
5922 change_settings = 1;
5928 syncrate = atof(optarg);
5930 warnx("sync rate %f is < 0", syncrate);
5932 goto ratecontrol_bailout;
5934 change_settings = 1;
5937 if (strncasecmp(optarg, "enable", 6) == 0)
5939 else if (strncasecmp(optarg, "disable", 7) == 0)
5942 warnx("-T argument \"%s\" is unknown", optarg);
5944 goto ratecontrol_bailout;
5946 change_settings = 1;
5952 bus_width = strtol(optarg, NULL, 0);
5953 if (bus_width < 0) {
5954 warnx("bus width %d is < 0", bus_width);
5956 goto ratecontrol_bailout;
5958 change_settings = 1;
5964 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5966 * Grab path inquiry information, so we can determine whether
5967 * or not the initiator is capable of the things that the user
5970 ccb->ccb_h.func_code = XPT_PATH_INQ;
5971 if (cam_send_ccb(device, ccb) < 0) {
5972 perror("error sending XPT_PATH_INQ CCB");
5973 if (arglist & CAM_ARG_VERBOSE) {
5974 cam_error_print(device, ccb, CAM_ESF_ALL,
5975 CAM_EPF_ALL, stderr);
5978 goto ratecontrol_bailout;
5980 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5981 warnx("XPT_PATH_INQ CCB failed");
5982 if (arglist & CAM_ARG_VERBOSE) {
5983 cam_error_print(device, ccb, CAM_ESF_ALL,
5984 CAM_EPF_ALL, stderr);
5987 goto ratecontrol_bailout;
5989 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5990 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5992 fprintf(stdout, "%s parameters:\n",
5993 user_settings ? "User" : "Current");
5995 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5997 goto ratecontrol_bailout;
5999 if (arglist & CAM_ARG_VERBOSE)
6002 if (change_settings) {
6003 int didsettings = 0;
6004 struct ccb_trans_settings_spi *spi = NULL;
6005 struct ccb_trans_settings_pata *pata = NULL;
6006 struct ccb_trans_settings_sata *sata = NULL;
6007 struct ccb_trans_settings_ata *ata = NULL;
6008 struct ccb_trans_settings_scsi *scsi = NULL;
6010 if (ccb->cts.transport == XPORT_SPI)
6011 spi = &ccb->cts.xport_specific.spi;
6012 if (ccb->cts.transport == XPORT_ATA)
6013 pata = &ccb->cts.xport_specific.ata;
6014 if (ccb->cts.transport == XPORT_SATA)
6015 sata = &ccb->cts.xport_specific.sata;
6016 if (ccb->cts.protocol == PROTO_ATA)
6017 ata = &ccb->cts.proto_specific.ata;
6018 if (ccb->cts.protocol == PROTO_SCSI)
6019 scsi = &ccb->cts.proto_specific.scsi;
6020 ccb->cts.xport_specific.valid = 0;
6021 ccb->cts.proto_specific.valid = 0;
6022 if (spi && disc_enable != -1) {
6023 spi->valid |= CTS_SPI_VALID_DISC;
6024 if (disc_enable == 0)
6025 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6027 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6030 if (tag_enable != -1) {
6031 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6032 warnx("HBA does not support tagged queueing, "
6033 "so you cannot modify tag settings");
6035 goto ratecontrol_bailout;
6038 ata->valid |= CTS_SCSI_VALID_TQ;
6039 if (tag_enable == 0)
6040 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6042 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6045 scsi->valid |= CTS_SCSI_VALID_TQ;
6046 if (tag_enable == 0)
6047 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6049 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6053 if (spi && offset != -1) {
6054 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6055 warnx("HBA is not capable of changing offset");
6057 goto ratecontrol_bailout;
6059 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6060 spi->sync_offset = offset;
6063 if (spi && syncrate != -1) {
6064 int prelim_sync_period;
6066 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6067 warnx("HBA is not capable of changing "
6070 goto ratecontrol_bailout;
6072 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6074 * The sync rate the user gives us is in MHz.
6075 * We need to translate it into KHz for this
6080 * Next, we calculate a "preliminary" sync period
6081 * in tenths of a nanosecond.
6084 prelim_sync_period = 0;
6086 prelim_sync_period = 10000000 / syncrate;
6088 scsi_calc_syncparam(prelim_sync_period);
6091 if (sata && syncrate != -1) {
6092 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6093 warnx("HBA is not capable of changing "
6096 goto ratecontrol_bailout;
6098 if (!user_settings) {
6099 warnx("You can modify only user rate "
6100 "settings for SATA");
6102 goto ratecontrol_bailout;
6104 sata->revision = ata_speed2revision(syncrate * 100);
6105 if (sata->revision < 0) {
6106 warnx("Invalid rate %f", syncrate);
6108 goto ratecontrol_bailout;
6110 sata->valid |= CTS_SATA_VALID_REVISION;
6113 if ((pata || sata) && mode != -1) {
6114 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6115 warnx("HBA is not capable of changing "
6118 goto ratecontrol_bailout;
6120 if (!user_settings) {
6121 warnx("You can modify only user mode "
6122 "settings for ATA/SATA");
6124 goto ratecontrol_bailout;
6128 pata->valid |= CTS_ATA_VALID_MODE;
6131 sata->valid |= CTS_SATA_VALID_MODE;
6136 * The bus_width argument goes like this:
6140 * Therefore, if you shift the number of bits given on the
6141 * command line right by 4, you should get the correct
6144 if (spi && bus_width != -1) {
6146 * We might as well validate things here with a
6147 * decipherable error message, rather than what
6148 * will probably be an indecipherable error message
6149 * by the time it gets back to us.
6151 if ((bus_width == 16)
6152 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6153 warnx("HBA does not support 16 bit bus width");
6155 goto ratecontrol_bailout;
6156 } else if ((bus_width == 32)
6157 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6158 warnx("HBA does not support 32 bit bus width");
6160 goto ratecontrol_bailout;
6161 } else if ((bus_width != 8)
6162 && (bus_width != 16)
6163 && (bus_width != 32)) {
6164 warnx("Invalid bus width %d", bus_width);
6166 goto ratecontrol_bailout;
6168 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6169 spi->bus_width = bus_width >> 4;
6172 if (didsettings == 0) {
6173 goto ratecontrol_bailout;
6175 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6176 if (cam_send_ccb(device, ccb) < 0) {
6177 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
6178 if (arglist & CAM_ARG_VERBOSE) {
6179 cam_error_print(device, ccb, CAM_ESF_ALL,
6180 CAM_EPF_ALL, stderr);
6183 goto ratecontrol_bailout;
6185 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6186 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6187 if (arglist & CAM_ARG_VERBOSE) {
6188 cam_error_print(device, ccb, CAM_ESF_ALL,
6189 CAM_EPF_ALL, stderr);
6192 goto ratecontrol_bailout;
6196 retval = testunitready(device, task_attr, retry_count, timeout,
6197 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6199 * If the TUR didn't succeed, just bail.
6203 fprintf(stderr, "Test Unit Ready failed\n");
6204 goto ratecontrol_bailout;
6207 if ((change_settings || send_tur) && !quiet &&
6208 (ccb->cts.transport == XPORT_ATA ||
6209 ccb->cts.transport == XPORT_SATA || send_tur)) {
6210 fprintf(stdout, "New parameters:\n");
6211 retval = get_print_cts(device, user_settings, 0, NULL);
6214 ratecontrol_bailout:
6220 scsiformat(struct cam_device *device, int argc, char **argv,
6221 char *combinedopt, int task_attr, int retry_count, int timeout)
6225 int ycount = 0, quiet = 0;
6226 int error = 0, retval = 0;
6227 int use_timeout = 10800 * 1000;
6229 struct format_defect_list_header fh;
6230 u_int8_t *data_ptr = NULL;
6231 u_int32_t dxfer_len = 0;
6233 int num_warnings = 0;
6236 ccb = cam_getccb(device);
6239 warnx("scsiformat: error allocating ccb");
6243 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6245 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6266 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6267 "following device:\n");
6269 error = scsidoinquiry(device, argc, argv, combinedopt,
6270 task_attr, retry_count, timeout);
6273 warnx("scsiformat: error sending inquiry");
6274 goto scsiformat_bailout;
6279 if (!get_confirmation()) {
6281 goto scsiformat_bailout;
6286 use_timeout = timeout;
6289 fprintf(stdout, "Current format timeout is %d seconds\n",
6290 use_timeout / 1000);
6294 * If the user hasn't disabled questions and didn't specify a
6295 * timeout on the command line, ask them if they want the current
6299 && (timeout == 0)) {
6301 int new_timeout = 0;
6303 fprintf(stdout, "Enter new timeout in seconds or press\n"
6304 "return to keep the current timeout [%d] ",
6305 use_timeout / 1000);
6307 if (fgets(str, sizeof(str), stdin) != NULL) {
6309 new_timeout = atoi(str);
6312 if (new_timeout != 0) {
6313 use_timeout = new_timeout * 1000;
6314 fprintf(stdout, "Using new timeout value %d\n",
6315 use_timeout / 1000);
6320 * Keep this outside the if block below to silence any unused
6321 * variable warnings.
6323 bzero(&fh, sizeof(fh));
6326 * If we're in immediate mode, we've got to include the format
6329 if (immediate != 0) {
6330 fh.byte2 = FU_DLH_IMMED;
6331 data_ptr = (u_int8_t *)&fh;
6332 dxfer_len = sizeof(fh);
6333 byte2 = FU_FMT_DATA;
6334 } else if (quiet == 0) {
6335 fprintf(stdout, "Formatting...");
6339 scsi_format_unit(&ccb->csio,
6340 /* retries */ retry_count,
6342 /* tag_action */ task_attr,
6345 /* data_ptr */ data_ptr,
6346 /* dxfer_len */ dxfer_len,
6347 /* sense_len */ SSD_FULL_SIZE,
6348 /* timeout */ use_timeout);
6350 /* Disable freezing the device queue */
6351 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6353 if (arglist & CAM_ARG_ERR_RECOVER)
6354 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6356 if (((retval = cam_send_ccb(device, ccb)) < 0)
6357 || ((immediate == 0)
6358 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6359 const char errstr[] = "error sending format command";
6366 if (arglist & CAM_ARG_VERBOSE) {
6367 cam_error_print(device, ccb, CAM_ESF_ALL,
6368 CAM_EPF_ALL, stderr);
6371 goto scsiformat_bailout;
6375 * If we ran in non-immediate mode, we already checked for errors
6376 * above and printed out any necessary information. If we're in
6377 * immediate mode, we need to loop through and get status
6378 * information periodically.
6380 if (immediate == 0) {
6382 fprintf(stdout, "Format Complete\n");
6384 goto scsiformat_bailout;
6391 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6394 * There's really no need to do error recovery or
6395 * retries here, since we're just going to sit in a
6396 * loop and wait for the device to finish formatting.
6398 scsi_test_unit_ready(&ccb->csio,
6401 /* tag_action */ task_attr,
6402 /* sense_len */ SSD_FULL_SIZE,
6403 /* timeout */ 5000);
6405 /* Disable freezing the device queue */
6406 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6408 retval = cam_send_ccb(device, ccb);
6411 * If we get an error from the ioctl, bail out. SCSI
6412 * errors are expected.
6415 warn("error sending CAMIOCOMMAND ioctl");
6416 if (arglist & CAM_ARG_VERBOSE) {
6417 cam_error_print(device, ccb, CAM_ESF_ALL,
6418 CAM_EPF_ALL, stderr);
6421 goto scsiformat_bailout;
6424 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6426 if ((status != CAM_REQ_CMP)
6427 && (status == CAM_SCSI_STATUS_ERROR)
6428 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6429 struct scsi_sense_data *sense;
6430 int error_code, sense_key, asc, ascq;
6432 sense = &ccb->csio.sense_data;
6433 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6434 ccb->csio.sense_resid, &error_code, &sense_key,
6435 &asc, &ascq, /*show_errors*/ 1);
6438 * According to the SCSI-2 and SCSI-3 specs, a
6439 * drive that is in the middle of a format should
6440 * return NOT READY with an ASC of "logical unit
6441 * not ready, format in progress". The sense key
6442 * specific bytes will then be a progress indicator.
6444 if ((sense_key == SSD_KEY_NOT_READY)
6445 && (asc == 0x04) && (ascq == 0x04)) {
6448 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6449 ccb->csio.sense_resid, sks) == 0)
6452 u_int64_t percentage;
6454 val = scsi_2btoul(&sks[1]);
6455 percentage = 10000ull * val;
6458 "\rFormatting: %ju.%02u %% "
6460 (uintmax_t)(percentage /
6462 (unsigned)((percentage /
6466 } else if ((quiet == 0)
6467 && (++num_warnings <= 1)) {
6468 warnx("Unexpected SCSI Sense Key "
6469 "Specific value returned "
6471 scsi_sense_print(device, &ccb->csio,
6473 warnx("Unable to print status "
6474 "information, but format will "
6476 warnx("will exit when format is "
6481 warnx("Unexpected SCSI error during format");
6482 cam_error_print(device, ccb, CAM_ESF_ALL,
6483 CAM_EPF_ALL, stderr);
6485 goto scsiformat_bailout;
6488 } else if (status != CAM_REQ_CMP) {
6489 warnx("Unexpected CAM status %#x", status);
6490 if (arglist & CAM_ARG_VERBOSE)
6491 cam_error_print(device, ccb, CAM_ESF_ALL,
6492 CAM_EPF_ALL, stderr);
6494 goto scsiformat_bailout;
6497 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6500 fprintf(stdout, "\nFormat Complete\n");
6510 scsisanitize(struct cam_device *device, int argc, char **argv,
6511 char *combinedopt, int task_attr, int retry_count, int timeout)
6514 u_int8_t action = 0;
6516 int ycount = 0, quiet = 0;
6517 int error = 0, retval = 0;
6518 int use_timeout = 10800 * 1000;
6524 const char *pattern = NULL;
6525 u_int8_t *data_ptr = NULL;
6526 u_int32_t dxfer_len = 0;
6528 int num_warnings = 0;
6531 ccb = cam_getccb(device);
6534 warnx("scsisanitize: error allocating ccb");
6538 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6540 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6543 if (strcasecmp(optarg, "overwrite") == 0)
6544 action = SSZ_SERVICE_ACTION_OVERWRITE;
6545 else if (strcasecmp(optarg, "block") == 0)
6546 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6547 else if (strcasecmp(optarg, "crypto") == 0)
6548 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6549 else if (strcasecmp(optarg, "exitfailure") == 0)
6550 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6552 warnx("invalid service operation \"%s\"",
6555 goto scsisanitize_bailout;
6559 passes = strtol(optarg, NULL, 0);
6560 if (passes < 1 || passes > 31) {
6561 warnx("invalid passes value %d", passes);
6563 goto scsisanitize_bailout;
6594 warnx("an action is required");
6596 goto scsisanitize_bailout;
6597 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6598 struct scsi_sanitize_parameter_list *pl;
6602 if (pattern == NULL) {
6603 warnx("overwrite action requires -P argument");
6605 goto scsisanitize_bailout;
6607 fd = open(pattern, O_RDONLY);
6609 warn("cannot open pattern file %s", pattern);
6611 goto scsisanitize_bailout;
6613 if (fstat(fd, &sb) < 0) {
6614 warn("cannot stat pattern file %s", pattern);
6616 goto scsisanitize_bailout;
6619 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6620 warnx("pattern file size exceeds maximum value %d",
6621 SSZPL_MAX_PATTERN_LENGTH);
6623 goto scsisanitize_bailout;
6625 dxfer_len = sizeof(*pl) + sz;
6626 data_ptr = calloc(1, dxfer_len);
6627 if (data_ptr == NULL) {
6628 warnx("cannot allocate parameter list buffer");
6630 goto scsisanitize_bailout;
6633 amt = read(fd, data_ptr + sizeof(*pl), sz);
6635 warn("cannot read pattern file");
6637 goto scsisanitize_bailout;
6638 } else if (amt != sz) {
6639 warnx("short pattern file read");
6641 goto scsisanitize_bailout;
6644 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6650 pl->byte1 |= SSZPL_INVERT;
6651 scsi_ulto2b(sz, pl->length);
6657 else if (invert != 0)
6659 else if (pattern != NULL)
6664 warnx("%s argument only valid with overwrite "
6667 goto scsisanitize_bailout;
6672 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6673 "following device:\n");
6675 error = scsidoinquiry(device, argc, argv, combinedopt,
6676 task_attr, retry_count, timeout);
6679 warnx("scsisanitize: error sending inquiry");
6680 goto scsisanitize_bailout;
6685 if (!get_confirmation()) {
6687 goto scsisanitize_bailout;
6692 use_timeout = timeout;
6695 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6696 use_timeout / 1000);
6700 * If the user hasn't disabled questions and didn't specify a
6701 * timeout on the command line, ask them if they want the current
6705 && (timeout == 0)) {
6707 int new_timeout = 0;
6709 fprintf(stdout, "Enter new timeout in seconds or press\n"
6710 "return to keep the current timeout [%d] ",
6711 use_timeout / 1000);
6713 if (fgets(str, sizeof(str), stdin) != NULL) {
6715 new_timeout = atoi(str);
6718 if (new_timeout != 0) {
6719 use_timeout = new_timeout * 1000;
6720 fprintf(stdout, "Using new timeout value %d\n",
6721 use_timeout / 1000);
6727 byte2 |= SSZ_UNRESTRICTED_EXIT;
6731 scsi_sanitize(&ccb->csio,
6732 /* retries */ retry_count,
6734 /* tag_action */ task_attr,
6737 /* data_ptr */ data_ptr,
6738 /* dxfer_len */ dxfer_len,
6739 /* sense_len */ SSD_FULL_SIZE,
6740 /* timeout */ use_timeout);
6742 /* Disable freezing the device queue */
6743 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6745 if (arglist & CAM_ARG_ERR_RECOVER)
6746 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6748 if (cam_send_ccb(device, ccb) < 0) {
6749 warn("error sending sanitize command");
6751 goto scsisanitize_bailout;
6754 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6755 struct scsi_sense_data *sense;
6756 int error_code, sense_key, asc, ascq;
6758 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6759 CAM_SCSI_STATUS_ERROR) {
6760 sense = &ccb->csio.sense_data;
6761 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6762 ccb->csio.sense_resid, &error_code, &sense_key,
6763 &asc, &ascq, /*show_errors*/ 1);
6765 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6766 asc == 0x20 && ascq == 0x00)
6767 warnx("sanitize is not supported by "
6770 warnx("error sanitizing this device");
6772 warnx("error sanitizing this device");
6774 if (arglist & CAM_ARG_VERBOSE) {
6775 cam_error_print(device, ccb, CAM_ESF_ALL,
6776 CAM_EPF_ALL, stderr);
6779 goto scsisanitize_bailout;
6783 * If we ran in non-immediate mode, we already checked for errors
6784 * above and printed out any necessary information. If we're in
6785 * immediate mode, we need to loop through and get status
6786 * information periodically.
6788 if (immediate == 0) {
6790 fprintf(stdout, "Sanitize Complete\n");
6792 goto scsisanitize_bailout;
6799 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6802 * There's really no need to do error recovery or
6803 * retries here, since we're just going to sit in a
6804 * loop and wait for the device to finish sanitizing.
6806 scsi_test_unit_ready(&ccb->csio,
6809 /* tag_action */ task_attr,
6810 /* sense_len */ SSD_FULL_SIZE,
6811 /* timeout */ 5000);
6813 /* Disable freezing the device queue */
6814 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6816 retval = cam_send_ccb(device, ccb);
6819 * If we get an error from the ioctl, bail out. SCSI
6820 * errors are expected.
6823 warn("error sending CAMIOCOMMAND ioctl");
6824 if (arglist & CAM_ARG_VERBOSE) {
6825 cam_error_print(device, ccb, CAM_ESF_ALL,
6826 CAM_EPF_ALL, stderr);
6829 goto scsisanitize_bailout;
6832 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6834 if ((status != CAM_REQ_CMP)
6835 && (status == CAM_SCSI_STATUS_ERROR)
6836 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6837 struct scsi_sense_data *sense;
6838 int error_code, sense_key, asc, ascq;
6840 sense = &ccb->csio.sense_data;
6841 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6842 ccb->csio.sense_resid, &error_code, &sense_key,
6843 &asc, &ascq, /*show_errors*/ 1);
6846 * According to the SCSI-3 spec, a drive that is in the
6847 * middle of a sanitize should return NOT READY with an
6848 * ASC of "logical unit not ready, sanitize in
6849 * progress". The sense key specific bytes will then
6850 * be a progress indicator.
6852 if ((sense_key == SSD_KEY_NOT_READY)
6853 && (asc == 0x04) && (ascq == 0x1b)) {
6856 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6857 ccb->csio.sense_resid, sks) == 0)
6860 u_int64_t percentage;
6862 val = scsi_2btoul(&sks[1]);
6863 percentage = 10000 * val;
6866 "\rSanitizing: %ju.%02u %% "
6868 (uintmax_t)(percentage /
6870 (unsigned)((percentage /
6874 } else if ((quiet == 0)
6875 && (++num_warnings <= 1)) {
6876 warnx("Unexpected SCSI Sense Key "
6877 "Specific value returned "
6878 "during sanitize:");
6879 scsi_sense_print(device, &ccb->csio,
6881 warnx("Unable to print status "
6882 "information, but sanitze will "
6884 warnx("will exit when sanitize is "
6889 warnx("Unexpected SCSI error during sanitize");
6890 cam_error_print(device, ccb, CAM_ESF_ALL,
6891 CAM_EPF_ALL, stderr);
6893 goto scsisanitize_bailout;
6896 } else if (status != CAM_REQ_CMP) {
6897 warnx("Unexpected CAM status %#x", status);
6898 if (arglist & CAM_ARG_VERBOSE)
6899 cam_error_print(device, ccb, CAM_ESF_ALL,
6900 CAM_EPF_ALL, stderr);
6902 goto scsisanitize_bailout;
6904 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6907 fprintf(stdout, "\nSanitize Complete\n");
6909 scsisanitize_bailout:
6912 if (data_ptr != NULL)
6920 scsireportluns(struct cam_device *device, int argc, char **argv,
6921 char *combinedopt, int task_attr, int retry_count, int timeout)
6924 int c, countonly, lunsonly;
6925 struct scsi_report_luns_data *lundata;
6927 uint8_t report_type;
6928 uint32_t list_len, i, j;
6933 report_type = RPL_REPORT_DEFAULT;
6934 ccb = cam_getccb(device);
6937 warnx("%s: error allocating ccb", __func__);
6941 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6946 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6955 if (strcasecmp(optarg, "default") == 0)
6956 report_type = RPL_REPORT_DEFAULT;
6957 else if (strcasecmp(optarg, "wellknown") == 0)
6958 report_type = RPL_REPORT_WELLKNOWN;
6959 else if (strcasecmp(optarg, "all") == 0)
6960 report_type = RPL_REPORT_ALL;
6962 warnx("%s: invalid report type \"%s\"",
6973 if ((countonly != 0)
6974 && (lunsonly != 0)) {
6975 warnx("%s: you can only specify one of -c or -l", __func__);
6980 * According to SPC-4, the allocation length must be at least 16
6981 * bytes -- enough for the header and one LUN.
6983 alloc_len = sizeof(*lundata) + 8;
6987 lundata = malloc(alloc_len);
6989 if (lundata == NULL) {
6990 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6995 scsi_report_luns(&ccb->csio,
6996 /*retries*/ retry_count,
6998 /*tag_action*/ task_attr,
6999 /*select_report*/ report_type,
7000 /*rpl_buf*/ lundata,
7001 /*alloc_len*/ alloc_len,
7002 /*sense_len*/ SSD_FULL_SIZE,
7003 /*timeout*/ timeout ? timeout : 5000);
7005 /* Disable freezing the device queue */
7006 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7008 if (arglist & CAM_ARG_ERR_RECOVER)
7009 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7011 if (cam_send_ccb(device, ccb) < 0) {
7012 warn("error sending REPORT LUNS command");
7014 if (arglist & CAM_ARG_VERBOSE)
7015 cam_error_print(device, ccb, CAM_ESF_ALL,
7016 CAM_EPF_ALL, stderr);
7022 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7023 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7029 list_len = scsi_4btoul(lundata->length);
7032 * If we need to list the LUNs, and our allocation
7033 * length was too short, reallocate and retry.
7035 if ((countonly == 0)
7036 && (list_len > (alloc_len - sizeof(*lundata)))) {
7037 alloc_len = list_len + sizeof(*lundata);
7043 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7044 ((list_len / 8) > 1) ? "s" : "");
7049 for (i = 0; i < (list_len / 8); i++) {
7053 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7055 fprintf(stdout, ",");
7056 switch (lundata->luns[i].lundata[j] &
7057 RPL_LUNDATA_ATYP_MASK) {
7058 case RPL_LUNDATA_ATYP_PERIPH:
7059 if ((lundata->luns[i].lundata[j] &
7060 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7061 fprintf(stdout, "%d:",
7062 lundata->luns[i].lundata[j] &
7063 RPL_LUNDATA_PERIPH_BUS_MASK);
7065 && ((lundata->luns[i].lundata[j+2] &
7066 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7069 fprintf(stdout, "%d",
7070 lundata->luns[i].lundata[j+1]);
7072 case RPL_LUNDATA_ATYP_FLAT: {
7074 tmplun[0] = lundata->luns[i].lundata[j] &
7075 RPL_LUNDATA_FLAT_LUN_MASK;
7076 tmplun[1] = lundata->luns[i].lundata[j+1];
7078 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7082 case RPL_LUNDATA_ATYP_LUN:
7083 fprintf(stdout, "%d:%d:%d",
7084 (lundata->luns[i].lundata[j+1] &
7085 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7086 lundata->luns[i].lundata[j] &
7087 RPL_LUNDATA_LUN_TARG_MASK,
7088 lundata->luns[i].lundata[j+1] &
7089 RPL_LUNDATA_LUN_LUN_MASK);
7091 case RPL_LUNDATA_ATYP_EXTLUN: {
7092 int field_len_code, eam_code;
7094 eam_code = lundata->luns[i].lundata[j] &
7095 RPL_LUNDATA_EXT_EAM_MASK;
7096 field_len_code = (lundata->luns[i].lundata[j] &
7097 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7099 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7100 && (field_len_code == 0x00)) {
7101 fprintf(stdout, "%d",
7102 lundata->luns[i].lundata[j+1]);
7103 } else if ((eam_code ==
7104 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7105 && (field_len_code == 0x03)) {
7109 * This format takes up all 8 bytes.
7110 * If we aren't starting at offset 0,
7114 fprintf(stdout, "Invalid "
7117 "specified format", j);
7121 bzero(tmp_lun, sizeof(tmp_lun));
7122 bcopy(&lundata->luns[i].lundata[j+1],
7123 &tmp_lun[1], sizeof(tmp_lun) - 1);
7124 fprintf(stdout, "%#jx",
7125 (intmax_t)scsi_8btou64(tmp_lun));
7128 fprintf(stderr, "Unknown Extended LUN"
7129 "Address method %#x, length "
7130 "code %#x", eam_code,
7137 fprintf(stderr, "Unknown LUN address method "
7138 "%#x\n", lundata->luns[i].lundata[0] &
7139 RPL_LUNDATA_ATYP_MASK);
7143 * For the flat addressing method, there are no
7144 * other levels after it.
7149 fprintf(stdout, "\n");
7162 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7163 char *combinedopt, int task_attr, int retry_count, int timeout)
7166 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
7167 struct scsi_read_capacity_data rcap;
7168 struct scsi_read_capacity_data_long rcaplong;
7182 ccb = cam_getccb(device);
7185 warnx("%s: error allocating ccb", __func__);
7189 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7191 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7218 if ((blocksizeonly != 0)
7219 && (numblocks != 0)) {
7220 warnx("%s: you can only specify one of -b or -N", __func__);
7225 if ((blocksizeonly != 0)
7226 && (sizeonly != 0)) {
7227 warnx("%s: you can only specify one of -b or -s", __func__);
7234 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7240 && (blocksizeonly != 0)) {
7241 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7246 scsi_read_capacity(&ccb->csio,
7247 /*retries*/ retry_count,
7249 /*tag_action*/ task_attr,
7252 /*timeout*/ timeout ? timeout : 5000);
7254 /* Disable freezing the device queue */
7255 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7257 if (arglist & CAM_ARG_ERR_RECOVER)
7258 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7260 if (cam_send_ccb(device, ccb) < 0) {
7261 warn("error sending READ CAPACITY command");
7263 if (arglist & CAM_ARG_VERBOSE)
7264 cam_error_print(device, ccb, CAM_ESF_ALL,
7265 CAM_EPF_ALL, stderr);
7271 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7272 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7277 maxsector = scsi_4btoul(rcap.addr);
7278 block_len = scsi_4btoul(rcap.length);
7281 * A last block of 2^32-1 means that the true capacity is over 2TB,
7282 * and we need to issue the long READ CAPACITY to get the real
7283 * capacity. Otherwise, we're all set.
7285 if (maxsector != 0xffffffff)
7288 scsi_read_capacity_16(&ccb->csio,
7289 /*retries*/ retry_count,
7291 /*tag_action*/ task_attr,
7295 /*rcap_buf*/ (uint8_t *)&rcaplong,
7296 /*rcap_buf_len*/ sizeof(rcaplong),
7297 /*sense_len*/ SSD_FULL_SIZE,
7298 /*timeout*/ timeout ? timeout : 5000);
7300 /* Disable freezing the device queue */
7301 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7303 if (arglist & CAM_ARG_ERR_RECOVER)
7304 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7306 if (cam_send_ccb(device, ccb) < 0) {
7307 warn("error sending READ CAPACITY (16) command");
7309 if (arglist & CAM_ARG_VERBOSE)
7310 cam_error_print(device, ccb, CAM_ESF_ALL,
7311 CAM_EPF_ALL, stderr);
7317 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7318 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7323 maxsector = scsi_8btou64(rcaplong.addr);
7324 block_len = scsi_4btoul(rcaplong.length);
7327 if (blocksizeonly == 0) {
7329 * Humanize implies !quiet, and also implies numblocks.
7331 if (humanize != 0) {
7336 tmpbytes = (maxsector + 1) * block_len;
7337 ret = humanize_number(tmpstr, sizeof(tmpstr),
7338 tmpbytes, "", HN_AUTOSCALE,
7341 HN_DIVISOR_1000 : 0));
7343 warnx("%s: humanize_number failed!", __func__);
7347 fprintf(stdout, "Device Size: %s%s", tmpstr,
7348 (sizeonly == 0) ? ", " : "\n");
7349 } else if (numblocks != 0) {
7350 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7351 "Blocks: " : "", (uintmax_t)maxsector + 1,
7352 (sizeonly == 0) ? ", " : "\n");
7354 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7355 "Last Block: " : "", (uintmax_t)maxsector,
7356 (sizeonly == 0) ? ", " : "\n");
7360 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7361 "Block Length: " : "", block_len, (quiet == 0) ?
7370 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7371 int retry_count, int timeout)
7375 uint8_t *smp_request = NULL, *smp_response = NULL;
7376 int request_size = 0, response_size = 0;
7377 int fd_request = 0, fd_response = 0;
7378 char *datastr = NULL;
7379 struct get_hook hook;
7384 * Note that at the moment we don't support sending SMP CCBs to
7385 * devices that aren't probed by CAM.
7387 ccb = cam_getccb(device);
7389 warnx("%s: error allocating CCB", __func__);
7393 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7395 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7398 arglist |= CAM_ARG_CMD_IN;
7399 response_size = strtol(optarg, NULL, 0);
7400 if (response_size <= 0) {
7401 warnx("invalid number of response bytes %d",
7404 goto smpcmd_bailout;
7406 hook.argc = argc - optind;
7407 hook.argv = argv + optind;
7410 datastr = cget(&hook, NULL);
7412 * If the user supplied "-" instead of a format, he
7413 * wants the data to be written to stdout.
7415 if ((datastr != NULL)
7416 && (datastr[0] == '-'))
7419 smp_response = (u_int8_t *)malloc(response_size);
7420 if (smp_response == NULL) {
7421 warn("can't malloc memory for SMP response");
7423 goto smpcmd_bailout;
7427 arglist |= CAM_ARG_CMD_OUT;
7428 request_size = strtol(optarg, NULL, 0);
7429 if (request_size <= 0) {
7430 warnx("invalid number of request bytes %d",
7433 goto smpcmd_bailout;
7435 hook.argc = argc - optind;
7436 hook.argv = argv + optind;
7438 datastr = cget(&hook, NULL);
7439 smp_request = (u_int8_t *)malloc(request_size);
7440 if (smp_request == NULL) {
7441 warn("can't malloc memory for SMP request");
7443 goto smpcmd_bailout;
7445 bzero(smp_request, request_size);
7447 * If the user supplied "-" instead of a format, he
7448 * wants the data to be read from stdin.
7450 if ((datastr != NULL)
7451 && (datastr[0] == '-'))
7454 buff_encode_visit(smp_request, request_size,
7465 * If fd_data is set, and we're writing to the device, we need to
7466 * read the data the user wants written from stdin.
7468 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7470 int amt_to_read = request_size;
7471 u_int8_t *buf_ptr = smp_request;
7473 for (amt_read = 0; amt_to_read > 0;
7474 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7475 if (amt_read == -1) {
7476 warn("error reading data from stdin");
7478 goto smpcmd_bailout;
7480 amt_to_read -= amt_read;
7481 buf_ptr += amt_read;
7485 if (((arglist & CAM_ARG_CMD_IN) == 0)
7486 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7487 warnx("%s: need both the request (-r) and response (-R) "
7488 "arguments", __func__);
7490 goto smpcmd_bailout;
7493 flags |= CAM_DEV_QFRZDIS;
7495 cam_fill_smpio(&ccb->smpio,
7496 /*retries*/ retry_count,
7499 /*smp_request*/ smp_request,
7500 /*smp_request_len*/ request_size,
7501 /*smp_response*/ smp_response,
7502 /*smp_response_len*/ response_size,
7503 /*timeout*/ timeout ? timeout : 5000);
7505 ccb->smpio.flags = SMP_FLAG_NONE;
7507 if (((retval = cam_send_ccb(device, ccb)) < 0)
7508 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7509 const char warnstr[] = "error sending command";
7516 if (arglist & CAM_ARG_VERBOSE) {
7517 cam_error_print(device, ccb, CAM_ESF_ALL,
7518 CAM_EPF_ALL, stderr);
7522 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7523 && (response_size > 0)) {
7524 if (fd_response == 0) {
7525 buff_decode_visit(smp_response, response_size,
7526 datastr, arg_put, NULL);
7527 fprintf(stdout, "\n");
7529 ssize_t amt_written;
7530 int amt_to_write = response_size;
7531 u_int8_t *buf_ptr = smp_response;
7533 for (amt_written = 0; (amt_to_write > 0) &&
7534 (amt_written = write(STDOUT_FILENO, buf_ptr,
7535 amt_to_write)) > 0;){
7536 amt_to_write -= amt_written;
7537 buf_ptr += amt_written;
7539 if (amt_written == -1) {
7540 warn("error writing data to stdout");
7542 goto smpcmd_bailout;
7543 } else if ((amt_written == 0)
7544 && (amt_to_write > 0)) {
7545 warnx("only wrote %u bytes out of %u",
7546 response_size - amt_to_write,
7555 if (smp_request != NULL)
7558 if (smp_response != NULL)
7565 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7566 int retry_count, int timeout)
7570 int32_t mmc_opcode = 0, mmc_arg = 0;
7571 int32_t mmc_flags = -1;
7574 int is_bw_4 = 0, is_bw_1 = 0;
7575 int is_highspeed = 0, is_stdspeed = 0;
7576 int is_info_request = 0;
7578 uint8_t mmc_data_byte = 0;
7580 /* For IO_RW_EXTENDED command */
7581 uint8_t *mmc_data = NULL;
7582 struct mmc_data mmc_d;
7583 int mmc_data_len = 0;
7586 * Note that at the moment we don't support sending SMP CCBs to
7587 * devices that aren't probed by CAM.
7589 ccb = cam_getccb(device);
7591 warnx("%s: error allocating CCB", __func__);
7595 bzero(&(&ccb->ccb_h)[1],
7596 sizeof(union ccb) - sizeof(struct ccb_hdr));
7598 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7607 if (!strcmp(optarg, "high"))
7613 is_info_request = 1;
7616 mmc_opcode = strtol(optarg, NULL, 0);
7617 if (mmc_opcode < 0) {
7618 warnx("invalid MMC opcode %d",
7621 goto mmccmd_bailout;
7625 mmc_arg = strtol(optarg, NULL, 0);
7627 warnx("invalid MMC arg %d",
7630 goto mmccmd_bailout;
7634 mmc_flags = strtol(optarg, NULL, 0);
7635 if (mmc_flags < 0) {
7636 warnx("invalid MMC flags %d",
7639 goto mmccmd_bailout;
7643 mmc_data_len = strtol(optarg, NULL, 0);
7644 if (mmc_data_len <= 0) {
7645 warnx("invalid MMC data len %d",
7648 goto mmccmd_bailout;
7655 mmc_data_byte = strtol(optarg, NULL, 0);
7661 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7663 /* If flags are left default, supply the right flags */
7665 switch (mmc_opcode) {
7666 case MMC_GO_IDLE_STATE:
7667 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7669 case IO_SEND_OP_COND:
7670 mmc_flags = MMC_RSP_R4;
7672 case SD_SEND_RELATIVE_ADDR:
7673 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7675 case MMC_SELECT_CARD:
7676 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7677 mmc_arg = mmc_arg << 16;
7679 case SD_IO_RW_DIRECT:
7680 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7681 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7683 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7685 case SD_IO_RW_EXTENDED:
7686 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7687 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7688 int len_arg = mmc_data_len;
7689 if (mmc_data_len == 512)
7693 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7695 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7698 mmc_flags = MMC_RSP_R1;
7702 // Switch bus width instead of sending IO command
7703 if (is_bw_4 || is_bw_1) {
7704 struct ccb_trans_settings_mmc *cts;
7705 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7706 ccb->ccb_h.flags = 0;
7707 cts = &ccb->cts.proto_specific.mmc;
7708 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7709 cts->ios_valid = MMC_BW;
7710 if (((retval = cam_send_ccb(device, ccb)) < 0)
7711 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7712 warn("Error sending command");
7714 printf("Parameters set OK\n");
7720 // Switch bus speed instead of sending IO command
7721 if (is_stdspeed || is_highspeed) {
7722 struct ccb_trans_settings_mmc *cts;
7723 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7724 ccb->ccb_h.flags = 0;
7725 cts = &ccb->cts.proto_specific.mmc;
7726 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
7727 cts->ios_valid = MMC_BT;
7728 if (((retval = cam_send_ccb(device, ccb)) < 0)
7729 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7730 warn("Error sending command");
7732 printf("Speed set OK (HS: %d)\n", is_highspeed);
7738 // Get information about controller and its settings
7739 if (is_info_request) {
7740 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
7741 ccb->ccb_h.flags = 0;
7742 struct ccb_trans_settings_mmc *cts;
7743 cts = &ccb->cts.proto_specific.mmc;
7744 if (((retval = cam_send_ccb(device, ccb)) < 0)
7745 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7746 warn("Error sending command");
7749 printf("Host controller information\n");
7750 printf("Host OCR: 0x%x\n", cts->host_ocr);
7751 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
7752 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
7753 printf("Supported bus width: ");
7754 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
7756 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
7758 printf("\nCurrent settings:\n");
7759 printf("Bus width: ");
7760 switch (cts->ios.bus_width) {
7771 printf("Freq: %d.%03d MHz%s\n",
7772 cts->ios.clock / 1000000,
7773 (cts->ios.clock / 1000) % 1000,
7774 cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : "");
7778 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
7780 if (mmc_data_len > 0) {
7781 flags |= CAM_DIR_IN;
7782 mmc_data = malloc(mmc_data_len);
7783 memset(mmc_data, 0, mmc_data_len);
7784 mmc_d.len = mmc_data_len;
7785 mmc_d.data = mmc_data;
7786 mmc_d.flags = MMC_DATA_READ;
7787 } else flags |= CAM_DIR_NONE;
7789 cam_fill_mmcio(&ccb->mmcio,
7790 /*retries*/ retry_count,
7793 /*mmc_opcode*/ mmc_opcode,
7794 /*mmc_arg*/ mmc_arg,
7795 /*mmc_flags*/ mmc_flags,
7796 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
7797 /*timeout*/ timeout ? timeout : 5000);
7799 if (((retval = cam_send_ccb(device, ccb)) < 0)
7800 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7801 const char warnstr[] = "error sending command";
7808 if (arglist & CAM_ARG_VERBOSE) {
7809 cam_error_print(device, ccb, CAM_ESF_ALL,
7810 CAM_EPF_ALL, stderr);
7814 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
7815 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
7816 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
7817 ccb->mmcio.cmd.resp[1],
7818 ccb->mmcio.cmd.resp[2],
7819 ccb->mmcio.cmd.resp[3]);
7821 switch (mmc_opcode) {
7822 case SD_IO_RW_DIRECT:
7823 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
7824 SD_R5_DATA(ccb->mmcio.cmd.resp),
7825 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
7827 case SD_IO_RW_EXTENDED:
7828 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
7829 hexdump(mmc_data, mmc_data_len, NULL, 0);
7831 case SD_SEND_RELATIVE_ADDR:
7832 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
7835 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
7842 if (mmc_data_len > 0 && mmc_data != NULL)
7849 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7850 char *combinedopt, int retry_count, int timeout)
7853 struct smp_report_general_request *request = NULL;
7854 struct smp_report_general_response *response = NULL;
7855 struct sbuf *sb = NULL;
7857 int c, long_response = 0;
7861 * Note that at the moment we don't support sending SMP CCBs to
7862 * devices that aren't probed by CAM.
7864 ccb = cam_getccb(device);
7866 warnx("%s: error allocating CCB", __func__);
7870 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7872 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7881 request = malloc(sizeof(*request));
7882 if (request == NULL) {
7883 warn("%s: unable to allocate %zd bytes", __func__,
7889 response = malloc(sizeof(*response));
7890 if (response == NULL) {
7891 warn("%s: unable to allocate %zd bytes", __func__,
7898 smp_report_general(&ccb->smpio,
7902 /*request_len*/ sizeof(*request),
7903 (uint8_t *)response,
7904 /*response_len*/ sizeof(*response),
7905 /*long_response*/ long_response,
7908 if (((retval = cam_send_ccb(device, ccb)) < 0)
7909 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7910 const char warnstr[] = "error sending command";
7917 if (arglist & CAM_ARG_VERBOSE) {
7918 cam_error_print(device, ccb, CAM_ESF_ALL,
7919 CAM_EPF_ALL, stderr);
7926 * If the device supports the long response bit, try again and see
7927 * if we can get all of the data.
7929 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7930 && (long_response == 0)) {
7931 ccb->ccb_h.status = CAM_REQ_INPROG;
7932 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7938 * XXX KDM detect and decode SMP errors here.
7940 sb = sbuf_new_auto();
7942 warnx("%s: error allocating sbuf", __func__);
7946 smp_report_general_sbuf(response, sizeof(*response), sb);
7948 if (sbuf_finish(sb) != 0) {
7949 warnx("%s: sbuf_finish", __func__);
7953 printf("%s", sbuf_data(sb));
7959 if (request != NULL)
7962 if (response != NULL)
7971 static struct camcontrol_opts phy_ops[] = {
7972 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7973 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7974 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7975 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7976 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7977 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7978 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7979 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7980 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7985 smpphycontrol(struct cam_device *device, int argc, char **argv,
7986 char *combinedopt, int retry_count, int timeout)
7989 struct smp_phy_control_request *request = NULL;
7990 struct smp_phy_control_response *response = NULL;
7991 int long_response = 0;
7994 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7996 uint64_t attached_dev_name = 0;
7997 int dev_name_set = 0;
7998 uint32_t min_plr = 0, max_plr = 0;
7999 uint32_t pp_timeout_val = 0;
8000 int slumber_partial = 0;
8001 int set_pp_timeout_val = 0;
8005 * Note that at the moment we don't support sending SMP CCBs to
8006 * devices that aren't probed by CAM.
8008 ccb = cam_getccb(device);
8010 warnx("%s: error allocating CCB", __func__);
8014 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8016 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8024 if (strcasecmp(optarg, "enable") == 0)
8026 else if (strcasecmp(optarg, "disable") == 0)
8029 warnx("%s: Invalid argument %s", __func__,
8036 slumber_partial |= enable <<
8037 SMP_PC_SAS_SLUMBER_SHIFT;
8040 slumber_partial |= enable <<
8041 SMP_PC_SAS_PARTIAL_SHIFT;
8044 slumber_partial |= enable <<
8045 SMP_PC_SATA_SLUMBER_SHIFT;
8048 slumber_partial |= enable <<
8049 SMP_PC_SATA_PARTIAL_SHIFT;
8052 warnx("%s: programmer error", __func__);
8055 break; /*NOTREACHED*/
8060 attached_dev_name = (uintmax_t)strtoumax(optarg,
8069 * We don't do extensive checking here, so this
8070 * will continue to work when new speeds come out.
8072 min_plr = strtoul(optarg, NULL, 0);
8074 || (min_plr > 0xf)) {
8075 warnx("%s: invalid link rate %x",
8083 * We don't do extensive checking here, so this
8084 * will continue to work when new speeds come out.
8086 max_plr = strtoul(optarg, NULL, 0);
8088 || (max_plr > 0xf)) {
8089 warnx("%s: invalid link rate %x",
8096 camcontrol_optret optreturn;
8097 cam_argmask argnums;
8100 if (phy_op_set != 0) {
8101 warnx("%s: only one phy operation argument "
8102 "(-o) allowed", __func__);
8110 * Allow the user to specify the phy operation
8111 * numerically, as well as with a name. This will
8112 * future-proof it a bit, so options that are added
8113 * in future specs can be used.
8115 if (isdigit(optarg[0])) {
8116 phy_operation = strtoul(optarg, NULL, 0);
8117 if ((phy_operation == 0)
8118 || (phy_operation > 0xff)) {
8119 warnx("%s: invalid phy operation %#x",
8120 __func__, phy_operation);
8126 optreturn = getoption(phy_ops, optarg, &phy_operation,
8129 if (optreturn == CC_OR_AMBIGUOUS) {
8130 warnx("%s: ambiguous option %s", __func__,
8135 } else if (optreturn == CC_OR_NOT_FOUND) {
8136 warnx("%s: option %s not found", __func__,
8148 pp_timeout_val = strtoul(optarg, NULL, 0);
8149 if (pp_timeout_val > 15) {
8150 warnx("%s: invalid partial pathway timeout "
8151 "value %u, need a value less than 16",
8152 __func__, pp_timeout_val);
8156 set_pp_timeout_val = 1;
8164 warnx("%s: a PHY (-p phy) argument is required",__func__);
8169 if (((dev_name_set != 0)
8170 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8171 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8172 && (dev_name_set == 0))) {
8173 warnx("%s: -d name and -o setdevname arguments both "
8174 "required to set device name", __func__);
8179 request = malloc(sizeof(*request));
8180 if (request == NULL) {
8181 warn("%s: unable to allocate %zd bytes", __func__,
8187 response = malloc(sizeof(*response));
8188 if (response == NULL) {
8189 warn("%s: unable to allocate %zd bytes", __func__,
8195 smp_phy_control(&ccb->smpio,
8200 (uint8_t *)response,
8203 /*expected_exp_change_count*/ 0,
8206 (set_pp_timeout_val != 0) ? 1 : 0,
8214 if (((retval = cam_send_ccb(device, ccb)) < 0)
8215 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8216 const char warnstr[] = "error sending command";
8223 if (arglist & CAM_ARG_VERBOSE) {
8225 * Use CAM_EPF_NORMAL so we only get one line of
8226 * SMP command decoding.
8228 cam_error_print(device, ccb, CAM_ESF_ALL,
8229 CAM_EPF_NORMAL, stderr);
8235 /* XXX KDM print out something here for success? */
8240 if (request != NULL)
8243 if (response != NULL)
8250 smpmaninfo(struct cam_device *device, int argc, char **argv,
8251 char *combinedopt, int retry_count, int timeout)
8254 struct smp_report_manuf_info_request request;
8255 struct smp_report_manuf_info_response response;
8256 struct sbuf *sb = NULL;
8257 int long_response = 0;
8262 * Note that at the moment we don't support sending SMP CCBs to
8263 * devices that aren't probed by CAM.
8265 ccb = cam_getccb(device);
8267 warnx("%s: error allocating CCB", __func__);
8271 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8273 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8282 bzero(&request, sizeof(request));
8283 bzero(&response, sizeof(response));
8285 smp_report_manuf_info(&ccb->smpio,
8290 (uint8_t *)&response,
8295 if (((retval = cam_send_ccb(device, ccb)) < 0)
8296 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8297 const char warnstr[] = "error sending command";
8304 if (arglist & CAM_ARG_VERBOSE) {
8305 cam_error_print(device, ccb, CAM_ESF_ALL,
8306 CAM_EPF_ALL, stderr);
8312 sb = sbuf_new_auto();
8314 warnx("%s: error allocating sbuf", __func__);
8318 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8320 if (sbuf_finish(sb) != 0) {
8321 warnx("%s: sbuf_finish", __func__);
8325 printf("%s", sbuf_data(sb));
8339 getdevid(struct cam_devitem *item)
8342 union ccb *ccb = NULL;
8344 struct cam_device *dev;
8346 dev = cam_open_btl(item->dev_match.path_id,
8347 item->dev_match.target_id,
8348 item->dev_match.target_lun, O_RDWR, NULL);
8351 warnx("%s", cam_errbuf);
8356 item->device_id_len = 0;
8358 ccb = cam_getccb(dev);
8360 warnx("%s: error allocating CCB", __func__);
8365 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8368 * On the first try, we just probe for the size of the data, and
8369 * then allocate that much memory and try again.
8372 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8373 ccb->ccb_h.flags = CAM_DIR_IN;
8374 ccb->cdai.flags = CDAI_FLAG_NONE;
8375 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8376 ccb->cdai.bufsiz = item->device_id_len;
8377 if (item->device_id_len != 0)
8378 ccb->cdai.buf = (uint8_t *)item->device_id;
8380 if (cam_send_ccb(dev, ccb) < 0) {
8381 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8386 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8387 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8392 if (item->device_id_len == 0) {
8394 * This is our first time through. Allocate the buffer,
8395 * and then go back to get the data.
8397 if (ccb->cdai.provsiz == 0) {
8398 warnx("%s: invalid .provsiz field returned with "
8399 "XPT_GDEV_ADVINFO CCB", __func__);
8403 item->device_id_len = ccb->cdai.provsiz;
8404 item->device_id = malloc(item->device_id_len);
8405 if (item->device_id == NULL) {
8406 warn("%s: unable to allocate %d bytes", __func__,
8407 item->device_id_len);
8411 ccb->ccb_h.status = CAM_REQ_INPROG;
8417 cam_close_device(dev);
8426 * XXX KDM merge this code with getdevtree()?
8429 buildbusdevlist(struct cam_devlist *devlist)
8432 int bufsize, fd = -1;
8433 struct dev_match_pattern *patterns;
8434 struct cam_devitem *item = NULL;
8435 int skip_device = 0;
8438 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8439 warn("couldn't open %s", XPT_DEVICE);
8443 bzero(&ccb, sizeof(union ccb));
8445 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8446 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8447 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8449 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8450 bufsize = sizeof(struct dev_match_result) * 100;
8451 ccb.cdm.match_buf_len = bufsize;
8452 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8453 if (ccb.cdm.matches == NULL) {
8454 warnx("can't malloc memory for matches");
8458 ccb.cdm.num_matches = 0;
8459 ccb.cdm.num_patterns = 2;
8460 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8461 ccb.cdm.num_patterns;
8463 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8464 if (patterns == NULL) {
8465 warnx("can't malloc memory for patterns");
8470 ccb.cdm.patterns = patterns;
8471 bzero(patterns, ccb.cdm.pattern_buf_len);
8473 patterns[0].type = DEV_MATCH_DEVICE;
8474 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8475 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8476 patterns[1].type = DEV_MATCH_PERIPH;
8477 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8478 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8481 * We do the ioctl multiple times if necessary, in case there are
8482 * more than 100 nodes in the EDT.
8487 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8488 warn("error sending CAMIOCOMMAND ioctl");
8493 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8494 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8495 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8496 warnx("got CAM error %#x, CDM error %d\n",
8497 ccb.ccb_h.status, ccb.cdm.status);
8502 for (i = 0; i < ccb.cdm.num_matches; i++) {
8503 switch (ccb.cdm.matches[i].type) {
8504 case DEV_MATCH_DEVICE: {
8505 struct device_match_result *dev_result;
8508 &ccb.cdm.matches[i].result.device_result;
8510 if (dev_result->flags &
8511 DEV_RESULT_UNCONFIGURED) {
8517 item = malloc(sizeof(*item));
8519 warn("%s: unable to allocate %zd bytes",
8520 __func__, sizeof(*item));
8524 bzero(item, sizeof(*item));
8525 bcopy(dev_result, &item->dev_match,
8526 sizeof(*dev_result));
8527 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8530 if (getdevid(item) != 0) {
8536 case DEV_MATCH_PERIPH: {
8537 struct periph_match_result *periph_result;
8540 &ccb.cdm.matches[i].result.periph_result;
8542 if (skip_device != 0)
8544 item->num_periphs++;
8545 item->periph_matches = realloc(
8546 item->periph_matches,
8548 sizeof(struct periph_match_result));
8549 if (item->periph_matches == NULL) {
8550 warn("%s: error allocating periph "
8555 bcopy(periph_result, &item->periph_matches[
8556 item->num_periphs - 1],
8557 sizeof(*periph_result));
8561 fprintf(stderr, "%s: unexpected match "
8562 "type %d\n", __func__,
8563 ccb.cdm.matches[i].type);
8566 break; /*NOTREACHED*/
8569 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8570 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8578 free(ccb.cdm.matches);
8581 freebusdevlist(devlist);
8587 freebusdevlist(struct cam_devlist *devlist)
8589 struct cam_devitem *item, *item2;
8591 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8592 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8594 free(item->device_id);
8595 free(item->periph_matches);
8600 static struct cam_devitem *
8601 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8603 struct cam_devitem *item;
8605 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8606 struct scsi_vpd_id_descriptor *idd;
8609 * XXX KDM look for LUN IDs as well?
8611 idd = scsi_get_devid(item->device_id,
8612 item->device_id_len,
8613 scsi_devid_is_sas_target);
8617 if (scsi_8btou64(idd->identifier) == sasaddr)
8625 smpphylist(struct cam_device *device, int argc, char **argv,
8626 char *combinedopt, int retry_count, int timeout)
8628 struct smp_report_general_request *rgrequest = NULL;
8629 struct smp_report_general_response *rgresponse = NULL;
8630 struct smp_discover_request *disrequest = NULL;
8631 struct smp_discover_response *disresponse = NULL;
8632 struct cam_devlist devlist;
8634 int long_response = 0;
8641 * Note that at the moment we don't support sending SMP CCBs to
8642 * devices that aren't probed by CAM.
8644 ccb = cam_getccb(device);
8646 warnx("%s: error allocating CCB", __func__);
8650 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8651 STAILQ_INIT(&devlist.dev_queue);
8653 rgrequest = malloc(sizeof(*rgrequest));
8654 if (rgrequest == NULL) {
8655 warn("%s: unable to allocate %zd bytes", __func__,
8656 sizeof(*rgrequest));
8661 rgresponse = malloc(sizeof(*rgresponse));
8662 if (rgresponse == NULL) {
8663 warn("%s: unable to allocate %zd bytes", __func__,
8664 sizeof(*rgresponse));
8669 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8682 smp_report_general(&ccb->smpio,
8686 /*request_len*/ sizeof(*rgrequest),
8687 (uint8_t *)rgresponse,
8688 /*response_len*/ sizeof(*rgresponse),
8689 /*long_response*/ long_response,
8692 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8694 if (((retval = cam_send_ccb(device, ccb)) < 0)
8695 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8696 const char warnstr[] = "error sending command";
8703 if (arglist & CAM_ARG_VERBOSE) {
8704 cam_error_print(device, ccb, CAM_ESF_ALL,
8705 CAM_EPF_ALL, stderr);
8711 num_phys = rgresponse->num_phys;
8713 if (num_phys == 0) {
8715 fprintf(stdout, "%s: No Phys reported\n", __func__);
8720 devlist.path_id = device->path_id;
8722 retval = buildbusdevlist(&devlist);
8727 fprintf(stdout, "%d PHYs:\n", num_phys);
8728 fprintf(stdout, "PHY Attached SAS Address\n");
8731 disrequest = malloc(sizeof(*disrequest));
8732 if (disrequest == NULL) {
8733 warn("%s: unable to allocate %zd bytes", __func__,
8734 sizeof(*disrequest));
8739 disresponse = malloc(sizeof(*disresponse));
8740 if (disresponse == NULL) {
8741 warn("%s: unable to allocate %zd bytes", __func__,
8742 sizeof(*disresponse));
8747 for (i = 0; i < num_phys; i++) {
8748 struct cam_devitem *item;
8749 struct device_match_result *dev_match;
8750 char vendor[16], product[48], revision[16];
8754 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8756 ccb->ccb_h.status = CAM_REQ_INPROG;
8757 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8759 smp_discover(&ccb->smpio,
8763 sizeof(*disrequest),
8764 (uint8_t *)disresponse,
8765 sizeof(*disresponse),
8767 /*ignore_zone_group*/ 0,
8771 if (((retval = cam_send_ccb(device, ccb)) < 0)
8772 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
8773 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
8774 const char warnstr[] = "error sending command";
8781 if (arglist & CAM_ARG_VERBOSE) {
8782 cam_error_print(device, ccb, CAM_ESF_ALL,
8783 CAM_EPF_ALL, stderr);
8789 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
8791 fprintf(stdout, "%3d <vacant>\n", i);
8795 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
8798 item = findsasdevice(&devlist,
8799 scsi_8btou64(disresponse->attached_sas_address));
8803 || (item != NULL)) {
8804 fprintf(stdout, "%3d 0x%016jx", i,
8805 (uintmax_t)scsi_8btou64(
8806 disresponse->attached_sas_address));
8808 fprintf(stdout, "\n");
8811 } else if (quiet != 0)
8814 dev_match = &item->dev_match;
8816 if (dev_match->protocol == PROTO_SCSI) {
8817 cam_strvis(vendor, dev_match->inq_data.vendor,
8818 sizeof(dev_match->inq_data.vendor),
8820 cam_strvis(product, dev_match->inq_data.product,
8821 sizeof(dev_match->inq_data.product),
8823 cam_strvis(revision, dev_match->inq_data.revision,
8824 sizeof(dev_match->inq_data.revision),
8826 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8828 } else if ((dev_match->protocol == PROTO_ATA)
8829 || (dev_match->protocol == PROTO_SATAPM)) {
8830 cam_strvis(product, dev_match->ident_data.model,
8831 sizeof(dev_match->ident_data.model),
8833 cam_strvis(revision, dev_match->ident_data.revision,
8834 sizeof(dev_match->ident_data.revision),
8836 sprintf(tmpstr, "<%s %s>", product, revision);
8838 sprintf(tmpstr, "<>");
8840 fprintf(stdout, " %-33s ", tmpstr);
8843 * If we have 0 periphs, that's a bug...
8845 if (item->num_periphs == 0) {
8846 fprintf(stdout, "\n");
8850 fprintf(stdout, "(");
8851 for (j = 0; j < item->num_periphs; j++) {
8853 fprintf(stdout, ",");
8855 fprintf(stdout, "%s%d",
8856 item->periph_matches[j].periph_name,
8857 item->periph_matches[j].unit_number);
8860 fprintf(stdout, ")\n");
8874 freebusdevlist(&devlist);
8880 atapm(struct cam_device *device, int argc, char **argv,
8881 char *combinedopt, int retry_count, int timeout)
8889 ccb = cam_getccb(device);
8892 warnx("%s: error allocating ccb", __func__);
8896 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8905 if (strcmp(argv[1], "idle") == 0) {
8907 cmd = ATA_IDLE_IMMEDIATE;
8910 } else if (strcmp(argv[1], "standby") == 0) {
8912 cmd = ATA_STANDBY_IMMEDIATE;
8914 cmd = ATA_STANDBY_CMD;
8922 else if (t <= (240 * 5))
8924 else if (t <= (252 * 5))
8925 /* special encoding for 21 minutes */
8927 else if (t <= (11 * 30 * 60))
8928 sc = (t - 1) / (30 * 60) + 241;
8932 retval = ata_do_28bit_cmd(device,
8934 /*retries*/retry_count,
8935 /*flags*/CAM_DIR_NONE,
8936 /*protocol*/AP_PROTO_NON_DATA,
8937 /*tag_action*/MSG_SIMPLE_Q_TAG,
8944 /*timeout*/timeout ? timeout : 30 * 1000,
8952 ataaxm(struct cam_device *device, int argc, char **argv,
8953 char *combinedopt, int retry_count, int timeout)
8961 ccb = cam_getccb(device);
8964 warnx("%s: error allocating ccb", __func__);
8968 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8978 if (strcmp(argv[1], "apm") == 0) {
8994 retval = ata_do_28bit_cmd(device,
8996 /*retries*/retry_count,
8997 /*flags*/CAM_DIR_NONE,
8998 /*protocol*/AP_PROTO_NON_DATA,
8999 /*tag_action*/MSG_SIMPLE_Q_TAG,
9000 /*command*/ATA_SETFEATURES,
9006 /*timeout*/timeout ? timeout : 30 * 1000,
9014 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9015 int show_sa_errors, int sa_set, int service_action,
9016 int timeout_desc, int task_attr, int retry_count, int timeout,
9017 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9019 union ccb *ccb = NULL;
9020 uint8_t *buf = NULL;
9021 uint32_t alloc_len = 0, num_opcodes;
9022 uint32_t valid_len = 0;
9023 uint32_t avail_len = 0;
9024 struct scsi_report_supported_opcodes_all *all_hdr;
9025 struct scsi_report_supported_opcodes_one *one;
9030 * Make it clear that we haven't yet allocated or filled anything.
9035 ccb = cam_getccb(device);
9037 warnx("couldn't allocate CCB");
9042 /* cam_getccb cleans up the header, caller has to zero the payload */
9043 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9045 if (opcode_set != 0) {
9046 options |= RSO_OPTIONS_OC;
9048 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9051 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9052 sizeof(struct scsi_report_supported_opcodes_descr));
9055 if (timeout_desc != 0) {
9056 options |= RSO_RCTD;
9057 alloc_len += num_opcodes *
9058 sizeof(struct scsi_report_supported_opcodes_timeout);
9062 options |= RSO_OPTIONS_OC_SA;
9063 if (show_sa_errors != 0)
9064 options &= ~RSO_OPTIONS_OC;
9073 buf = malloc(alloc_len);
9075 warn("Unable to allocate %u bytes", alloc_len);
9079 bzero(buf, alloc_len);
9081 scsi_report_supported_opcodes(&ccb->csio,
9082 /*retries*/ retry_count,
9084 /*tag_action*/ task_attr,
9085 /*options*/ options,
9086 /*req_opcode*/ opcode,
9087 /*req_service_action*/ service_action,
9089 /*dxfer_len*/ alloc_len,
9090 /*sense_len*/ SSD_FULL_SIZE,
9091 /*timeout*/ timeout ? timeout : 10000);
9093 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9095 if (retry_count != 0)
9096 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9098 if (cam_send_ccb(device, ccb) < 0) {
9099 perror("error sending REPORT SUPPORTED OPERATION CODES");
9104 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9105 if (verbosemode != 0)
9106 cam_error_print(device, ccb, CAM_ESF_ALL,
9107 CAM_EPF_ALL, stderr);
9112 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9114 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9115 && (valid_len >= sizeof(*all_hdr))) {
9116 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9117 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9118 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9119 && (valid_len >= sizeof(*one))) {
9120 uint32_t cdb_length;
9122 one = (struct scsi_report_supported_opcodes_one *)buf;
9123 cdb_length = scsi_2btoul(one->cdb_length);
9124 avail_len = sizeof(*one) + cdb_length;
9125 if (one->support & RSO_ONE_CTDP) {
9126 struct scsi_report_supported_opcodes_timeout *td;
9128 td = (struct scsi_report_supported_opcodes_timeout *)
9130 if (valid_len >= (avail_len + sizeof(td->length))) {
9131 avail_len += scsi_2btoul(td->length) +
9134 avail_len += sizeof(*td);
9140 * avail_len could be zero if we didn't get enough data back from
9141 * thet target to determine
9143 if ((avail_len != 0)
9144 && (avail_len > valid_len)) {
9145 alloc_len = avail_len;
9149 *fill_len = valid_len;
9161 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9162 int req_sa, uint8_t *buf, uint32_t valid_len)
9164 struct scsi_report_supported_opcodes_one *one;
9165 struct scsi_report_supported_opcodes_timeout *td;
9166 uint32_t cdb_len = 0, td_len = 0;
9167 const char *op_desc = NULL;
9171 one = (struct scsi_report_supported_opcodes_one *)buf;
9174 * If we don't have the full single opcode descriptor, no point in
9177 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9179 warnx("Only %u bytes returned, not enough to verify support",
9185 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9187 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9190 printf(", SA 0x%x", req_sa);
9193 switch (one->support & RSO_ONE_SUP_MASK) {
9194 case RSO_ONE_SUP_UNAVAIL:
9195 printf("No command support information currently available\n");
9197 case RSO_ONE_SUP_NOT_SUP:
9198 printf("Command not supported\n");
9201 break; /*NOTREACHED*/
9202 case RSO_ONE_SUP_AVAIL:
9203 printf("Command is supported, complies with a SCSI standard\n");
9205 case RSO_ONE_SUP_VENDOR:
9206 printf("Command is supported, vendor-specific "
9207 "implementation\n");
9210 printf("Unknown command support flags 0x%#x\n",
9211 one->support & RSO_ONE_SUP_MASK);
9216 * If we don't have the CDB length, it isn't exactly an error, the
9217 * command probably isn't supported.
9219 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9223 cdb_len = scsi_2btoul(one->cdb_length);
9226 * If our valid data doesn't include the full reported length,
9227 * return. The caller should have detected this and adjusted his
9228 * allocation length to get all of the available data.
9230 if (valid_len < sizeof(*one) + cdb_len) {
9236 * If all we have is the opcode, there is no point in printing out
9244 printf("CDB usage bitmap:");
9245 for (i = 0; i < cdb_len; i++) {
9246 printf(" %02x", one->cdb_usage[i]);
9251 * If we don't have a timeout descriptor, we're done.
9253 if ((one->support & RSO_ONE_CTDP) == 0)
9257 * If we don't have enough valid length to include the timeout
9258 * descriptor length, we're done.
9260 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9263 td = (struct scsi_report_supported_opcodes_timeout *)
9264 &buf[sizeof(*one) + cdb_len];
9265 td_len = scsi_2btoul(td->length);
9266 td_len += sizeof(td->length);
9269 * If we don't have the full timeout descriptor, we're done.
9271 if (td_len < sizeof(*td))
9275 * If we don't have enough valid length to contain the full timeout
9276 * descriptor, we're done.
9278 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9281 printf("Timeout information:\n");
9282 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9283 printf("Nominal timeout: %u seconds\n",
9284 scsi_4btoul(td->nominal_time));
9285 printf("Recommended timeout: %u seconds\n",
9286 scsi_4btoul(td->recommended_time));
9293 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9296 struct scsi_report_supported_opcodes_all *hdr;
9297 struct scsi_report_supported_opcodes_descr *desc;
9298 uint32_t avail_len = 0, used_len = 0;
9302 if (valid_len < sizeof(*hdr)) {
9303 warnx("%s: not enough returned data (%u bytes) opcode list",
9304 __func__, valid_len);
9308 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9309 avail_len = scsi_4btoul(hdr->length);
9310 avail_len += sizeof(hdr->length);
9312 * Take the lesser of the amount of data the drive claims is
9313 * available, and the amount of data the HBA says was returned.
9315 avail_len = MIN(avail_len, valid_len);
9317 used_len = sizeof(hdr->length);
9319 printf("%-6s %4s %8s ",
9320 "Opcode", "SA", "CDB len" );
9323 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9324 printf(" Description\n");
9326 while ((avail_len - used_len) > sizeof(*desc)) {
9327 struct scsi_report_supported_opcodes_timeout *td;
9329 const char *op_desc = NULL;
9331 cur_ptr = &buf[used_len];
9332 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9334 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9335 if (op_desc == NULL)
9336 op_desc = "UNKNOWN";
9338 printf("0x%02x %#4x %8u ", desc->opcode,
9339 scsi_2btoul(desc->service_action),
9340 scsi_2btoul(desc->cdb_length));
9342 used_len += sizeof(*desc);
9344 if ((desc->flags & RSO_CTDP) == 0) {
9345 printf(" %s\n", op_desc);
9350 * If we don't have enough space to fit a timeout
9351 * descriptor, then we're done.
9353 if (avail_len - used_len < sizeof(*td)) {
9354 used_len = avail_len;
9355 printf(" %s\n", op_desc);
9358 cur_ptr = &buf[used_len];
9359 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9360 td_len = scsi_2btoul(td->length);
9361 td_len += sizeof(td->length);
9365 * If the given timeout descriptor length is less than what
9366 * we understand, skip it.
9368 if (td_len < sizeof(*td)) {
9369 printf(" %s\n", op_desc);
9373 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9374 scsi_4btoul(td->nominal_time),
9375 scsi_4btoul(td->recommended_time), op_desc);
9382 scsiopcodes(struct cam_device *device, int argc, char **argv,
9383 char *combinedopt, int task_attr, int retry_count, int timeout,
9387 uint32_t opcode = 0, service_action = 0;
9388 int td_set = 0, opcode_set = 0, sa_set = 0;
9389 int show_sa_errors = 1;
9390 uint32_t valid_len = 0;
9391 uint8_t *buf = NULL;
9395 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9401 opcode = strtoul(optarg, &endptr, 0);
9402 if (*endptr != '\0') {
9403 warnx("Invalid opcode \"%s\", must be a number",
9408 if (opcode > 0xff) {
9409 warnx("Invalid opcode 0x%#x, must be between"
9410 "0 and 0xff inclusive", opcode);
9417 service_action = strtoul(optarg, &endptr, 0);
9418 if (*endptr != '\0') {
9419 warnx("Invalid service action \"%s\", must "
9420 "be a number", optarg);
9424 if (service_action > 0xffff) {
9425 warnx("Invalid service action 0x%#x, must "
9426 "be between 0 and 0xffff inclusive",
9441 && (opcode_set == 0)) {
9442 warnx("You must specify an opcode with -o if a service "
9447 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9448 sa_set, service_action, td_set, task_attr,
9449 retry_count, timeout, verbosemode, &valid_len,
9454 if ((opcode_set != 0)
9456 retval = scsiprintoneopcode(device, opcode, sa_set,
9457 service_action, buf, valid_len);
9459 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9468 #endif /* MINIMALISTIC */
9471 scsireprobe(struct cam_device *device)
9476 ccb = cam_getccb(device);
9479 warnx("%s: error allocating ccb", __func__);
9483 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9485 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9487 if (cam_send_ccb(device, ccb) < 0) {
9488 warn("error sending XPT_REPROBE_LUN CCB");
9493 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9494 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9506 usage(int printlong)
9509 fprintf(printlong ? stdout : stderr,
9510 "usage: camcontrol <command> [device id][generic args][command args]\n"
9511 " camcontrol devlist [-b] [-v]\n"
9512 #ifndef MINIMALISTIC
9513 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9514 " camcontrol tur [dev_id][generic args]\n"
9515 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9516 " camcontrol identify [dev_id][generic args] [-v]\n"
9517 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9518 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9520 " camcontrol start [dev_id][generic args]\n"
9521 " camcontrol stop [dev_id][generic args]\n"
9522 " camcontrol load [dev_id][generic args]\n"
9523 " camcontrol eject [dev_id][generic args]\n"
9524 " camcontrol reprobe [dev_id][generic args]\n"
9525 #endif /* MINIMALISTIC */
9526 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9527 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9528 #ifndef MINIMALISTIC
9529 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9530 " [-q][-s][-S offset][-X]\n"
9531 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9532 " [-P pagectl][-e | -b][-d]\n"
9533 " camcontrol cmd [dev_id][generic args]\n"
9534 " <-a cmd [args] | -c cmd [args]>\n"
9535 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9536 " camcontrol smpcmd [dev_id][generic args]\n"
9537 " <-r len fmt [args]> <-R len fmt [args]>\n"
9538 " camcontrol smprg [dev_id][generic args][-l]\n"
9539 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9540 " [-o operation][-d name][-m rate][-M rate]\n"
9541 " [-T pp_timeout][-a enable|disable]\n"
9542 " [-A enable|disable][-s enable|disable]\n"
9543 " [-S enable|disable]\n"
9544 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9545 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9546 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9547 " <all|bus[:target[:lun]]|off>\n"
9548 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9549 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9550 " [-D <enable|disable>][-M mode][-O offset]\n"
9551 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9552 " [-U][-W bus_width]\n"
9553 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9554 " camcontrol sanitize [dev_id][generic args]\n"
9555 " [-a overwrite|block|crypto|exitfailure]\n"
9556 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9558 " camcontrol idle [dev_id][generic args][-t time]\n"
9559 " camcontrol standby [dev_id][generic args][-t time]\n"
9560 " camcontrol sleep [dev_id][generic args]\n"
9561 " camcontrol apm [dev_id][generic args][-l level]\n"
9562 " camcontrol aam [dev_id][generic args][-l level]\n"
9563 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9565 " camcontrol security [dev_id][generic args]\n"
9566 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9567 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9568 " [-U <user|master>] [-y]\n"
9569 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9570 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9571 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9572 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9573 " [-s scope][-S][-T type][-U]\n"
9574 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9575 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9576 " [-p part][-s start][-T type][-V vol]\n"
9577 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9579 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9580 " [-o rep_opts] [-P print_opts]\n"
9581 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9582 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9583 " [-S power_src] [-T timer]\n"
9584 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9585 " <-s <-f format -T time | -U >>\n"
9587 #endif /* MINIMALISTIC */
9588 " camcontrol help\n");
9591 #ifndef MINIMALISTIC
9593 "Specify one of the following options:\n"
9594 "devlist list all CAM devices\n"
9595 "periphlist list all CAM peripheral drivers attached to a device\n"
9596 "tur send a test unit ready to the named device\n"
9597 "inquiry send a SCSI inquiry command to the named device\n"
9598 "identify send a ATA identify command to the named device\n"
9599 "reportluns send a SCSI report luns command to the device\n"
9600 "readcap send a SCSI read capacity command to the device\n"
9601 "start send a Start Unit command to the device\n"
9602 "stop send a Stop Unit command to the device\n"
9603 "load send a Start Unit command to the device with the load bit set\n"
9604 "eject send a Stop Unit command to the device with the eject bit set\n"
9605 "reprobe update capacity information of the given device\n"
9606 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9607 "reset reset all buses, the given bus, bus:target:lun or device\n"
9608 "defects read the defect list of the specified device\n"
9609 "modepage display or edit (-e) the given mode page\n"
9610 "cmd send the given SCSI command, may need -i or -o as well\n"
9611 "smpcmd send the given SMP command, requires -o and -i\n"
9612 "smprg send the SMP Report General command\n"
9613 "smppc send the SMP PHY Control command, requires -p\n"
9614 "smpphylist display phys attached to a SAS expander\n"
9615 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9616 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9617 "tags report or set the number of transaction slots for a device\n"
9618 "negotiate report or set device negotiation parameters\n"
9619 "format send the SCSI FORMAT UNIT command to the named device\n"
9620 "sanitize send the SCSI SANITIZE command to the named device\n"
9621 "idle send the ATA IDLE command to the named device\n"
9622 "standby send the ATA STANDBY command to the named device\n"
9623 "sleep send the ATA SLEEP command to the named device\n"
9624 "fwdownload program firmware of the named device with the given image\n"
9625 "security report or send ATA security commands to the named device\n"
9626 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9627 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9628 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9629 "zone manage Zoned Block (Shingled) devices\n"
9630 "epc send ATA Extended Power Conditions commands\n"
9631 "timestamp report or set the device's timestamp\n"
9632 "help this message\n"
9633 "Device Identifiers:\n"
9634 "bus:target specify the bus and target, lun defaults to 0\n"
9635 "bus:target:lun specify the bus, target and lun\n"
9636 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
9637 "Generic arguments:\n"
9638 "-v be verbose, print out sense information\n"
9639 "-t timeout command timeout in seconds, overrides default timeout\n"
9640 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
9641 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
9642 "-E have the kernel attempt to perform SCSI error recovery\n"
9643 "-C count specify the SCSI command retry count (needs -E to work)\n"
9644 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
9645 "modepage arguments:\n"
9646 "-l list all available mode pages\n"
9647 "-m page specify the mode page to view or edit\n"
9648 "-e edit the specified mode page\n"
9649 "-b force view to binary mode\n"
9650 "-d disable block descriptors for mode sense\n"
9651 "-P pgctl page control field 0-3\n"
9652 "defects arguments:\n"
9653 "-f format specify defect list format (block, bfi or phys)\n"
9654 "-G get the grown defect list\n"
9655 "-P get the permanent defect list\n"
9656 "inquiry arguments:\n"
9657 "-D get the standard inquiry data\n"
9658 "-S get the serial number\n"
9659 "-R get the transfer rate, etc.\n"
9660 "reportluns arguments:\n"
9661 "-c only report a count of available LUNs\n"
9662 "-l only print out luns, and not a count\n"
9663 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
9664 "readcap arguments\n"
9665 "-b only report the blocksize\n"
9666 "-h human readable device size, base 2\n"
9667 "-H human readable device size, base 10\n"
9668 "-N print the number of blocks instead of last block\n"
9669 "-q quiet, print numbers only\n"
9670 "-s only report the last block/device size\n"
9672 "-c cdb [args] specify the SCSI CDB\n"
9673 "-i len fmt specify input data and input data format\n"
9674 "-o len fmt [args] specify output data and output data fmt\n"
9675 "smpcmd arguments:\n"
9676 "-r len fmt [args] specify the SMP command to be sent\n"
9677 "-R len fmt [args] specify SMP response format\n"
9678 "smprg arguments:\n"
9679 "-l specify the long response format\n"
9680 "smppc arguments:\n"
9681 "-p phy specify the PHY to operate on\n"
9682 "-l specify the long request/response format\n"
9683 "-o operation specify the phy control operation\n"
9684 "-d name set the attached device name\n"
9685 "-m rate set the minimum physical link rate\n"
9686 "-M rate set the maximum physical link rate\n"
9687 "-T pp_timeout set the partial pathway timeout value\n"
9688 "-a enable|disable enable or disable SATA slumber\n"
9689 "-A enable|disable enable or disable SATA partial phy power\n"
9690 "-s enable|disable enable or disable SAS slumber\n"
9691 "-S enable|disable enable or disable SAS partial phy power\n"
9692 "smpphylist arguments:\n"
9693 "-l specify the long response format\n"
9694 "-q only print phys with attached devices\n"
9695 "smpmaninfo arguments:\n"
9696 "-l specify the long response format\n"
9697 "debug arguments:\n"
9698 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
9699 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
9700 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
9701 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
9703 "-N tags specify the number of tags to use for this device\n"
9704 "-q be quiet, don't report the number of tags\n"
9705 "-v report a number of tag-related parameters\n"
9706 "negotiate arguments:\n"
9707 "-a send a test unit ready after negotiation\n"
9708 "-c report/set current negotiation settings\n"
9709 "-D <arg> \"enable\" or \"disable\" disconnection\n"
9710 "-M mode set ATA mode\n"
9711 "-O offset set command delay offset\n"
9712 "-q be quiet, don't report anything\n"
9713 "-R syncrate synchronization rate in MHz\n"
9714 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
9715 "-U report/set user negotiation settings\n"
9716 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
9717 "-v also print a Path Inquiry CCB for the controller\n"
9718 "format arguments:\n"
9719 "-q be quiet, don't print status messages\n"
9720 "-r run in report only mode\n"
9721 "-w don't send immediate format command\n"
9722 "-y don't ask any questions\n"
9723 "sanitize arguments:\n"
9724 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
9725 "-c passes overwrite passes to perform (1 to 31)\n"
9726 "-I invert overwrite pattern after each pass\n"
9727 "-P pattern path to overwrite pattern file\n"
9728 "-q be quiet, don't print status messages\n"
9729 "-r run in report only mode\n"
9730 "-U run operation in unrestricted completion exit mode\n"
9731 "-w don't send immediate sanitize command\n"
9732 "-y don't ask any questions\n"
9733 "idle/standby arguments:\n"
9734 "-t <arg> number of seconds before respective state.\n"
9735 "fwdownload arguments:\n"
9736 "-f fw_image path to firmware image file\n"
9737 "-q don't print informational messages, only errors\n"
9738 "-s run in simulation mode\n"
9739 "-v print info for every firmware segment sent to device\n"
9740 "-y don't ask any questions\n"
9741 "security arguments:\n"
9742 "-d pwd disable security using the given password for the selected\n"
9744 "-e pwd erase the device using the given pwd for the selected user\n"
9745 "-f freeze the security configuration of the specified device\n"
9746 "-h pwd enhanced erase the device using the given pwd for the\n"
9748 "-k pwd unlock the device using the given pwd for the selected\n"
9750 "-l <high|maximum> specifies which security level to set: high or maximum\n"
9751 "-q be quiet, do not print any status messages\n"
9752 "-s pwd password the device (enable security) using the given\n"
9753 " pwd for the selected user\n"
9754 "-T timeout overrides the timeout (seconds) used for erase operation\n"
9755 "-U <user|master> specifies which user to set: user or master\n"
9756 "-y don't ask any questions\n"
9758 "-f freeze the HPA configuration of the device\n"
9759 "-l lock the HPA configuration of the device\n"
9760 "-P make the HPA max sectors persist\n"
9761 "-p pwd Set the HPA configuration password required for unlock\n"
9763 "-q be quiet, do not print any status messages\n"
9764 "-s sectors configures the maximum user accessible sectors of the\n"
9766 "-U pwd unlock the HPA configuration of the device\n"
9767 "-y don't ask any questions\n"
9768 "persist arguments:\n"
9769 "-i action specify read_keys, read_reservation, report_cap, or\n"
9770 " read_full_status\n"
9771 "-o action specify register, register_ignore, reserve, release,\n"
9772 " clear, preempt, preempt_abort, register_move, replace_lost\n"
9773 "-a set the All Target Ports (ALL_TG_PT) bit\n"
9774 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
9775 "-k key specify the Reservation Key\n"
9776 "-K sa_key specify the Service Action Reservation Key\n"
9777 "-p set the Activate Persist Through Power Loss bit\n"
9778 "-R rtp specify the Relative Target Port\n"
9779 "-s scope specify the scope: lun, extent, element or a number\n"
9780 "-S specify Transport ID for register, requires -I\n"
9781 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
9782 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
9783 "-U unregister the current initiator for register_move\n"
9784 "attrib arguments:\n"
9785 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
9787 "-w attr specify an attribute to write, one -w argument per attr\n"
9788 "-a attr_num only display this attribute number\n"
9789 "-c get cached attributes\n"
9790 "-e elem_addr request attributes for the given element in a changer\n"
9791 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
9792 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
9793 " field_none, field_desc, field_num, field_size, field_rw\n"
9794 "-p partition request attributes for the given partition\n"
9795 "-s start_attr request attributes starting at the given number\n"
9796 "-T elem_type specify the element type (used with -e)\n"
9797 "-V logical_vol specify the logical volume ID\n"
9798 "opcodes arguments:\n"
9799 "-o opcode specify the individual opcode to list\n"
9800 "-s service_action specify the service action for the opcode\n"
9801 "-N do not return SCSI error for unsupported SA\n"
9802 "-T request nominal and recommended timeout values\n"
9804 "-c cmd required: rz, open, close, finish, or rwp\n"
9805 "-a apply the action to all zones\n"
9806 "-l LBA specify the zone starting LBA\n"
9807 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
9808 " closed, full, ro, offline, reset, nonseq, nonwp\n"
9809 "-P print_opt report zones printing: normal, summary, script\n"
9811 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
9812 " source, status, list\n"
9813 "-d disable power mode (timer, state)\n"
9814 "-D delayed entry (goto)\n"
9815 "-e enable power mode (timer, state)\n"
9816 "-H hold power mode (goto)\n"
9817 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
9819 "-P only display power mode (status)\n"
9820 "-r rst_src restore settings from: default, saved (restore)\n"
9821 "-s save mode (timer, state, restore)\n"
9822 "-S power_src set power source: battery, nonbattery (source)\n"
9823 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
9824 "timestamp arguments:\n"
9825 "-r report the timestamp of the device\n"
9826 "-f format report the timestamp of the device with the given\n"
9827 " strftime(3) format string\n"
9828 "-m report the timestamp of the device as milliseconds since\n"
9829 " January 1st, 1970\n"
9830 "-U report the time with UTC instead of the local time zone\n"
9831 "-s set the timestamp of the device\n"
9832 "-f format the format of the time string passed into strptime(3)\n"
9833 "-T time the time value passed into strptime(3)\n"
9834 "-U set the timestamp of the device to UTC time\n"
9836 #endif /* MINIMALISTIC */
9840 main(int argc, char **argv)
9843 char *device = NULL;
9845 struct cam_device *cam_dev = NULL;
9846 int timeout = 0, retry_count = 1;
9847 camcontrol_optret optreturn;
9849 const char *mainopt = "C:En:Q:t:u:v";
9850 const char *subopt = NULL;
9851 char combinedopt[256];
9852 int error = 0, optstart = 2;
9853 int task_attr = MSG_SIMPLE_Q_TAG;
9855 #ifndef MINIMALISTIC
9859 #endif /* MINIMALISTIC */
9861 cmdlist = CAM_CMD_NONE;
9862 arglist = CAM_ARG_NONE;
9870 * Get the base option.
9872 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
9874 if (optreturn == CC_OR_AMBIGUOUS) {
9875 warnx("ambiguous option %s", argv[1]);
9878 } else if (optreturn == CC_OR_NOT_FOUND) {
9879 warnx("option %s not found", argv[1]);
9885 * Ahh, getopt(3) is a pain.
9887 * This is a gross hack. There really aren't many other good
9888 * options (excuse the pun) for parsing options in a situation like
9889 * this. getopt is kinda braindead, so you end up having to run
9890 * through the options twice, and give each invocation of getopt
9891 * the option string for the other invocation.
9893 * You would think that you could just have two groups of options.
9894 * The first group would get parsed by the first invocation of
9895 * getopt, and the second group would get parsed by the second
9896 * invocation of getopt. It doesn't quite work out that way. When
9897 * the first invocation of getopt finishes, it leaves optind pointing
9898 * to the argument _after_ the first argument in the second group.
9899 * So when the second invocation of getopt comes around, it doesn't
9900 * recognize the first argument it gets and then bails out.
9902 * A nice alternative would be to have a flag for getopt that says
9903 * "just keep parsing arguments even when you encounter an unknown
9904 * argument", but there isn't one. So there's no real clean way to
9905 * easily parse two sets of arguments without having one invocation
9906 * of getopt know about the other.
9908 * Without this hack, the first invocation of getopt would work as
9909 * long as the generic arguments are first, but the second invocation
9910 * (in the subfunction) would fail in one of two ways. In the case
9911 * where you don't set optreset, it would fail because optind may be
9912 * pointing to the argument after the one it should be pointing at.
9913 * In the case where you do set optreset, and reset optind, it would
9914 * fail because getopt would run into the first set of options, which
9915 * it doesn't understand.
9917 * All of this would "sort of" work if you could somehow figure out
9918 * whether optind had been incremented one option too far. The
9919 * mechanics of that, however, are more daunting than just giving
9920 * both invocations all of the expect options for either invocation.
9922 * Needless to say, I wouldn't mind if someone invented a better
9923 * (non-GPL!) command line parsing interface than getopt. I
9924 * wouldn't mind if someone added more knobs to getopt to make it
9925 * work better. Who knows, I may talk myself into doing it someday,
9926 * if the standards weenies let me. As it is, it just leads to
9927 * hackery like this and causes people to avoid it in some cases.
9929 * KDM, September 8th, 1998
9932 sprintf(combinedopt, "%s%s", mainopt, subopt);
9934 sprintf(combinedopt, "%s", mainopt);
9937 * For these options we do not parse optional device arguments and
9938 * we do not open a passthrough device.
9940 if ((cmdlist == CAM_CMD_RESCAN)
9941 || (cmdlist == CAM_CMD_RESET)
9942 || (cmdlist == CAM_CMD_DEVTREE)
9943 || (cmdlist == CAM_CMD_USAGE)
9944 || (cmdlist == CAM_CMD_DEBUG))
9947 #ifndef MINIMALISTIC
9949 && (argc > 2 && argv[2][0] != '-')) {
9953 if (isdigit(argv[2][0])) {
9954 /* device specified as bus:target[:lun] */
9955 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9957 errx(1, "numeric device specification must "
9958 "be either bus:target, or "
9960 /* default to 0 if lun was not specified */
9961 if ((arglist & CAM_ARG_LUN) == 0) {
9963 arglist |= CAM_ARG_LUN;
9967 if (cam_get_device(argv[2], name, sizeof name, &unit)
9969 errx(1, "%s", cam_errbuf);
9970 device = strdup(name);
9971 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
9975 #endif /* MINIMALISTIC */
9977 * Start getopt processing at argv[2/3], since we've already
9978 * accepted argv[1..2] as the command name, and as a possible
9984 * Now we run through the argument list looking for generic
9985 * options, and ignoring options that possibly belong to
9988 while ((c = getopt(argc, argv, combinedopt))!= -1){
9991 retry_count = strtol(optarg, NULL, 0);
9992 if (retry_count < 0)
9993 errx(1, "retry count %d is < 0",
9995 arglist |= CAM_ARG_RETRIES;
9998 arglist |= CAM_ARG_ERR_RECOVER;
10001 arglist |= CAM_ARG_DEVICE;
10003 while (isspace(*tstr) && (*tstr != '\0'))
10005 device = (char *)strdup(tstr);
10009 int table_entry = 0;
10012 while (isspace(*tstr) && (*tstr != '\0'))
10014 if (isdigit(*tstr)) {
10015 task_attr = strtol(tstr, &endptr, 0);
10016 if (*endptr != '\0') {
10017 errx(1, "Invalid queue option "
10022 scsi_nv_status status;
10024 table_size = sizeof(task_attrs) /
10025 sizeof(task_attrs[0]);
10026 status = scsi_get_nv(task_attrs,
10027 table_size, tstr, &table_entry,
10028 SCSI_NV_FLAG_IG_CASE);
10029 if (status == SCSI_NV_FOUND)
10030 task_attr = task_attrs[
10031 table_entry].value;
10033 errx(1, "%s option %s",
10034 (status == SCSI_NV_AMBIGUOUS)?
10035 "ambiguous" : "invalid",
10042 timeout = strtol(optarg, NULL, 0);
10044 errx(1, "invalid timeout %d", timeout);
10045 /* Convert the timeout from seconds to ms */
10047 arglist |= CAM_ARG_TIMEOUT;
10050 arglist |= CAM_ARG_UNIT;
10051 unit = strtol(optarg, NULL, 0);
10054 arglist |= CAM_ARG_VERBOSE;
10061 #ifndef MINIMALISTIC
10063 * For most commands we'll want to open the passthrough device
10064 * associated with the specified device. In the case of the rescan
10065 * commands, we don't use a passthrough device at all, just the
10066 * transport layer device.
10068 if (devopen == 1) {
10069 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10070 && (((arglist & CAM_ARG_DEVICE) == 0)
10071 || ((arglist & CAM_ARG_UNIT) == 0))) {
10072 errx(1, "subcommand \"%s\" requires a valid device "
10073 "identifier", argv[1]);
10076 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10077 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10078 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10080 errx(1,"%s", cam_errbuf);
10082 #endif /* MINIMALISTIC */
10085 * Reset optind to 2, and reset getopt, so these routines can parse
10086 * the arguments again.
10092 #ifndef MINIMALISTIC
10093 case CAM_CMD_DEVLIST:
10094 error = getdevlist(cam_dev);
10097 error = atahpa(cam_dev, retry_count, timeout,
10098 argc, argv, combinedopt);
10100 #endif /* MINIMALISTIC */
10101 case CAM_CMD_DEVTREE:
10102 error = getdevtree(argc, argv, combinedopt);
10104 #ifndef MINIMALISTIC
10106 error = testunitready(cam_dev, task_attr, retry_count,
10109 case CAM_CMD_INQUIRY:
10110 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10111 task_attr, retry_count, timeout);
10113 case CAM_CMD_IDENTIFY:
10114 error = identify(cam_dev, retry_count, timeout);
10116 case CAM_CMD_STARTSTOP:
10117 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10118 arglist & CAM_ARG_EJECT, task_attr,
10119 retry_count, timeout);
10121 #endif /* MINIMALISTIC */
10122 case CAM_CMD_RESCAN:
10123 error = dorescan_or_reset(argc, argv, 1);
10125 case CAM_CMD_RESET:
10126 error = dorescan_or_reset(argc, argv, 0);
10128 #ifndef MINIMALISTIC
10129 case CAM_CMD_READ_DEFECTS:
10130 error = readdefects(cam_dev, argc, argv, combinedopt,
10131 task_attr, retry_count, timeout);
10133 case CAM_CMD_MODE_PAGE:
10134 modepage(cam_dev, argc, argv, combinedopt,
10135 task_attr, retry_count, timeout);
10137 case CAM_CMD_SCSI_CMD:
10138 error = scsicmd(cam_dev, argc, argv, combinedopt,
10139 task_attr, retry_count, timeout);
10141 case CAM_CMD_MMCSD_CMD:
10142 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10143 retry_count, timeout);
10145 case CAM_CMD_SMP_CMD:
10146 error = smpcmd(cam_dev, argc, argv, combinedopt,
10147 retry_count, timeout);
10149 case CAM_CMD_SMP_RG:
10150 error = smpreportgeneral(cam_dev, argc, argv,
10151 combinedopt, retry_count,
10154 case CAM_CMD_SMP_PC:
10155 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10156 retry_count, timeout);
10158 case CAM_CMD_SMP_PHYLIST:
10159 error = smpphylist(cam_dev, argc, argv, combinedopt,
10160 retry_count, timeout);
10162 case CAM_CMD_SMP_MANINFO:
10163 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10164 retry_count, timeout);
10166 case CAM_CMD_DEBUG:
10167 error = camdebug(argc, argv, combinedopt);
10170 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10173 error = ratecontrol(cam_dev, task_attr, retry_count,
10174 timeout, argc, argv, combinedopt);
10176 case CAM_CMD_FORMAT:
10177 error = scsiformat(cam_dev, argc, argv,
10178 combinedopt, task_attr, retry_count,
10181 case CAM_CMD_REPORTLUNS:
10182 error = scsireportluns(cam_dev, argc, argv,
10183 combinedopt, task_attr,
10184 retry_count, timeout);
10186 case CAM_CMD_READCAP:
10187 error = scsireadcapacity(cam_dev, argc, argv,
10188 combinedopt, task_attr,
10189 retry_count, timeout);
10192 case CAM_CMD_STANDBY:
10193 case CAM_CMD_SLEEP:
10194 error = atapm(cam_dev, argc, argv,
10195 combinedopt, retry_count, timeout);
10199 error = ataaxm(cam_dev, argc, argv,
10200 combinedopt, retry_count, timeout);
10202 case CAM_CMD_SECURITY:
10203 error = atasecurity(cam_dev, retry_count, timeout,
10204 argc, argv, combinedopt);
10206 case CAM_CMD_DOWNLOAD_FW:
10207 error = fwdownload(cam_dev, argc, argv, combinedopt,
10208 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10211 case CAM_CMD_SANITIZE:
10212 error = scsisanitize(cam_dev, argc, argv,
10213 combinedopt, task_attr,
10214 retry_count, timeout);
10216 case CAM_CMD_PERSIST:
10217 error = scsipersist(cam_dev, argc, argv, combinedopt,
10218 task_attr, retry_count, timeout,
10219 arglist & CAM_ARG_VERBOSE,
10220 arglist & CAM_ARG_ERR_RECOVER);
10222 case CAM_CMD_ATTRIB:
10223 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10224 task_attr, retry_count, timeout,
10225 arglist & CAM_ARG_VERBOSE,
10226 arglist & CAM_ARG_ERR_RECOVER);
10228 case CAM_CMD_OPCODES:
10229 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10230 task_attr, retry_count, timeout,
10231 arglist & CAM_ARG_VERBOSE);
10233 case CAM_CMD_REPROBE:
10234 error = scsireprobe(cam_dev);
10237 error = zone(cam_dev, argc, argv, combinedopt,
10238 task_attr, retry_count, timeout,
10239 arglist & CAM_ARG_VERBOSE);
10242 error = epc(cam_dev, argc, argv, combinedopt,
10243 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10245 case CAM_CMD_TIMESTAMP:
10246 error = timestamp(cam_dev, argc, argv, combinedopt,
10247 task_attr, retry_count, timeout,
10248 arglist & CAM_ARG_VERBOSE);
10250 #endif /* MINIMALISTIC */
10251 case CAM_CMD_USAGE:
10260 if (cam_dev != NULL)
10261 cam_close_device(cam_dev);