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