2 * Copyright (c) 1997-2007 Kenneth D. Merry
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/ioctl.h>
33 #include <sys/stdint.h>
34 #include <sys/types.h>
36 #include <sys/endian.h>
53 #include <cam/cam_debug.h>
54 #include <cam/cam_ccb.h>
55 #include <cam/scsi/scsi_all.h>
56 #include <cam/scsi/scsi_da.h>
57 #include <cam/scsi/scsi_pass.h>
58 #include <cam/scsi/scsi_message.h>
59 #include <cam/scsi/smp_all.h>
60 #include <cam/ata/ata_all.h>
61 #include <cam/mmc/mmc_all.h>
63 #include "camcontrol.h"
65 #include "nvmecontrol_ext.h"
69 CAM_CMD_NONE = 0x00000000,
70 CAM_CMD_DEVLIST = 0x00000001,
71 CAM_CMD_TUR = 0x00000002,
72 CAM_CMD_INQUIRY = 0x00000003,
73 CAM_CMD_STARTSTOP = 0x00000004,
74 CAM_CMD_RESCAN = 0x00000005,
75 CAM_CMD_READ_DEFECTS = 0x00000006,
76 CAM_CMD_MODE_PAGE = 0x00000007,
77 CAM_CMD_SCSI_CMD = 0x00000008,
78 CAM_CMD_DEVTREE = 0x00000009,
79 CAM_CMD_USAGE = 0x0000000a,
80 CAM_CMD_DEBUG = 0x0000000b,
81 CAM_CMD_RESET = 0x0000000c,
82 CAM_CMD_FORMAT = 0x0000000d,
83 CAM_CMD_TAG = 0x0000000e,
84 CAM_CMD_RATE = 0x0000000f,
85 CAM_CMD_DETACH = 0x00000010,
86 CAM_CMD_REPORTLUNS = 0x00000011,
87 CAM_CMD_READCAP = 0x00000012,
88 CAM_CMD_IDENTIFY = 0x00000013,
89 CAM_CMD_IDLE = 0x00000014,
90 CAM_CMD_STANDBY = 0x00000015,
91 CAM_CMD_SLEEP = 0x00000016,
92 CAM_CMD_SMP_CMD = 0x00000017,
93 CAM_CMD_SMP_RG = 0x00000018,
94 CAM_CMD_SMP_PC = 0x00000019,
95 CAM_CMD_SMP_PHYLIST = 0x0000001a,
96 CAM_CMD_SMP_MANINFO = 0x0000001b,
97 CAM_CMD_DOWNLOAD_FW = 0x0000001c,
98 CAM_CMD_SECURITY = 0x0000001d,
99 CAM_CMD_HPA = 0x0000001e,
100 CAM_CMD_SANITIZE = 0x0000001f,
101 CAM_CMD_PERSIST = 0x00000020,
102 CAM_CMD_APM = 0x00000021,
103 CAM_CMD_AAM = 0x00000022,
104 CAM_CMD_ATTRIB = 0x00000023,
105 CAM_CMD_OPCODES = 0x00000024,
106 CAM_CMD_REPROBE = 0x00000025,
107 CAM_CMD_ZONE = 0x00000026,
108 CAM_CMD_EPC = 0x00000027,
109 CAM_CMD_TIMESTAMP = 0x00000028,
110 CAM_CMD_MMCSD_CMD = 0x00000029,
111 CAM_CMD_POWER_MODE = 0x0000002a,
112 CAM_CMD_DEVTYPE = 0x0000002b,
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 {
155 struct ata_res_pass16 {
156 u_int16_t reserved[5];
159 u_int8_t sector_count_exp;
160 u_int8_t sector_count;
161 u_int8_t lba_low_exp;
163 u_int8_t lba_mid_exp;
165 u_int8_t lba_high_exp;
171 struct ata_set_max_pwd
174 u_int8_t password[32];
175 u_int16_t reserved2[239];
178 static struct scsi_nv task_attrs[] = {
179 { "simple", MSG_SIMPLE_Q_TAG },
180 { "head", MSG_HEAD_OF_Q_TAG },
181 { "ordered", MSG_ORDERED_Q_TAG },
182 { "iwr", MSG_IGN_WIDE_RESIDUE },
183 { "aca", MSG_ACA_TASK }
186 static const char scsicmd_opts[] = "a:c:dfi:o:r";
187 static const char readdefect_opts[] = "f:GPqsS:X";
188 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
189 static const char smprg_opts[] = "l";
190 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
191 static const char smpphylist_opts[] = "lq";
194 static struct camcontrol_opts option_table[] = {
195 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
196 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
197 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
198 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
199 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
200 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
201 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
202 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
203 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHlNqs"},
204 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
205 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
206 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
207 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
208 {"mmcsdcmd", CAM_CMD_MMCSD_CMD, CAM_ARG_NONE, "c:a:f:Wb:l:41S:I"},
209 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
210 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
211 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
212 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
213 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
214 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
215 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
216 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
217 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
218 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
219 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
220 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
221 {"devtype", CAM_CMD_DEVTYPE, CAM_ARG_NONE, ""},
222 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
223 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
224 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
225 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
226 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
227 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
228 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
229 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
230 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
231 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
232 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
233 {"powermode", CAM_CMD_POWER_MODE, CAM_ARG_NONE, ""},
234 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
235 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
236 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
237 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
238 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
239 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
240 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
241 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
242 {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
243 {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
244 {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
245 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
246 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
247 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
252 struct device_match_result dev_match;
254 struct periph_match_result *periph_matches;
255 struct scsi_vpd_device_id *device_id;
257 STAILQ_ENTRY(cam_devitem) links;
261 STAILQ_HEAD(, cam_devitem) dev_queue;
265 static cam_cmdmask cmdlist;
266 static cam_argmask arglist;
268 static const char *devtype_names[] = {
278 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
279 uint32_t *cmdnum, cam_argmask *argnum,
280 const char **subopt);
281 static int getdevlist(struct cam_device *device);
282 static int getdevtree(int argc, char **argv, char *combinedopt);
283 static int getdevtype(struct cam_device *device);
284 static int print_dev_scsi(struct device_match_result *dev_result, char *tmpstr);
285 static int print_dev_ata(struct device_match_result *dev_result, char *tmpstr);
286 static int print_dev_semb(struct device_match_result *dev_result, char *tmpstr);
287 static int print_dev_mmcsd(struct device_match_result *dev_result,
290 static int print_dev_nvme(struct device_match_result *dev_result, char *tmpstr);
292 static int testunitready(struct cam_device *device, int task_attr,
293 int retry_count, int timeout, int quiet);
294 static int scsistart(struct cam_device *device, int startstop, int loadeject,
295 int task_attr, int retry_count, int timeout);
296 static int scsiinquiry(struct cam_device *device, int task_attr,
297 int retry_count, int timeout);
298 static int scsiserial(struct cam_device *device, int task_attr,
299 int retry_count, int timeout);
300 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
301 lun_id_t *lun, cam_argmask *arglst);
302 static int dorescan_or_reset(int argc, char **argv, int rescan);
303 static int rescan_or_reset_bus(path_id_t bus, int rescan);
304 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
305 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);
373 #define min(a,b) (((a)<(b))?(a):(b))
376 #define max(a,b) (((a)>(b))?(a):(b))
380 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
381 cam_argmask *argnum, const char **subopt)
383 struct camcontrol_opts *opts;
386 for (opts = table; (opts != NULL) && (opts->optname != NULL);
388 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
389 *cmdnum = opts->cmdnum;
390 *argnum = opts->argnum;
391 *subopt = opts->subopt;
392 if (++num_matches > 1)
393 return (CC_OR_AMBIGUOUS);
398 return (CC_OR_FOUND);
400 return (CC_OR_NOT_FOUND);
404 getdevlist(struct cam_device *device)
410 ccb = cam_getccb(device);
412 ccb->ccb_h.func_code = XPT_GDEVLIST;
413 ccb->ccb_h.flags = CAM_DIR_NONE;
414 ccb->ccb_h.retry_count = 1;
416 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
417 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
418 if (cam_send_ccb(device, ccb) < 0) {
419 perror("error getting device list");
426 switch (ccb->cgdl.status) {
427 case CAM_GDEVLIST_MORE_DEVS:
428 strcpy(status, "MORE");
430 case CAM_GDEVLIST_LAST_DEVICE:
431 strcpy(status, "LAST");
433 case CAM_GDEVLIST_LIST_CHANGED:
434 strcpy(status, "CHANGED");
436 case CAM_GDEVLIST_ERROR:
437 strcpy(status, "ERROR");
442 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
443 ccb->cgdl.periph_name,
444 ccb->cgdl.unit_number,
445 ccb->cgdl.generation,
450 * If the list has changed, we need to start over from the
453 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
463 getdevtree(int argc, char **argv, char *combinedopt)
474 while ((c = getopt(argc, argv, combinedopt)) != -1) {
477 if ((arglist & CAM_ARG_VERBOSE) == 0)
485 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
486 warn("couldn't open %s", XPT_DEVICE);
490 bzero(&ccb, sizeof(union ccb));
492 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
493 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
494 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
496 ccb.ccb_h.func_code = XPT_DEV_MATCH;
497 bufsize = sizeof(struct dev_match_result) * 100;
498 ccb.cdm.match_buf_len = bufsize;
499 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
500 if (ccb.cdm.matches == NULL) {
501 warnx("can't malloc memory for matches");
505 ccb.cdm.num_matches = 0;
508 * We fetch all nodes, since we display most of them in the default
509 * case, and all in the verbose case.
511 ccb.cdm.num_patterns = 0;
512 ccb.cdm.pattern_buf_len = 0;
515 * We do the ioctl multiple times if necessary, in case there are
516 * more than 100 nodes in the EDT.
519 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
520 warn("error sending CAMIOCOMMAND ioctl");
525 if ((ccb.ccb_h.status != CAM_REQ_CMP)
526 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
527 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
528 warnx("got CAM error %#x, CDM error %d\n",
529 ccb.ccb_h.status, ccb.cdm.status);
534 for (i = 0; i < ccb.cdm.num_matches; i++) {
535 switch (ccb.cdm.matches[i].type) {
536 case DEV_MATCH_BUS: {
537 struct bus_match_result *bus_result;
540 * Only print the bus information if the
541 * user turns on the verbose flag.
543 if ((busonly == 0) &&
544 (arglist & CAM_ARG_VERBOSE) == 0)
548 &ccb.cdm.matches[i].result.bus_result;
551 fprintf(stdout, ")\n");
555 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
557 bus_result->dev_name,
558 bus_result->unit_number,
560 (busonly ? "" : ":"));
563 case DEV_MATCH_DEVICE: {
564 struct device_match_result *dev_result;
571 &ccb.cdm.matches[i].result.device_result;
573 if ((dev_result->flags
574 & DEV_RESULT_UNCONFIGURED)
575 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
581 if (dev_result->protocol == PROTO_SCSI) {
582 if (print_dev_scsi(dev_result,
587 } else if (dev_result->protocol == PROTO_ATA ||
588 dev_result->protocol == PROTO_SATAPM) {
589 if (print_dev_ata(dev_result,
594 } else if (dev_result->protocol == PROTO_MMCSD){
595 if (print_dev_mmcsd(dev_result,
600 } else if (dev_result->protocol == PROTO_SEMB) {
601 if (print_dev_semb(dev_result,
607 } else if (dev_result->protocol == PROTO_NVME) {
608 if (print_dev_nvme(dev_result,
615 sprintf(tmpstr, "<>");
618 fprintf(stdout, ")\n");
622 fprintf(stdout, "%-33s at scbus%d "
623 "target %d lun %jx (",
626 dev_result->target_id,
627 (uintmax_t)dev_result->target_lun);
633 case DEV_MATCH_PERIPH: {
634 struct periph_match_result *periph_result;
637 &ccb.cdm.matches[i].result.periph_result;
639 if (busonly || skip_device != 0)
643 fprintf(stdout, ",");
645 fprintf(stdout, "%s%d",
646 periph_result->periph_name,
647 periph_result->unit_number);
653 fprintf(stdout, "unknown match type\n");
658 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
659 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
662 fprintf(stdout, ")\n");
670 getdevtype(struct cam_device *cam_dev)
672 camcontrol_devtype dt;
676 * Get the device type and report it, request no I/O be done to do this.
678 error = get_device_type(cam_dev, -1, 0, 0, &dt);
679 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
680 fprintf(stdout, "illegal\n");
683 fprintf(stdout, "%s\n", devtype_names[dt]);
688 print_dev_scsi(struct device_match_result *dev_result, char *tmpstr)
690 char vendor[16], product[48], revision[16];
692 cam_strvis(vendor, dev_result->inq_data.vendor,
693 sizeof(dev_result->inq_data.vendor), sizeof(vendor));
694 cam_strvis(product, dev_result->inq_data.product,
695 sizeof(dev_result->inq_data.product), sizeof(product));
696 cam_strvis(revision, dev_result->inq_data.revision,
697 sizeof(dev_result->inq_data.revision), sizeof(revision));
698 sprintf(tmpstr, "<%s %s %s>", vendor, product, revision);
704 print_dev_ata(struct device_match_result *dev_result, char *tmpstr)
706 char product[48], revision[16];
708 cam_strvis(product, dev_result->ident_data.model,
709 sizeof(dev_result->ident_data.model), sizeof(product));
710 cam_strvis(revision, dev_result->ident_data.revision,
711 sizeof(dev_result->ident_data.revision), sizeof(revision));
712 sprintf(tmpstr, "<%s %s>", product, revision);
718 print_dev_semb(struct device_match_result *dev_result, char *tmpstr)
720 struct sep_identify_data *sid;
721 char vendor[16], product[48], revision[16], fw[5];
723 sid = (struct sep_identify_data *)&dev_result->ident_data;
724 cam_strvis(vendor, sid->vendor_id,
725 sizeof(sid->vendor_id), sizeof(vendor));
726 cam_strvis(product, sid->product_id,
727 sizeof(sid->product_id), sizeof(product));
728 cam_strvis(revision, sid->product_rev,
729 sizeof(sid->product_rev), sizeof(revision));
730 cam_strvis(fw, sid->firmware_rev,
731 sizeof(sid->firmware_rev), sizeof(fw));
732 sprintf(tmpstr, "<%s %s %s %s>", vendor, product, revision, fw);
738 print_dev_mmcsd(struct device_match_result *dev_result, char *tmpstr)
741 struct ccb_dev_advinfo *advi;
742 struct cam_device *dev;
743 struct mmc_params mmc_ident_data;
745 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
746 dev_result->target_lun, O_RDWR, NULL);
748 warnx("%s", cam_errbuf);
752 ccb = cam_getccb(dev);
754 warnx("couldn't allocate CCB");
755 cam_close_device(dev);
760 advi->ccb_h.flags = CAM_DIR_IN;
761 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
762 advi->flags = CDAI_FLAG_NONE;
763 advi->buftype = CDAI_TYPE_MMC_PARAMS;
764 advi->bufsiz = sizeof(struct mmc_params);
765 advi->buf = (uint8_t *)&mmc_ident_data;
767 if (cam_send_ccb(dev, ccb) < 0) {
768 warn("error sending CAMIOCOMMAND ioctl");
770 cam_close_device(dev);
774 if (strlen(mmc_ident_data.model) > 0) {
775 sprintf(tmpstr, "<%s>", mmc_ident_data.model);
777 sprintf(tmpstr, "<%s card>",
778 mmc_ident_data.card_features &
779 CARD_FEATURE_SDIO ? "SDIO" : "unknown");
783 cam_close_device(dev);
789 nvme_get_cdata(struct cam_device *dev, struct nvme_controller_data *cdata)
792 struct ccb_dev_advinfo *advi;
794 ccb = cam_getccb(dev);
796 warnx("couldn't allocate CCB");
797 cam_close_device(dev);
802 advi->ccb_h.flags = CAM_DIR_IN;
803 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
804 advi->flags = CDAI_FLAG_NONE;
805 advi->buftype = CDAI_TYPE_NVME_CNTRL;
806 advi->bufsiz = sizeof(struct nvme_controller_data);
807 advi->buf = (uint8_t *)cdata;
809 if (cam_send_ccb(dev, ccb) < 0) {
810 warn("error sending CAMIOCOMMAND ioctl");
812 cam_close_device(dev);
815 if (advi->ccb_h.status != CAM_REQ_CMP) {
816 warnx("got CAM error %#x", advi->ccb_h.status);
818 cam_close_device(dev);
826 print_dev_nvme(struct device_match_result *dev_result, char *tmpstr)
828 struct cam_device *dev;
829 struct nvme_controller_data cdata;
830 char vendor[64], product[64];
832 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
833 dev_result->target_lun, O_RDWR, NULL);
835 warnx("%s", cam_errbuf);
839 if (nvme_get_cdata(dev, &cdata))
842 cam_strvis(vendor, cdata.mn, sizeof(cdata.mn), sizeof(vendor));
843 cam_strvis(product, cdata.fr, sizeof(cdata.fr), sizeof(product));
844 sprintf(tmpstr, "<%s %s>", vendor, product);
846 cam_close_device(dev);
852 testunitready(struct cam_device *device, int task_attr, int retry_count,
853 int timeout, int quiet)
858 ccb = cam_getccb(device);
860 scsi_test_unit_ready(&ccb->csio,
861 /* retries */ retry_count,
863 /* tag_action */ task_attr,
864 /* sense_len */ SSD_FULL_SIZE,
865 /* timeout */ timeout ? timeout : 5000);
867 /* Disable freezing the device queue */
868 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
870 if (arglist & CAM_ARG_ERR_RECOVER)
871 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
873 if (cam_send_ccb(device, ccb) < 0) {
875 perror("error sending test unit ready");
877 if (arglist & CAM_ARG_VERBOSE) {
878 cam_error_print(device, ccb, CAM_ESF_ALL,
879 CAM_EPF_ALL, stderr);
886 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
888 fprintf(stdout, "Unit is ready\n");
891 fprintf(stdout, "Unit is not ready\n");
894 if (arglist & CAM_ARG_VERBOSE) {
895 cam_error_print(device, ccb, CAM_ESF_ALL,
896 CAM_EPF_ALL, stderr);
906 scsistart(struct cam_device *device, int startstop, int loadeject,
907 int task_attr, int retry_count, int timeout)
912 ccb = cam_getccb(device);
915 * If we're stopping, send an ordered tag so the drive in question
916 * will finish any previously queued writes before stopping. If
917 * the device isn't capable of tagged queueing, or if tagged
918 * queueing is turned off, the tag action is a no-op. We override
919 * the default simple tag, although this also has the effect of
920 * overriding the user's wishes if he wanted to specify a simple
924 && (task_attr == MSG_SIMPLE_Q_TAG))
925 task_attr = MSG_ORDERED_Q_TAG;
927 scsi_start_stop(&ccb->csio,
928 /* retries */ retry_count,
930 /* tag_action */ task_attr,
931 /* start/stop */ startstop,
932 /* load_eject */ loadeject,
934 /* sense_len */ SSD_FULL_SIZE,
935 /* timeout */ timeout ? timeout : 120000);
937 /* Disable freezing the device queue */
938 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
940 if (arglist & CAM_ARG_ERR_RECOVER)
941 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
943 if (cam_send_ccb(device, ccb) < 0) {
944 perror("error sending start unit");
946 if (arglist & CAM_ARG_VERBOSE) {
947 cam_error_print(device, ccb, CAM_ESF_ALL,
948 CAM_EPF_ALL, stderr);
955 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
957 fprintf(stdout, "Unit started successfully");
959 fprintf(stdout,", Media loaded\n");
961 fprintf(stdout,"\n");
963 fprintf(stdout, "Unit stopped successfully");
965 fprintf(stdout, ", Media ejected\n");
967 fprintf(stdout, "\n");
973 "Error received from start unit command\n");
976 "Error received from stop unit command\n");
978 if (arglist & CAM_ARG_VERBOSE) {
979 cam_error_print(device, ccb, CAM_ESF_ALL,
980 CAM_EPF_ALL, stderr);
990 scsidoinquiry(struct cam_device *device, int argc, char **argv,
991 char *combinedopt, int task_attr, int retry_count, int timeout)
996 while ((c = getopt(argc, argv, combinedopt)) != -1) {
999 arglist |= CAM_ARG_GET_STDINQ;
1002 arglist |= CAM_ARG_GET_XFERRATE;
1005 arglist |= CAM_ARG_GET_SERIAL;
1013 * If the user didn't specify any inquiry options, he wants all of
1016 if ((arglist & CAM_ARG_INQ_MASK) == 0)
1017 arglist |= CAM_ARG_INQ_MASK;
1019 if (arglist & CAM_ARG_GET_STDINQ)
1020 error = scsiinquiry(device, task_attr, retry_count, timeout);
1025 if (arglist & CAM_ARG_GET_SERIAL)
1026 scsiserial(device, task_attr, retry_count, timeout);
1028 if (arglist & CAM_ARG_GET_XFERRATE)
1029 error = camxferrate(device);
1035 scsiinquiry(struct cam_device *device, int task_attr, int retry_count,
1039 struct scsi_inquiry_data *inq_buf;
1042 ccb = cam_getccb(device);
1045 warnx("couldn't allocate CCB");
1049 /* cam_getccb cleans up the header, caller has to zero the payload */
1050 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1052 inq_buf = (struct scsi_inquiry_data *)malloc(
1053 sizeof(struct scsi_inquiry_data));
1055 if (inq_buf == NULL) {
1057 warnx("can't malloc memory for inquiry\n");
1060 bzero(inq_buf, sizeof(*inq_buf));
1063 * Note that although the size of the inquiry buffer is the full
1064 * 256 bytes specified in the SCSI spec, we only tell the device
1065 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
1066 * two reasons for this:
1068 * - The SCSI spec says that when a length field is only 1 byte,
1069 * a value of 0 will be interpreted as 256. Therefore
1070 * scsi_inquiry() will convert an inq_len (which is passed in as
1071 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
1072 * to 0. Evidently, very few devices meet the spec in that
1073 * regard. Some devices, like many Seagate disks, take the 0 as
1074 * 0, and don't return any data. One Pioneer DVD-R drive
1075 * returns more data than the command asked for.
1077 * So, since there are numerous devices that just don't work
1078 * right with the full inquiry size, we don't send the full size.
1080 * - The second reason not to use the full inquiry data length is
1081 * that we don't need it here. The only reason we issue a
1082 * standard inquiry is to get the vendor name, device name,
1083 * and revision so scsi_print_inquiry() can print them.
1085 * If, at some point in the future, more inquiry data is needed for
1086 * some reason, this code should use a procedure similar to the
1087 * probe code. i.e., issue a short inquiry, and determine from
1088 * the additional length passed back from the device how much
1089 * inquiry data the device supports. Once the amount the device
1090 * supports is determined, issue an inquiry for that amount and no
1095 scsi_inquiry(&ccb->csio,
1096 /* retries */ retry_count,
1098 /* tag_action */ task_attr,
1099 /* inq_buf */ (u_int8_t *)inq_buf,
1100 /* inq_len */ SHORT_INQUIRY_LENGTH,
1103 /* sense_len */ SSD_FULL_SIZE,
1104 /* timeout */ timeout ? timeout : 5000);
1106 /* Disable freezing the device queue */
1107 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1109 if (arglist & CAM_ARG_ERR_RECOVER)
1110 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1112 if (cam_send_ccb(device, ccb) < 0) {
1113 perror("error sending SCSI inquiry");
1115 if (arglist & CAM_ARG_VERBOSE) {
1116 cam_error_print(device, ccb, CAM_ESF_ALL,
1117 CAM_EPF_ALL, stderr);
1124 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1127 if (arglist & CAM_ARG_VERBOSE) {
1128 cam_error_print(device, ccb, CAM_ESF_ALL,
1129 CAM_EPF_ALL, stderr);
1140 fprintf(stdout, "%s%d: ", device->device_name,
1141 device->dev_unit_num);
1142 scsi_print_inquiry(inq_buf);
1150 scsiserial(struct cam_device *device, int task_attr, int retry_count,
1154 struct scsi_vpd_unit_serial_number *serial_buf;
1155 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
1158 ccb = cam_getccb(device);
1161 warnx("couldn't allocate CCB");
1165 /* cam_getccb cleans up the header, caller has to zero the payload */
1166 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1168 serial_buf = (struct scsi_vpd_unit_serial_number *)
1169 malloc(sizeof(*serial_buf));
1171 if (serial_buf == NULL) {
1173 warnx("can't malloc memory for serial number");
1177 scsi_inquiry(&ccb->csio,
1178 /*retries*/ retry_count,
1180 /* tag_action */ task_attr,
1181 /* inq_buf */ (u_int8_t *)serial_buf,
1182 /* inq_len */ sizeof(*serial_buf),
1184 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
1185 /* sense_len */ SSD_FULL_SIZE,
1186 /* timeout */ timeout ? timeout : 5000);
1188 /* Disable freezing the device queue */
1189 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1191 if (arglist & CAM_ARG_ERR_RECOVER)
1192 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1194 if (cam_send_ccb(device, ccb) < 0) {
1195 warn("error getting serial number");
1197 if (arglist & CAM_ARG_VERBOSE) {
1198 cam_error_print(device, ccb, CAM_ESF_ALL,
1199 CAM_EPF_ALL, stderr);
1207 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1210 if (arglist & CAM_ARG_VERBOSE) {
1211 cam_error_print(device, ccb, CAM_ESF_ALL,
1212 CAM_EPF_ALL, stderr);
1223 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1224 serial_num[serial_buf->length] = '\0';
1226 if ((arglist & CAM_ARG_GET_STDINQ)
1227 || (arglist & CAM_ARG_GET_XFERRATE))
1228 fprintf(stdout, "%s%d: Serial Number ",
1229 device->device_name, device->dev_unit_num);
1231 fprintf(stdout, "%.60s\n", serial_num);
1239 camxferrate(struct cam_device *device)
1241 struct ccb_pathinq cpi;
1243 u_int32_t speed = 0;
1248 if ((retval = get_cpi(device, &cpi)) != 0)
1251 ccb = cam_getccb(device);
1254 warnx("couldn't allocate CCB");
1258 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
1260 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1261 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1263 if (((retval = cam_send_ccb(device, ccb)) < 0)
1264 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1265 const char error_string[] = "error getting transfer settings";
1270 warnx(error_string);
1272 if (arglist & CAM_ARG_VERBOSE)
1273 cam_error_print(device, ccb, CAM_ESF_ALL,
1274 CAM_EPF_ALL, stderr);
1278 goto xferrate_bailout;
1282 speed = cpi.base_transfer_speed;
1284 if (ccb->cts.transport == XPORT_SPI) {
1285 struct ccb_trans_settings_spi *spi =
1286 &ccb->cts.xport_specific.spi;
1288 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1289 freq = scsi_calc_syncsrate(spi->sync_period);
1292 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1293 speed *= (0x01 << spi->bus_width);
1295 } else if (ccb->cts.transport == XPORT_FC) {
1296 struct ccb_trans_settings_fc *fc =
1297 &ccb->cts.xport_specific.fc;
1299 if (fc->valid & CTS_FC_VALID_SPEED)
1300 speed = fc->bitrate;
1301 } else if (ccb->cts.transport == XPORT_SAS) {
1302 struct ccb_trans_settings_sas *sas =
1303 &ccb->cts.xport_specific.sas;
1305 if (sas->valid & CTS_SAS_VALID_SPEED)
1306 speed = sas->bitrate;
1307 } else if (ccb->cts.transport == XPORT_ATA) {
1308 struct ccb_trans_settings_pata *pata =
1309 &ccb->cts.xport_specific.ata;
1311 if (pata->valid & CTS_ATA_VALID_MODE)
1312 speed = ata_mode2speed(pata->mode);
1313 } else if (ccb->cts.transport == XPORT_SATA) {
1314 struct ccb_trans_settings_sata *sata =
1315 &ccb->cts.xport_specific.sata;
1317 if (sata->valid & CTS_SATA_VALID_REVISION)
1318 speed = ata_revision2speed(sata->revision);
1323 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1324 device->device_name, device->dev_unit_num,
1327 fprintf(stdout, "%s%d: %dKB/s transfers",
1328 device->device_name, device->dev_unit_num,
1332 if (ccb->cts.transport == XPORT_SPI) {
1333 struct ccb_trans_settings_spi *spi =
1334 &ccb->cts.xport_specific.spi;
1336 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1337 && (spi->sync_offset != 0))
1338 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1339 freq % 1000, spi->sync_offset);
1341 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1342 && (spi->bus_width > 0)) {
1343 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1344 && (spi->sync_offset != 0)) {
1345 fprintf(stdout, ", ");
1347 fprintf(stdout, " (");
1349 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1350 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1351 && (spi->sync_offset != 0)) {
1352 fprintf(stdout, ")");
1354 } else if (ccb->cts.transport == XPORT_ATA) {
1355 struct ccb_trans_settings_pata *pata =
1356 &ccb->cts.xport_specific.ata;
1359 if (pata->valid & CTS_ATA_VALID_MODE)
1360 printf("%s, ", ata_mode2string(pata->mode));
1361 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1362 printf("ATAPI %dbytes, ", pata->atapi);
1363 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1364 printf("PIO %dbytes", pata->bytecount);
1366 } else if (ccb->cts.transport == XPORT_SATA) {
1367 struct ccb_trans_settings_sata *sata =
1368 &ccb->cts.xport_specific.sata;
1371 if (sata->valid & CTS_SATA_VALID_REVISION)
1372 printf("SATA %d.x, ", sata->revision);
1375 if (sata->valid & CTS_SATA_VALID_MODE)
1376 printf("%s, ", ata_mode2string(sata->mode));
1377 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1378 printf("ATAPI %dbytes, ", sata->atapi);
1379 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1380 printf("PIO %dbytes", sata->bytecount);
1384 if (ccb->cts.protocol == PROTO_SCSI) {
1385 struct ccb_trans_settings_scsi *scsi =
1386 &ccb->cts.proto_specific.scsi;
1387 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1388 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1389 fprintf(stdout, ", Command Queueing Enabled");
1394 fprintf(stdout, "\n");
1404 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1406 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1407 ((u_int32_t)parm->lba_size_2 << 16);
1409 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1410 ((u_int64_t)parm->lba_size48_2 << 16) |
1411 ((u_int64_t)parm->lba_size48_3 << 32) |
1412 ((u_int64_t)parm->lba_size48_4 << 48);
1416 "Support Enabled Value\n");
1419 printf("Host Protected Area (HPA) ");
1420 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1421 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1422 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1425 printf("HPA - Security ");
1426 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1436 atasata(struct ata_params *parm)
1440 if (parm->satacapabilities != 0xffff &&
1441 parm->satacapabilities != 0x0000)
1448 atacapprint(struct ata_params *parm)
1450 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1451 ((u_int32_t)parm->lba_size_2 << 16);
1453 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1454 ((u_int64_t)parm->lba_size48_2 << 16) |
1455 ((u_int64_t)parm->lba_size48_3 << 32) |
1456 ((u_int64_t)parm->lba_size48_4 << 48);
1459 printf("protocol ");
1460 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1461 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1462 if (parm->satacapabilities & ATA_SATA_GEN3)
1463 printf(" SATA 3.x\n");
1464 else if (parm->satacapabilities & ATA_SATA_GEN2)
1465 printf(" SATA 2.x\n");
1466 else if (parm->satacapabilities & ATA_SATA_GEN1)
1467 printf(" SATA 1.x\n");
1473 printf("device model %.40s\n", parm->model);
1474 printf("firmware revision %.8s\n", parm->revision);
1475 printf("serial number %.20s\n", parm->serial);
1476 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1477 printf("WWN %04x%04x%04x%04x\n",
1478 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1480 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1481 printf("media serial number %.30s\n",
1482 parm->media_serial);
1485 printf("cylinders %d\n", parm->cylinders);
1486 printf("heads %d\n", parm->heads);
1487 printf("sectors/track %d\n", parm->sectors);
1488 printf("sector size logical %u, physical %lu, offset %lu\n",
1489 ata_logical_sector_size(parm),
1490 (unsigned long)ata_physical_sector_size(parm),
1491 (unsigned long)ata_logical_sector_offset(parm));
1493 if (parm->config == ATA_PROTO_CFA ||
1494 (parm->support.command2 & ATA_SUPPORT_CFA))
1495 printf("CFA supported\n");
1497 printf("LBA%ssupported ",
1498 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1500 printf("%d sectors\n", lbasize);
1504 printf("LBA48%ssupported ",
1505 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1507 printf("%ju sectors\n", (uintmax_t)lbasize48);
1511 printf("PIO supported PIO");
1512 switch (ata_max_pmode(parm)) {
1528 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1529 printf(" w/o IORDY");
1532 printf("DMA%ssupported ",
1533 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1534 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1535 if (parm->mwdmamodes & 0xff) {
1537 if (parm->mwdmamodes & 0x04)
1539 else if (parm->mwdmamodes & 0x02)
1541 else if (parm->mwdmamodes & 0x01)
1545 if ((parm->atavalid & ATA_FLAG_88) &&
1546 (parm->udmamodes & 0xff)) {
1548 if (parm->udmamodes & 0x40)
1550 else if (parm->udmamodes & 0x20)
1552 else if (parm->udmamodes & 0x10)
1554 else if (parm->udmamodes & 0x08)
1556 else if (parm->udmamodes & 0x04)
1558 else if (parm->udmamodes & 0x02)
1560 else if (parm->udmamodes & 0x01)
1567 if (parm->media_rotation_rate == 1) {
1568 printf("media RPM non-rotating\n");
1569 } else if (parm->media_rotation_rate >= 0x0401 &&
1570 parm->media_rotation_rate <= 0xFFFE) {
1571 printf("media RPM %d\n",
1572 parm->media_rotation_rate);
1575 printf("Zoned-Device Commands ");
1576 switch (parm->support3 & ATA_SUPPORT_ZONE_MASK) {
1577 case ATA_SUPPORT_ZONE_DEV_MANAGED:
1578 printf("device managed\n");
1580 case ATA_SUPPORT_ZONE_HOST_AWARE:
1581 printf("host aware\n");
1588 "Support Enabled Value Vendor\n");
1589 printf("read ahead %s %s\n",
1590 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1591 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1592 printf("write cache %s %s\n",
1593 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1594 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1595 printf("flush cache %s %s\n",
1596 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1597 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1598 printf("overlap %s\n",
1599 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1600 printf("Tagged Command Queuing (TCQ) %s %s",
1601 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1602 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1603 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1604 printf(" %d tags\n",
1605 ATA_QUEUE_LEN(parm->queue) + 1);
1608 printf("Native Command Queuing (NCQ) ");
1609 if (parm->satacapabilities != 0xffff &&
1610 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1611 printf("yes %d tags\n",
1612 ATA_QUEUE_LEN(parm->queue) + 1);
1616 printf("NCQ Queue Management %s\n", atasata(parm) &&
1617 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1619 printf("NCQ Streaming %s\n", atasata(parm) &&
1620 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1622 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1623 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1626 printf("SMART %s %s\n",
1627 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1628 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1629 printf("microcode download %s %s\n",
1630 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1631 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1632 printf("security %s %s\n",
1633 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1634 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1635 printf("power management %s %s\n",
1636 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1637 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1638 printf("advanced power management %s %s",
1639 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1640 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1641 if (parm->support.command2 & ATA_SUPPORT_APM) {
1642 printf(" %d/0x%02X\n",
1643 parm->apm_value & 0xff, parm->apm_value & 0xff);
1646 printf("automatic acoustic management %s %s",
1647 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1648 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1649 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1650 printf(" %d/0x%02X %d/0x%02X\n",
1651 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1652 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1653 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1654 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1657 printf("media status notification %s %s\n",
1658 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1659 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1660 printf("power-up in Standby %s %s\n",
1661 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1662 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1663 printf("write-read-verify %s %s",
1664 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1665 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1666 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1667 printf(" %d/0x%x\n",
1668 parm->wrv_mode, parm->wrv_mode);
1671 printf("unload %s %s\n",
1672 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1673 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1674 printf("general purpose logging %s %s\n",
1675 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1676 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1677 printf("free-fall %s %s\n",
1678 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1679 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1680 printf("Data Set Management (DSM/TRIM) ");
1681 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1683 printf("DSM - max 512byte blocks ");
1684 if (parm->max_dsm_blocks == 0x00)
1685 printf("yes not specified\n");
1688 parm->max_dsm_blocks);
1690 printf("DSM - deterministic read ");
1691 if (parm->support3 & ATA_SUPPORT_DRAT) {
1692 if (parm->support3 & ATA_SUPPORT_RZAT)
1693 printf("yes zeroed\n");
1695 printf("yes any value\n");
1705 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1707 struct ata_pass_16 *ata_pass_16;
1708 struct ata_cmd ata_cmd;
1710 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1711 ata_cmd.command = ata_pass_16->command;
1712 ata_cmd.control = ata_pass_16->control;
1713 ata_cmd.features = ata_pass_16->features;
1715 if (arglist & CAM_ARG_VERBOSE) {
1716 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1717 ata_op_string(&ata_cmd),
1718 ccb->csio.ccb_h.timeout);
1721 /* Disable freezing the device queue */
1722 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1724 if (arglist & CAM_ARG_ERR_RECOVER)
1725 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1727 if (cam_send_ccb(device, ccb) < 0) {
1728 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1729 warn("error sending ATA %s via pass_16",
1730 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);
1741 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1742 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1743 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1744 warnx("ATA %s via pass_16 failed",
1745 ata_op_string(&ata_cmd));
1747 if (arglist & CAM_ARG_VERBOSE) {
1748 cam_error_print(device, ccb, CAM_ESF_ALL,
1749 CAM_EPF_ALL, stderr);
1760 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1762 if (arglist & CAM_ARG_VERBOSE) {
1763 warnx("sending ATA %s with timeout of %u msecs",
1764 ata_op_string(&(ccb->ataio.cmd)),
1765 ccb->ataio.ccb_h.timeout);
1768 /* Disable freezing the device queue */
1769 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1771 if (arglist & CAM_ARG_ERR_RECOVER)
1772 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1774 if (cam_send_ccb(device, ccb) < 0) {
1775 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1776 warn("error sending ATA %s",
1777 ata_op_string(&(ccb->ataio.cmd)));
1780 if (arglist & CAM_ARG_VERBOSE) {
1781 cam_error_print(device, ccb, CAM_ESF_ALL,
1782 CAM_EPF_ALL, stderr);
1788 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1789 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1790 warnx("ATA %s failed: %d",
1791 ata_op_string(&(ccb->ataio.cmd)), quiet);
1794 if (arglist & CAM_ARG_VERBOSE) {
1795 cam_error_print(device, ccb, CAM_ESF_ALL,
1796 CAM_EPF_ALL, stderr);
1806 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1807 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1808 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1809 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1810 u_int16_t dxfer_len, int timeout, int quiet)
1812 if (data_ptr != NULL) {
1813 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1814 AP_FLAG_TLEN_SECT_CNT;
1815 if (flags & CAM_DIR_OUT)
1816 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1818 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1820 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1823 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1825 scsi_ata_pass_16(&ccb->csio,
1839 /*sense_len*/SSD_FULL_SIZE,
1842 return scsi_cam_pass_16_send(device, ccb, quiet);
1846 ata_try_pass_16(struct cam_device *device)
1848 struct ccb_pathinq cpi;
1850 if (get_cpi(device, &cpi) != 0) {
1851 warnx("couldn't get CPI");
1855 if (cpi.protocol == PROTO_SCSI) {
1856 /* possibly compatible with pass_16 */
1860 /* likely not compatible with pass_16 */
1865 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1866 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1867 u_int8_t command, u_int8_t features, u_int32_t lba,
1868 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1869 int timeout, int quiet)
1873 switch (ata_try_pass_16(device)) {
1877 /* Try using SCSI Passthrough */
1878 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1879 0, tag_action, command, features, lba,
1880 sector_count, data_ptr, dxfer_len,
1884 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1885 cam_fill_ataio(&ccb->ataio,
1894 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1895 return ata_cam_send(device, ccb, quiet);
1899 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1900 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1901 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1902 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1903 u_int16_t dxfer_len, int timeout, int force48bit)
1907 retval = ata_try_pass_16(device);
1914 /* Try using SCSI Passthrough */
1915 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1916 ata_flags, tag_action, command, features,
1917 lba, sector_count, data_ptr, dxfer_len,
1920 if (ata_flags & AP_FLAG_CHK_COND) {
1921 /* Decode ata_res from sense data */
1922 struct ata_res_pass16 *res_pass16;
1923 struct ata_res *res;
1927 /* sense_data is 4 byte aligned */
1928 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1929 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1930 ptr[i] = le16toh(ptr[i]);
1932 /* sense_data is 4 byte aligned */
1933 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1934 &ccb->csio.sense_data;
1935 res = &ccb->ataio.res;
1936 res->flags = res_pass16->flags;
1937 res->status = res_pass16->status;
1938 res->error = res_pass16->error;
1939 res->lba_low = res_pass16->lba_low;
1940 res->lba_mid = res_pass16->lba_mid;
1941 res->lba_high = res_pass16->lba_high;
1942 res->device = res_pass16->device;
1943 res->lba_low_exp = res_pass16->lba_low_exp;
1944 res->lba_mid_exp = res_pass16->lba_mid_exp;
1945 res->lba_high_exp = res_pass16->lba_high_exp;
1946 res->sector_count = res_pass16->sector_count;
1947 res->sector_count_exp = res_pass16->sector_count_exp;
1953 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1954 cam_fill_ataio(&ccb->ataio,
1963 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1964 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1966 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1968 if (ata_flags & AP_FLAG_CHK_COND)
1969 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1971 return ata_cam_send(device, ccb, 0);
1975 dump_data(uint16_t *ptr, uint32_t len)
1979 for (i = 0; i < len / 2; i++) {
1981 printf(" %3d: ", i);
1982 printf("%04hx ", ptr[i]);
1991 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1992 int is48bit, u_int64_t *hpasize)
1994 struct ata_res *res;
1996 res = &ccb->ataio.res;
1997 if (res->status & ATA_STATUS_ERROR) {
1998 if (arglist & CAM_ARG_VERBOSE) {
1999 cam_error_print(device, ccb, CAM_ESF_ALL,
2000 CAM_EPF_ALL, stderr);
2001 printf("error = 0x%02x, sector_count = 0x%04x, "
2002 "device = 0x%02x, status = 0x%02x\n",
2003 res->error, res->sector_count,
2004 res->device, res->status);
2007 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
2008 warnx("Max address has already been set since "
2009 "last power-on or hardware reset");
2015 if (arglist & CAM_ARG_VERBOSE) {
2016 fprintf(stdout, "%s%d: Raw native max data:\n",
2017 device->device_name, device->dev_unit_num);
2018 /* res is 4 byte aligned */
2019 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
2021 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
2022 "status = 0x%02x\n", res->error, res->sector_count,
2023 res->device, res->status);
2026 if (hpasize != NULL) {
2028 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
2029 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
2030 ((res->lba_high << 16) | (res->lba_mid << 8) |
2033 *hpasize = (((res->device & 0x0f) << 24) |
2034 (res->lba_high << 16) | (res->lba_mid << 8) |
2043 ata_read_native_max(struct cam_device *device, int retry_count,
2044 u_int32_t timeout, union ccb *ccb,
2045 struct ata_params *parm, u_int64_t *hpasize)
2051 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
2052 protocol = AP_PROTO_NON_DATA;
2055 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
2056 protocol |= AP_EXTEND;
2058 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
2061 error = ata_do_cmd(device,
2064 /*flags*/CAM_DIR_NONE,
2065 /*protocol*/protocol,
2066 /*ata_flags*/AP_FLAG_CHK_COND,
2067 /*tag_action*/MSG_SIMPLE_Q_TAG,
2074 timeout ? timeout : 5000,
2080 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
2084 atahpa_set_max(struct cam_device *device, int retry_count,
2085 u_int32_t timeout, union ccb *ccb,
2086 int is48bit, u_int64_t maxsize, int persist)
2092 protocol = AP_PROTO_NON_DATA;
2095 cmd = ATA_SET_MAX_ADDRESS48;
2096 protocol |= AP_EXTEND;
2098 cmd = ATA_SET_MAX_ADDRESS;
2101 /* lba's are zero indexed so the max lba is requested max - 1 */
2105 error = ata_do_cmd(device,
2108 /*flags*/CAM_DIR_NONE,
2109 /*protocol*/protocol,
2110 /*ata_flags*/AP_FLAG_CHK_COND,
2111 /*tag_action*/MSG_SIMPLE_Q_TAG,
2113 /*features*/ATA_HPA_FEAT_MAX_ADDR,
2115 /*sector_count*/persist,
2118 timeout ? timeout : 1000,
2124 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2128 atahpa_password(struct cam_device *device, int retry_count,
2129 u_int32_t timeout, union ccb *ccb,
2130 int is48bit, struct ata_set_max_pwd *pwd)
2136 protocol = AP_PROTO_PIO_OUT;
2137 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2139 error = ata_do_cmd(device,
2142 /*flags*/CAM_DIR_OUT,
2143 /*protocol*/protocol,
2144 /*ata_flags*/AP_FLAG_CHK_COND,
2145 /*tag_action*/MSG_SIMPLE_Q_TAG,
2147 /*features*/ATA_HPA_FEAT_SET_PWD,
2150 /*data_ptr*/(u_int8_t*)pwd,
2151 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2152 timeout ? timeout : 1000,
2158 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2162 atahpa_lock(struct cam_device *device, int retry_count,
2163 u_int32_t timeout, union ccb *ccb, int is48bit)
2169 protocol = AP_PROTO_NON_DATA;
2170 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2172 error = ata_do_cmd(device,
2175 /*flags*/CAM_DIR_NONE,
2176 /*protocol*/protocol,
2177 /*ata_flags*/AP_FLAG_CHK_COND,
2178 /*tag_action*/MSG_SIMPLE_Q_TAG,
2180 /*features*/ATA_HPA_FEAT_LOCK,
2185 timeout ? timeout : 1000,
2191 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2195 atahpa_unlock(struct cam_device *device, int retry_count,
2196 u_int32_t timeout, union ccb *ccb,
2197 int is48bit, struct ata_set_max_pwd *pwd)
2203 protocol = AP_PROTO_PIO_OUT;
2204 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2206 error = ata_do_cmd(device,
2209 /*flags*/CAM_DIR_OUT,
2210 /*protocol*/protocol,
2211 /*ata_flags*/AP_FLAG_CHK_COND,
2212 /*tag_action*/MSG_SIMPLE_Q_TAG,
2214 /*features*/ATA_HPA_FEAT_UNLOCK,
2217 /*data_ptr*/(u_int8_t*)pwd,
2218 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2219 timeout ? timeout : 1000,
2225 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2229 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2230 u_int32_t timeout, union ccb *ccb, int is48bit)
2236 protocol = AP_PROTO_NON_DATA;
2237 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2239 error = ata_do_cmd(device,
2242 /*flags*/CAM_DIR_NONE,
2243 /*protocol*/protocol,
2244 /*ata_flags*/AP_FLAG_CHK_COND,
2245 /*tag_action*/MSG_SIMPLE_Q_TAG,
2247 /*features*/ATA_HPA_FEAT_FREEZE,
2252 timeout ? timeout : 1000,
2258 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2263 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2264 union ccb *ccb, struct ata_params** ident_bufp)
2266 struct ata_params *ident_buf;
2267 struct ccb_pathinq cpi;
2268 struct ccb_getdev cgd;
2271 u_int8_t command, retry_command;
2273 if (get_cpi(device, &cpi) != 0) {
2274 warnx("couldn't get CPI");
2278 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2279 if (cpi.protocol == PROTO_ATA) {
2280 if (get_cgd(device, &cgd) != 0) {
2281 warnx("couldn't get CGD");
2285 command = (cgd.protocol == PROTO_ATA) ?
2286 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2289 /* We don't know which for sure so try both */
2290 command = ATA_ATA_IDENTIFY;
2291 retry_command = ATA_ATAPI_IDENTIFY;
2294 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2296 warnx("can't calloc memory for identify\n");
2300 error = ata_do_28bit_cmd(device,
2302 /*retries*/retry_count,
2303 /*flags*/CAM_DIR_IN,
2304 /*protocol*/AP_PROTO_PIO_IN,
2305 /*tag_action*/MSG_SIMPLE_Q_TAG,
2310 /*data_ptr*/(u_int8_t *)ptr,
2311 /*dxfer_len*/sizeof(struct ata_params),
2312 /*timeout*/timeout ? timeout : 30 * 1000,
2316 if (retry_command == 0) {
2320 error = ata_do_28bit_cmd(device,
2322 /*retries*/retry_count,
2323 /*flags*/CAM_DIR_IN,
2324 /*protocol*/AP_PROTO_PIO_IN,
2325 /*tag_action*/MSG_SIMPLE_Q_TAG,
2326 /*command*/retry_command,
2330 /*data_ptr*/(u_int8_t *)ptr,
2331 /*dxfer_len*/sizeof(struct ata_params),
2332 /*timeout*/timeout ? timeout : 30 * 1000,
2341 ident_buf = (struct ata_params *)ptr;
2342 ata_param_fixup(ident_buf);
2345 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2350 if (arglist & CAM_ARG_VERBOSE) {
2351 fprintf(stdout, "%s%d: Raw identify data:\n",
2352 device->device_name, device->dev_unit_num);
2353 dump_data(ptr, sizeof(struct ata_params));
2356 /* check for invalid (all zero) response */
2358 warnx("Invalid identify response detected");
2363 *ident_bufp = ident_buf;
2370 ataidentify(struct cam_device *device, int retry_count, int timeout)
2373 struct ata_params *ident_buf;
2376 if ((ccb = cam_getccb(device)) == NULL) {
2377 warnx("couldn't allocate CCB");
2381 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2386 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2387 if (ata_read_native_max(device, retry_count, timeout, ccb,
2388 ident_buf, &hpasize) != 0) {
2396 printf("%s%d: ", device->device_name, device->dev_unit_num);
2397 ata_print_ident(ident_buf);
2398 camxferrate(device);
2399 atacapprint(ident_buf);
2400 atahpa_print(ident_buf, hpasize, 0);
2410 nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused)
2412 struct nvme_controller_data cdata;
2414 if (nvme_get_cdata(device, &cdata))
2416 nvme_print_controller(&cdata);
2423 identify(struct cam_device *device, int retry_count, int timeout)
2426 struct ccb_pathinq cpi;
2428 if (get_cpi(device, &cpi) != 0) {
2429 warnx("couldn't get CPI");
2433 if (cpi.protocol == PROTO_NVME) {
2434 return (nvmeidentify(device, retry_count, timeout));
2437 return (ataidentify(device, retry_count, timeout));
2442 ATA_SECURITY_ACTION_PRINT,
2443 ATA_SECURITY_ACTION_FREEZE,
2444 ATA_SECURITY_ACTION_UNLOCK,
2445 ATA_SECURITY_ACTION_DISABLE,
2446 ATA_SECURITY_ACTION_ERASE,
2447 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2448 ATA_SECURITY_ACTION_SET_PASSWORD
2452 atasecurity_print_time(u_int16_t tw)
2456 printf("unspecified");
2458 printf("> 508 min");
2460 printf("%i min", 2 * tw);
2464 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2468 return 2 * 3600 * 1000; /* default: two hours */
2469 else if (timeout > 255)
2470 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2472 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2477 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2481 bzero(&cmd, sizeof(cmd));
2482 cmd.command = command;
2483 printf("Issuing %s", ata_op_string(&cmd));
2486 char pass[sizeof(pwd->password)+1];
2488 /* pwd->password may not be null terminated */
2489 pass[sizeof(pwd->password)] = '\0';
2490 strncpy(pass, pwd->password, sizeof(pwd->password));
2491 printf(" password='%s', user='%s'",
2493 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2496 if (command == ATA_SECURITY_SET_PASSWORD) {
2497 printf(", mode='%s'",
2498 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2499 "maximum" : "high");
2507 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2508 int retry_count, u_int32_t timeout, int quiet)
2512 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2514 return ata_do_28bit_cmd(device,
2517 /*flags*/CAM_DIR_NONE,
2518 /*protocol*/AP_PROTO_NON_DATA,
2519 /*tag_action*/MSG_SIMPLE_Q_TAG,
2520 /*command*/ATA_SECURITY_FREEZE_LOCK,
2531 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2532 int retry_count, u_int32_t timeout,
2533 struct ata_security_password *pwd, int quiet)
2537 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2539 return ata_do_28bit_cmd(device,
2542 /*flags*/CAM_DIR_OUT,
2543 /*protocol*/AP_PROTO_PIO_OUT,
2544 /*tag_action*/MSG_SIMPLE_Q_TAG,
2545 /*command*/ATA_SECURITY_UNLOCK,
2549 /*data_ptr*/(u_int8_t *)pwd,
2550 /*dxfer_len*/sizeof(*pwd),
2556 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2557 int retry_count, u_int32_t timeout,
2558 struct ata_security_password *pwd, int quiet)
2562 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2563 return ata_do_28bit_cmd(device,
2566 /*flags*/CAM_DIR_OUT,
2567 /*protocol*/AP_PROTO_PIO_OUT,
2568 /*tag_action*/MSG_SIMPLE_Q_TAG,
2569 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2573 /*data_ptr*/(u_int8_t *)pwd,
2574 /*dxfer_len*/sizeof(*pwd),
2581 atasecurity_erase_confirm(struct cam_device *device,
2582 struct ata_params* ident_buf)
2585 printf("\nYou are about to ERASE ALL DATA from the following"
2586 " device:\n%s%d,%s%d: ", device->device_name,
2587 device->dev_unit_num, device->given_dev_name,
2588 device->given_unit_number);
2589 ata_print_ident(ident_buf);
2593 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2595 if (fgets(str, sizeof(str), stdin) != NULL) {
2596 if (strncasecmp(str, "yes", 3) == 0) {
2598 } else if (strncasecmp(str, "no", 2) == 0) {
2601 printf("Please answer \"yes\" or "
2612 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2613 int retry_count, u_int32_t timeout,
2614 u_int32_t erase_timeout,
2615 struct ata_security_password *pwd, int quiet)
2620 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2622 error = ata_do_28bit_cmd(device,
2625 /*flags*/CAM_DIR_NONE,
2626 /*protocol*/AP_PROTO_NON_DATA,
2627 /*tag_action*/MSG_SIMPLE_Q_TAG,
2628 /*command*/ATA_SECURITY_ERASE_PREPARE,
2641 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2643 error = ata_do_28bit_cmd(device,
2646 /*flags*/CAM_DIR_OUT,
2647 /*protocol*/AP_PROTO_PIO_OUT,
2648 /*tag_action*/MSG_SIMPLE_Q_TAG,
2649 /*command*/ATA_SECURITY_ERASE_UNIT,
2653 /*data_ptr*/(u_int8_t *)pwd,
2654 /*dxfer_len*/sizeof(*pwd),
2655 /*timeout*/erase_timeout,
2658 if (error == 0 && quiet == 0)
2659 printf("\nErase Complete\n");
2665 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2666 int retry_count, u_int32_t timeout,
2667 struct ata_security_password *pwd, int quiet)
2671 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2673 return ata_do_28bit_cmd(device,
2676 /*flags*/CAM_DIR_OUT,
2677 /*protocol*/AP_PROTO_PIO_OUT,
2678 /*tag_action*/MSG_SIMPLE_Q_TAG,
2679 /*command*/ATA_SECURITY_SET_PASSWORD,
2683 /*data_ptr*/(u_int8_t *)pwd,
2684 /*dxfer_len*/sizeof(*pwd),
2690 atasecurity_print(struct ata_params *parm)
2693 printf("\nSecurity Option Value\n");
2694 if (arglist & CAM_ARG_VERBOSE) {
2695 printf("status %04x\n",
2696 parm->security_status);
2698 printf("supported %s\n",
2699 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2700 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2702 printf("enabled %s\n",
2703 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2704 printf("drive locked %s\n",
2705 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2706 printf("security config frozen %s\n",
2707 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2708 printf("count expired %s\n",
2709 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2710 printf("security level %s\n",
2711 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2712 printf("enhanced erase supported %s\n",
2713 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2714 printf("erase time ");
2715 atasecurity_print_time(parm->erase_time);
2717 printf("enhanced erase time ");
2718 atasecurity_print_time(parm->enhanced_erase_time);
2720 printf("master password rev %04x%s\n",
2721 parm->master_passwd_revision,
2722 parm->master_passwd_revision == 0x0000 ||
2723 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2727 * Validates and copies the password in optarg to the passed buffer.
2728 * If the password in optarg is the same length as the buffer then
2729 * the data will still be copied but no null termination will occur.
2732 ata_getpwd(u_int8_t *passwd, int max, char opt)
2736 len = strlen(optarg);
2738 warnx("-%c password is too long", opt);
2740 } else if (len == 0) {
2741 warnx("-%c password is missing", opt);
2743 } else if (optarg[0] == '-'){
2744 warnx("-%c password starts with '-' (generic arg?)", opt);
2746 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2747 warnx("-%c password conflicts with existing password from -%c",
2752 /* Callers pass in a buffer which does NOT need to be terminated */
2753 strncpy(passwd, optarg, max);
2760 ATA_HPA_ACTION_PRINT,
2761 ATA_HPA_ACTION_SET_MAX,
2762 ATA_HPA_ACTION_SET_PWD,
2763 ATA_HPA_ACTION_LOCK,
2764 ATA_HPA_ACTION_UNLOCK,
2765 ATA_HPA_ACTION_FREEZE_LOCK
2769 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2770 u_int64_t maxsize, int persist)
2772 printf("\nYou are about to configure HPA to limit the user accessible\n"
2773 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2774 persist ? "persistently" : "temporarily",
2775 device->device_name, device->dev_unit_num,
2776 device->given_dev_name, device->given_unit_number);
2777 ata_print_ident(ident_buf);
2781 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2783 if (NULL != fgets(str, sizeof(str), stdin)) {
2784 if (0 == strncasecmp(str, "yes", 3)) {
2786 } else if (0 == strncasecmp(str, "no", 2)) {
2789 printf("Please answer \"yes\" or "
2800 atahpa(struct cam_device *device, int retry_count, int timeout,
2801 int argc, char **argv, char *combinedopt)
2804 struct ata_params *ident_buf;
2805 struct ccb_getdev cgd;
2806 struct ata_set_max_pwd pwd;
2807 int error, confirm, quiet, c, action, actions, persist;
2808 int security, is48bit, pwdsize;
2809 u_int64_t hpasize, maxsize;
2818 memset(&pwd, 0, sizeof(pwd));
2820 /* default action is to print hpa information */
2821 action = ATA_HPA_ACTION_PRINT;
2822 pwdsize = sizeof(pwd.password);
2824 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2827 action = ATA_HPA_ACTION_SET_MAX;
2828 maxsize = strtoumax(optarg, NULL, 0);
2833 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2835 action = ATA_HPA_ACTION_SET_PWD;
2841 action = ATA_HPA_ACTION_LOCK;
2847 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2849 action = ATA_HPA_ACTION_UNLOCK;
2855 action = ATA_HPA_ACTION_FREEZE_LOCK;
2875 warnx("too many hpa actions specified");
2879 if (get_cgd(device, &cgd) != 0) {
2880 warnx("couldn't get CGD");
2884 ccb = cam_getccb(device);
2886 warnx("couldn't allocate CCB");
2890 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2897 printf("%s%d: ", device->device_name, device->dev_unit_num);
2898 ata_print_ident(ident_buf);
2899 camxferrate(device);
2902 if (action == ATA_HPA_ACTION_PRINT) {
2903 error = ata_read_native_max(device, retry_count, timeout, ccb,
2904 ident_buf, &hpasize);
2906 atahpa_print(ident_buf, hpasize, 1);
2913 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2914 warnx("HPA is not supported by this device");
2920 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2921 warnx("HPA Security is not supported by this device");
2927 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2930 * The ATA spec requires:
2931 * 1. Read native max addr is called directly before set max addr
2932 * 2. Read native max addr is NOT called before any other set max call
2935 case ATA_HPA_ACTION_SET_MAX:
2937 atahpa_set_confirm(device, ident_buf, maxsize,
2944 error = ata_read_native_max(device, retry_count, timeout,
2945 ccb, ident_buf, &hpasize);
2947 error = atahpa_set_max(device, retry_count, timeout,
2948 ccb, is48bit, maxsize, persist);
2950 /* redo identify to get new lba values */
2951 error = ata_do_identify(device, retry_count,
2954 atahpa_print(ident_buf, hpasize, 1);
2959 case ATA_HPA_ACTION_SET_PWD:
2960 error = atahpa_password(device, retry_count, timeout,
2961 ccb, is48bit, &pwd);
2963 printf("HPA password has been set\n");
2966 case ATA_HPA_ACTION_LOCK:
2967 error = atahpa_lock(device, retry_count, timeout,
2970 printf("HPA has been locked\n");
2973 case ATA_HPA_ACTION_UNLOCK:
2974 error = atahpa_unlock(device, retry_count, timeout,
2975 ccb, is48bit, &pwd);
2977 printf("HPA has been unlocked\n");
2980 case ATA_HPA_ACTION_FREEZE_LOCK:
2981 error = atahpa_freeze_lock(device, retry_count, timeout,
2984 printf("HPA has been frozen\n");
2988 errx(1, "Option currently not supported");
2998 atasecurity(struct cam_device *device, int retry_count, int timeout,
2999 int argc, char **argv, char *combinedopt)
3002 struct ata_params *ident_buf;
3003 int error, confirm, quiet, c, action, actions, setpwd;
3004 int security_enabled, erase_timeout, pwdsize;
3005 struct ata_security_password pwd;
3013 memset(&pwd, 0, sizeof(pwd));
3015 /* default action is to print security information */
3016 action = ATA_SECURITY_ACTION_PRINT;
3018 /* user is master by default as its safer that way */
3019 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3020 pwdsize = sizeof(pwd.password);
3022 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3025 action = ATA_SECURITY_ACTION_FREEZE;
3030 if (strcasecmp(optarg, "user") == 0) {
3031 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
3032 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
3033 } else if (strcasecmp(optarg, "master") == 0) {
3034 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3035 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
3037 warnx("-U argument '%s' is invalid (must be "
3038 "'user' or 'master')", optarg);
3044 if (strcasecmp(optarg, "high") == 0) {
3045 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3046 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3047 } else if (strcasecmp(optarg, "maximum") == 0) {
3048 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3049 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3051 warnx("-l argument '%s' is unknown (must be "
3052 "'high' or 'maximum')", optarg);
3058 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3060 action = ATA_SECURITY_ACTION_UNLOCK;
3065 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3067 action = ATA_SECURITY_ACTION_DISABLE;
3072 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3074 action = ATA_SECURITY_ACTION_ERASE;
3079 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3081 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3082 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3087 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3090 if (action == ATA_SECURITY_ACTION_PRINT)
3091 action = ATA_SECURITY_ACTION_SET_PASSWORD;
3093 * Don't increment action as this can be combined
3094 * with other actions.
3107 erase_timeout = atoi(optarg) * 1000;
3113 warnx("too many security actions specified");
3117 if ((ccb = cam_getccb(device)) == NULL) {
3118 warnx("couldn't allocate CCB");
3122 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3129 printf("%s%d: ", device->device_name, device->dev_unit_num);
3130 ata_print_ident(ident_buf);
3131 camxferrate(device);
3134 if (action == ATA_SECURITY_ACTION_PRINT) {
3135 atasecurity_print(ident_buf);
3141 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3142 warnx("Security not supported");
3148 /* default timeout 15 seconds the same as linux hdparm */
3149 timeout = timeout ? timeout : 15 * 1000;
3151 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3153 /* first set the password if requested */
3155 /* confirm we can erase before setting the password if erasing */
3157 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3158 action == ATA_SECURITY_ACTION_ERASE) &&
3159 atasecurity_erase_confirm(device, ident_buf) == 0) {
3165 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3166 pwd.revision = ident_buf->master_passwd_revision;
3167 if (pwd.revision != 0 && pwd.revision != 0xfff &&
3168 --pwd.revision == 0) {
3169 pwd.revision = 0xfffe;
3172 error = atasecurity_set_password(device, ccb, retry_count,
3173 timeout, &pwd, quiet);
3179 security_enabled = 1;
3183 case ATA_SECURITY_ACTION_FREEZE:
3184 error = atasecurity_freeze(device, ccb, retry_count,
3188 case ATA_SECURITY_ACTION_UNLOCK:
3189 if (security_enabled) {
3190 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3191 error = atasecurity_unlock(device, ccb,
3192 retry_count, timeout, &pwd, quiet);
3194 warnx("Can't unlock, drive is not locked");
3198 warnx("Can't unlock, security is disabled");
3203 case ATA_SECURITY_ACTION_DISABLE:
3204 if (security_enabled) {
3205 /* First unlock the drive if its locked */
3206 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3207 error = atasecurity_unlock(device, ccb,
3215 error = atasecurity_disable(device,
3223 warnx("Can't disable security (already disabled)");
3228 case ATA_SECURITY_ACTION_ERASE:
3229 if (security_enabled) {
3230 if (erase_timeout == 0) {
3231 erase_timeout = atasecurity_erase_timeout_msecs(
3232 ident_buf->erase_time);
3235 error = atasecurity_erase(device, ccb, retry_count,
3236 timeout, erase_timeout, &pwd, quiet);
3238 warnx("Can't secure erase (security is disabled)");
3243 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3244 if (security_enabled) {
3245 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3246 if (erase_timeout == 0) {
3248 atasecurity_erase_timeout_msecs(
3249 ident_buf->enhanced_erase_time);
3252 error = atasecurity_erase(device, ccb,
3253 retry_count, timeout,
3254 erase_timeout, &pwd,
3257 warnx("Enhanced erase is not supported");
3261 warnx("Can't secure erase (enhanced), "
3262 "(security is disabled)");
3275 * Parse out a bus, or a bus, target and lun in the following
3281 * Returns the number of parsed components, or 0.
3284 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3285 cam_argmask *arglst)
3290 while (isspace(*tstr) && (*tstr != '\0'))
3293 tmpstr = (char *)strtok(tstr, ":");
3294 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3295 *bus = strtol(tmpstr, NULL, 0);
3296 *arglst |= CAM_ARG_BUS;
3298 tmpstr = (char *)strtok(NULL, ":");
3299 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3300 *target = strtol(tmpstr, NULL, 0);
3301 *arglst |= CAM_ARG_TARGET;
3303 tmpstr = (char *)strtok(NULL, ":");
3304 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3305 *lun = strtol(tmpstr, NULL, 0);
3306 *arglst |= CAM_ARG_LUN;
3316 dorescan_or_reset(int argc, char **argv, int rescan)
3318 static const char must[] =
3319 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3321 path_id_t bus = CAM_BUS_WILDCARD;
3322 target_id_t target = CAM_TARGET_WILDCARD;
3323 lun_id_t lun = CAM_LUN_WILDCARD;
3327 warnx(must, rescan? "rescan" : "reset");
3331 tstr = argv[optind];
3332 while (isspace(*tstr) && (*tstr != '\0'))
3334 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3335 arglist |= CAM_ARG_BUS;
3336 else if (isdigit(*tstr)) {
3337 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3338 if (rv != 1 && rv != 3) {
3339 warnx(must, rescan? "rescan" : "reset");
3349 * Note that resetting or rescanning a device used to
3350 * require a bus or bus:target:lun. This is because the
3351 * device in question may not exist and you're trying to
3352 * get the controller to rescan to find it. It may also be
3353 * because the device is hung / unresponsive, and opening
3354 * an unresponsive device is not desireable.
3356 * It can be more convenient to reference a device by
3357 * peripheral name and unit number, though, and it is
3358 * possible to get the bus:target:lun for devices that
3359 * currently exist in the EDT. So this can work for
3360 * devices that we want to reset, or devices that exist
3361 * that we want to rescan, but not devices that do not
3364 * So, we are careful here to look up the bus/target/lun
3365 * for the device the user wants to operate on, specified
3366 * by peripheral instance (e.g. da0, pass32) without
3367 * actually opening that device. The process is similar to
3368 * what cam_lookup_pass() does, except that we don't
3369 * actually open the passthrough driver instance in the end.
3372 if (cam_get_device(tstr, name, sizeof(name), &unit) == -1) {
3373 warnx("%s", cam_errbuf);
3378 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3379 warn("Unable to open %s", XPT_DEVICE);
3384 bzero(&ccb, sizeof(ccb));
3387 * The function code isn't strictly necessary for the
3388 * GETPASSTHRU ioctl.
3390 ccb.ccb_h.func_code = XPT_GDEVLIST;
3393 * These two are necessary for the GETPASSTHRU ioctl to
3396 strlcpy(ccb.cgdl.periph_name, name,
3397 sizeof(ccb.cgdl.periph_name));
3398 ccb.cgdl.unit_number = unit;
3401 * Attempt to get the passthrough device. This ioctl will
3402 * fail if the device name is null, if the device doesn't
3403 * exist, or if the passthrough driver isn't in the kernel.
3405 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3406 warn("Unable to find bus:target:lun for device %s%d",
3412 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3413 const struct cam_status_entry *entry;
3415 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3416 warnx("Unable to find bus:target_lun for device %s%d, "
3417 "CAM status: %s (%#x)", name, unit,
3418 entry ? entry->status_text : "Unknown",
3426 * The kernel fills in the bus/target/lun. We don't
3427 * need the passthrough device name and unit number since
3428 * we aren't going to open it.
3430 bus = ccb.ccb_h.path_id;
3431 target = ccb.ccb_h.target_id;
3432 lun = ccb.ccb_h.target_lun;
3434 arglist |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3439 if ((arglist & CAM_ARG_BUS)
3440 && (arglist & CAM_ARG_TARGET)
3441 && (arglist & CAM_ARG_LUN))
3442 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3444 error = rescan_or_reset_bus(bus, rescan);
3452 rescan_or_reset_bus(path_id_t bus, int rescan)
3454 union ccb *ccb = NULL, *matchccb = NULL;
3455 int fd = -1, retval;
3460 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3461 warnx("error opening transport layer device %s", XPT_DEVICE);
3462 warn("%s", XPT_DEVICE);
3466 ccb = malloc(sizeof(*ccb));
3468 warn("failed to allocate CCB");
3472 bzero(ccb, sizeof(*ccb));
3474 if (bus != CAM_BUS_WILDCARD) {
3475 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3476 ccb->ccb_h.path_id = bus;
3477 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3478 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3479 ccb->crcn.flags = CAM_FLAG_NONE;
3481 /* run this at a low priority */
3482 ccb->ccb_h.pinfo.priority = 5;
3484 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3485 warn("CAMIOCOMMAND ioctl failed");
3490 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3491 fprintf(stdout, "%s of bus %d was successful\n",
3492 rescan ? "Re-scan" : "Reset", bus);
3494 fprintf(stdout, "%s of bus %d returned error %#x\n",
3495 rescan ? "Re-scan" : "Reset", bus,
3496 ccb->ccb_h.status & CAM_STATUS_MASK);
3505 * The right way to handle this is to modify the xpt so that it can
3506 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3507 * that isn't implemented, so instead we enumerate the buses and
3508 * send the rescan or reset to those buses in the case where the
3509 * given bus is -1 (wildcard). We don't send a rescan or reset
3510 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3511 * no-op, sending a rescan to the xpt bus would result in a status of
3514 matchccb = malloc(sizeof(*matchccb));
3515 if (matchccb == NULL) {
3516 warn("failed to allocate CCB");
3520 bzero(matchccb, sizeof(*matchccb));
3521 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3522 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3523 bufsize = sizeof(struct dev_match_result) * 20;
3524 matchccb->cdm.match_buf_len = bufsize;
3525 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3526 if (matchccb->cdm.matches == NULL) {
3527 warnx("can't malloc memory for matches");
3531 matchccb->cdm.num_matches = 0;
3533 matchccb->cdm.num_patterns = 1;
3534 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3536 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3537 matchccb->cdm.pattern_buf_len);
3538 if (matchccb->cdm.patterns == NULL) {
3539 warnx("can't malloc memory for patterns");
3543 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3544 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3549 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3550 warn("CAMIOCOMMAND ioctl failed");
3555 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3556 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3557 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3558 warnx("got CAM error %#x, CDM error %d\n",
3559 matchccb->ccb_h.status, matchccb->cdm.status);
3564 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3565 struct bus_match_result *bus_result;
3567 /* This shouldn't happen. */
3568 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3571 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3574 * We don't want to rescan or reset the xpt bus.
3577 if (bus_result->path_id == CAM_XPT_PATH_ID)
3580 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3582 ccb->ccb_h.path_id = bus_result->path_id;
3583 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3584 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3585 ccb->crcn.flags = CAM_FLAG_NONE;
3587 /* run this at a low priority */
3588 ccb->ccb_h.pinfo.priority = 5;
3590 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3591 warn("CAMIOCOMMAND ioctl failed");
3596 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3597 fprintf(stdout, "%s of bus %d was successful\n",
3598 rescan? "Re-scan" : "Reset",
3599 bus_result->path_id);
3602 * Don't bail out just yet, maybe the other
3603 * rescan or reset commands will complete
3606 fprintf(stderr, "%s of bus %d returned error "
3607 "%#x\n", rescan? "Re-scan" : "Reset",
3608 bus_result->path_id,
3609 ccb->ccb_h.status & CAM_STATUS_MASK);
3613 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3614 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3621 if (matchccb != NULL) {
3622 free(matchccb->cdm.patterns);
3623 free(matchccb->cdm.matches);
3632 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3635 struct cam_device *device;
3640 if (bus == CAM_BUS_WILDCARD) {
3641 warnx("invalid bus number %d", bus);
3645 if (target == CAM_TARGET_WILDCARD) {
3646 warnx("invalid target number %d", target);
3650 if (lun == CAM_LUN_WILDCARD) {
3651 warnx("invalid lun number %jx", (uintmax_t)lun);
3657 bzero(&ccb, sizeof(union ccb));
3660 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3661 warnx("error opening transport layer device %s\n",
3663 warn("%s", XPT_DEVICE);
3667 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3668 if (device == NULL) {
3669 warnx("%s", cam_errbuf);
3674 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3675 ccb.ccb_h.path_id = bus;
3676 ccb.ccb_h.target_id = target;
3677 ccb.ccb_h.target_lun = lun;
3678 ccb.ccb_h.timeout = 5000;
3679 ccb.crcn.flags = CAM_FLAG_NONE;
3681 /* run this at a low priority */
3682 ccb.ccb_h.pinfo.priority = 5;
3685 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3686 warn("CAMIOCOMMAND ioctl failed");
3691 if (cam_send_ccb(device, &ccb) < 0) {
3692 warn("error sending XPT_RESET_DEV CCB");
3693 cam_close_device(device);
3701 cam_close_device(device);
3704 * An error code of CAM_BDR_SENT is normal for a BDR request.
3706 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3708 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3709 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3710 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3713 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3714 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3715 ccb.ccb_h.status & CAM_STATUS_MASK);
3721 static struct scsi_nv defect_list_type_map[] = {
3722 { "block", SRDD10_BLOCK_FORMAT },
3723 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3724 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3725 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3726 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3727 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3731 readdefects(struct cam_device *device, int argc, char **argv,
3732 char *combinedopt, int task_attr, int retry_count, int timeout)
3734 union ccb *ccb = NULL;
3735 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3736 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3737 size_t hdr_size = 0, entry_size = 0;
3740 u_int8_t *defect_list = NULL;
3741 u_int8_t list_format = 0;
3742 int list_type_set = 0;
3743 u_int32_t dlist_length = 0;
3744 u_int32_t returned_length = 0, valid_len = 0;
3745 u_int32_t num_returned = 0, num_valid = 0;
3746 u_int32_t max_possible_size = 0, hdr_max = 0;
3747 u_int32_t starting_offset = 0;
3748 u_int8_t returned_format, returned_type;
3750 int summary = 0, quiet = 0;
3752 int lists_specified = 0;
3753 int get_length = 1, first_pass = 1;
3756 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3760 scsi_nv_status status;
3763 status = scsi_get_nv(defect_list_type_map,
3764 sizeof(defect_list_type_map) /
3765 sizeof(defect_list_type_map[0]), optarg,
3766 &entry_num, SCSI_NV_FLAG_IG_CASE);
3768 if (status == SCSI_NV_FOUND) {
3769 list_format = defect_list_type_map[
3773 warnx("%s: %s %s option %s", __func__,
3774 (status == SCSI_NV_AMBIGUOUS) ?
3775 "ambiguous" : "invalid", "defect list type",
3778 goto defect_bailout;
3783 arglist |= CAM_ARG_GLIST;
3786 arglist |= CAM_ARG_PLIST;
3797 starting_offset = strtoul(optarg, &endptr, 0);
3798 if (*endptr != '\0') {
3800 warnx("invalid starting offset %s", optarg);
3801 goto defect_bailout;
3813 if (list_type_set == 0) {
3815 warnx("no defect list format specified");
3816 goto defect_bailout;
3819 if (arglist & CAM_ARG_PLIST) {
3820 list_format |= SRDD10_PLIST;
3824 if (arglist & CAM_ARG_GLIST) {
3825 list_format |= SRDD10_GLIST;
3830 * This implies a summary, and was the previous behavior.
3832 if (lists_specified == 0)
3835 ccb = cam_getccb(device);
3840 * We start off asking for just the header to determine how much
3841 * defect data is available. Some Hitachi drives return an error
3842 * if you ask for more data than the drive has. Once we know the
3843 * length, we retry the command with the returned length.
3845 if (use_12byte == 0)
3846 dlist_length = sizeof(*hdr10);
3848 dlist_length = sizeof(*hdr12);
3851 if (defect_list != NULL) {
3855 defect_list = malloc(dlist_length);
3856 if (defect_list == NULL) {
3857 warnx("can't malloc memory for defect list");
3859 goto defect_bailout;
3863 bzero(defect_list, dlist_length);
3866 * cam_getccb() zeros the CCB header only. So we need to zero the
3867 * payload portion of the ccb.
3869 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3871 scsi_read_defects(&ccb->csio,
3872 /*retries*/ retry_count,
3874 /*tag_action*/ task_attr,
3875 /*list_format*/ list_format,
3876 /*addr_desc_index*/ starting_offset,
3877 /*data_ptr*/ defect_list,
3878 /*dxfer_len*/ dlist_length,
3879 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3880 /*sense_len*/ SSD_FULL_SIZE,
3881 /*timeout*/ timeout ? timeout : 5000);
3883 /* Disable freezing the device queue */
3884 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3886 if (cam_send_ccb(device, ccb) < 0) {
3887 perror("error reading defect list");
3889 if (arglist & CAM_ARG_VERBOSE) {
3890 cam_error_print(device, ccb, CAM_ESF_ALL,
3891 CAM_EPF_ALL, stderr);
3895 goto defect_bailout;
3898 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3900 if (use_12byte == 0) {
3901 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3902 hdr_size = sizeof(*hdr10);
3903 hdr_max = SRDDH10_MAX_LENGTH;
3905 if (valid_len >= hdr_size) {
3906 returned_length = scsi_2btoul(hdr10->length);
3907 returned_format = hdr10->format;
3909 returned_length = 0;
3910 returned_format = 0;
3913 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3914 hdr_size = sizeof(*hdr12);
3915 hdr_max = SRDDH12_MAX_LENGTH;
3917 if (valid_len >= hdr_size) {
3918 returned_length = scsi_4btoul(hdr12->length);
3919 returned_format = hdr12->format;
3921 returned_length = 0;
3922 returned_format = 0;
3926 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3927 switch (returned_type) {
3928 case SRDD10_BLOCK_FORMAT:
3929 entry_size = sizeof(struct scsi_defect_desc_block);
3931 case SRDD10_LONG_BLOCK_FORMAT:
3932 entry_size = sizeof(struct scsi_defect_desc_long_block);
3934 case SRDD10_EXT_PHYS_FORMAT:
3935 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3936 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3938 case SRDD10_EXT_BFI_FORMAT:
3939 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3940 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3943 warnx("Unknown defect format 0x%x\n", returned_type);
3945 goto defect_bailout;
3949 max_possible_size = (hdr_max / entry_size) * entry_size;
3950 num_returned = returned_length / entry_size;
3951 num_valid = min(returned_length, valid_len - hdr_size);
3952 num_valid /= entry_size;
3954 if (get_length != 0) {
3957 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3958 CAM_SCSI_STATUS_ERROR) {
3959 struct scsi_sense_data *sense;
3960 int error_code, sense_key, asc, ascq;
3962 sense = &ccb->csio.sense_data;
3963 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3964 ccb->csio.sense_resid, &error_code, &sense_key,
3965 &asc, &ascq, /*show_errors*/ 1);
3968 * If the drive is reporting that it just doesn't
3969 * support the defect list format, go ahead and use
3970 * the length it reported. Otherwise, the length
3971 * may not be valid, so use the maximum.
3973 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3974 && (asc == 0x1c) && (ascq == 0x00)
3975 && (returned_length > 0)) {
3976 if ((use_12byte == 0)
3977 && (returned_length >= max_possible_size)) {
3982 dlist_length = returned_length + hdr_size;
3983 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3984 && (asc == 0x1f) && (ascq == 0x00)
3985 && (returned_length > 0)) {
3986 /* Partial defect list transfer */
3988 * Hitachi drives return this error
3989 * along with a partial defect list if they
3990 * have more defects than the 10 byte
3991 * command can support. Retry with the 12
3994 if (use_12byte == 0) {
3999 dlist_length = returned_length + hdr_size;
4000 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
4001 && (asc == 0x24) && (ascq == 0x00)) {
4002 /* Invalid field in CDB */
4004 * SBC-3 says that if the drive has more
4005 * defects than can be reported with the
4006 * 10 byte command, it should return this
4007 * error and no data. Retry with the 12
4010 if (use_12byte == 0) {
4015 dlist_length = returned_length + hdr_size;
4018 * If we got a SCSI error and no valid length,
4019 * just use the 10 byte maximum. The 12
4020 * byte maximum is too large.
4022 if (returned_length == 0)
4023 dlist_length = SRDD10_MAX_LENGTH;
4025 if ((use_12byte == 0)
4026 && (returned_length >=
4027 max_possible_size)) {
4032 dlist_length = returned_length +
4036 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4039 warnx("Error reading defect header");
4040 if (arglist & CAM_ARG_VERBOSE)
4041 cam_error_print(device, ccb, CAM_ESF_ALL,
4042 CAM_EPF_ALL, stderr);
4043 goto defect_bailout;
4045 if ((use_12byte == 0)
4046 && (returned_length >= max_possible_size)) {
4051 dlist_length = returned_length + hdr_size;
4054 fprintf(stdout, "%u", num_returned);
4056 fprintf(stdout, " defect%s",
4057 (num_returned != 1) ? "s" : "");
4059 fprintf(stdout, "\n");
4061 goto defect_bailout;
4065 * We always limit the list length to the 10-byte maximum
4066 * length (0xffff). The reason is that some controllers
4067 * can't handle larger I/Os, and we can transfer the entire
4068 * 10 byte list in one shot. For drives that support the 12
4069 * byte read defects command, we'll step through the list
4070 * by specifying a starting offset. For drives that don't
4071 * support the 12 byte command's starting offset, we'll
4072 * just display the first 64K.
4074 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4080 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4081 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4082 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4083 struct scsi_sense_data *sense;
4084 int error_code, sense_key, asc, ascq;
4086 sense = &ccb->csio.sense_data;
4087 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4088 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4089 &ascq, /*show_errors*/ 1);
4092 * According to the SCSI spec, if the disk doesn't support
4093 * the requested format, it will generally return a sense
4094 * key of RECOVERED ERROR, and an additional sense code
4095 * of "DEFECT LIST NOT FOUND". HGST drives also return
4096 * Primary/Grown defect list not found errors. So just
4097 * check for an ASC of 0x1c.
4099 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4101 const char *format_str;
4103 format_str = scsi_nv_to_str(defect_list_type_map,
4104 sizeof(defect_list_type_map) /
4105 sizeof(defect_list_type_map[0]),
4106 list_format & SRDD10_DLIST_FORMAT_MASK);
4107 warnx("requested defect format %s not available",
4108 format_str ? format_str : "unknown");
4110 format_str = scsi_nv_to_str(defect_list_type_map,
4111 sizeof(defect_list_type_map) /
4112 sizeof(defect_list_type_map[0]), returned_type);
4113 if (format_str != NULL) {
4114 warnx("Device returned %s format",
4118 warnx("Device returned unknown defect"
4119 " data format %#x", returned_type);
4120 goto defect_bailout;
4124 warnx("Error returned from read defect data command");
4125 if (arglist & CAM_ARG_VERBOSE)
4126 cam_error_print(device, ccb, CAM_ESF_ALL,
4127 CAM_EPF_ALL, stderr);
4128 goto defect_bailout;
4130 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
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;
4139 if (first_pass != 0) {
4140 fprintf(stderr, "Got %d defect", num_returned);
4142 if ((lists_specified == 0) || (num_returned == 0)) {
4143 fprintf(stderr, "s.\n");
4144 goto defect_bailout;
4145 } else if (num_returned == 1)
4146 fprintf(stderr, ":\n");
4148 fprintf(stderr, "s:\n");
4154 * XXX KDM I should probably clean up the printout format for the
4157 switch (returned_type) {
4158 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4159 case SRDD10_EXT_PHYS_FORMAT:
4161 struct scsi_defect_desc_phys_sector *dlist;
4163 dlist = (struct scsi_defect_desc_phys_sector *)
4164 (defect_list + hdr_size);
4166 for (i = 0; i < num_valid; i++) {
4169 sector = scsi_4btoul(dlist[i].sector);
4170 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4171 mads = (sector & SDD_EXT_PHYS_MADS) ?
4173 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4175 if (hex_format == 0)
4176 fprintf(stdout, "%d:%d:%d%s",
4177 scsi_3btoul(dlist[i].cylinder),
4179 scsi_4btoul(dlist[i].sector),
4180 mads ? " - " : "\n");
4182 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4183 scsi_3btoul(dlist[i].cylinder),
4185 scsi_4btoul(dlist[i].sector),
4186 mads ? " - " : "\n");
4189 if (num_valid < num_returned) {
4190 starting_offset += num_valid;
4195 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4196 case SRDD10_EXT_BFI_FORMAT:
4198 struct scsi_defect_desc_bytes_from_index *dlist;
4200 dlist = (struct scsi_defect_desc_bytes_from_index *)
4201 (defect_list + hdr_size);
4203 for (i = 0; i < num_valid; i++) {
4206 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4207 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4208 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4209 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4211 if (hex_format == 0)
4212 fprintf(stdout, "%d:%d:%d%s",
4213 scsi_3btoul(dlist[i].cylinder),
4215 scsi_4btoul(dlist[i].bytes_from_index),
4216 mads ? " - " : "\n");
4218 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4219 scsi_3btoul(dlist[i].cylinder),
4221 scsi_4btoul(dlist[i].bytes_from_index),
4222 mads ? " - " : "\n");
4226 if (num_valid < num_returned) {
4227 starting_offset += num_valid;
4232 case SRDDH10_BLOCK_FORMAT:
4234 struct scsi_defect_desc_block *dlist;
4236 dlist = (struct scsi_defect_desc_block *)
4237 (defect_list + hdr_size);
4239 for (i = 0; i < num_valid; i++) {
4240 if (hex_format == 0)
4241 fprintf(stdout, "%u\n",
4242 scsi_4btoul(dlist[i].address));
4244 fprintf(stdout, "0x%x\n",
4245 scsi_4btoul(dlist[i].address));
4248 if (num_valid < num_returned) {
4249 starting_offset += num_valid;
4255 case SRDD10_LONG_BLOCK_FORMAT:
4257 struct scsi_defect_desc_long_block *dlist;
4259 dlist = (struct scsi_defect_desc_long_block *)
4260 (defect_list + hdr_size);
4262 for (i = 0; i < num_valid; i++) {
4263 if (hex_format == 0)
4264 fprintf(stdout, "%ju\n",
4265 (uintmax_t)scsi_8btou64(
4268 fprintf(stdout, "0x%jx\n",
4269 (uintmax_t)scsi_8btou64(
4273 if (num_valid < num_returned) {
4274 starting_offset += num_valid;
4280 fprintf(stderr, "Unknown defect format 0x%x\n",
4287 if (defect_list != NULL)
4298 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4302 ccb = cam_getccb(device);
4309 mode_sense(struct cam_device *device, int dbd, int pc, int page, int subpage,
4310 int task_attr, int retry_count, int timeout, u_int8_t *data,
4316 ccb = cam_getccb(device);
4319 errx(1, "mode_sense: couldn't allocate CCB");
4321 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4323 scsi_mode_sense_subpage(&ccb->csio,
4324 /* retries */ retry_count,
4326 /* tag_action */ task_attr,
4330 /* subpage */ subpage,
4331 /* param_buf */ data,
4332 /* param_len */ datalen,
4333 /* minimum_cmd_size */ 0,
4334 /* sense_len */ SSD_FULL_SIZE,
4335 /* timeout */ timeout ? timeout : 5000);
4337 if (arglist & CAM_ARG_ERR_RECOVER)
4338 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4340 /* Disable freezing the device queue */
4341 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4343 if (((retval = cam_send_ccb(device, ccb)) < 0)
4344 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4345 if (arglist & CAM_ARG_VERBOSE) {
4346 cam_error_print(device, ccb, CAM_ESF_ALL,
4347 CAM_EPF_ALL, stderr);
4350 cam_close_device(device);
4352 err(1, "error sending mode sense command");
4354 errx(1, "error sending mode sense command");
4361 mode_select(struct cam_device *device, int save_pages, int task_attr,
4362 int retry_count, int timeout, u_int8_t *data, int datalen)
4367 ccb = cam_getccb(device);
4370 errx(1, "mode_select: couldn't allocate CCB");
4372 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4374 scsi_mode_select(&ccb->csio,
4375 /* retries */ retry_count,
4377 /* tag_action */ task_attr,
4378 /* scsi_page_fmt */ 1,
4379 /* save_pages */ save_pages,
4380 /* param_buf */ data,
4381 /* param_len */ datalen,
4382 /* sense_len */ SSD_FULL_SIZE,
4383 /* timeout */ timeout ? timeout : 5000);
4385 if (arglist & CAM_ARG_ERR_RECOVER)
4386 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4388 /* Disable freezing the device queue */
4389 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4391 if (((retval = cam_send_ccb(device, ccb)) < 0)
4392 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4393 if (arglist & CAM_ARG_VERBOSE) {
4394 cam_error_print(device, ccb, CAM_ESF_ALL,
4395 CAM_EPF_ALL, stderr);
4398 cam_close_device(device);
4401 err(1, "error sending mode select command");
4403 errx(1, "error sending mode select command");
4411 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4412 int task_attr, int retry_count, int timeout)
4415 int c, page = -1, subpage = -1, pc = 0;
4416 int binary = 0, dbd = 0, edit = 0, list = 0;
4418 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4433 str_subpage = optarg;
4434 strsep(&str_subpage, ",");
4435 page = strtol(optarg, NULL, 0);
4437 subpage = strtol(str_subpage, NULL, 0);
4441 errx(1, "invalid mode page %d", page);
4443 errx(1, "invalid mode subpage %d", subpage);
4446 pc = strtol(optarg, NULL, 0);
4447 if ((pc < 0) || (pc > 3))
4448 errx(1, "invalid page control field %d", pc);
4455 if (page == -1 && list == 0)
4456 errx(1, "you must specify a mode page!");
4459 mode_list(device, dbd, pc, list > 1, task_attr, retry_count,
4462 mode_edit(device, dbd, pc, page, subpage, edit, binary,
4463 task_attr, retry_count, timeout);
4468 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4469 int task_attr, int retry_count, int timeout)
4472 u_int32_t flags = CAM_DIR_NONE;
4473 u_int8_t *data_ptr = NULL;
4475 u_int8_t atacmd[12];
4476 struct get_hook hook;
4477 int c, data_bytes = 0, valid_bytes;
4483 char *datastr = NULL, *tstr, *resstr = NULL;
4485 int fd_data = 0, fd_res = 0;
4488 ccb = cam_getccb(device);
4491 warnx("scsicmd: error allocating ccb");
4495 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4497 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4501 while (isspace(*tstr) && (*tstr != '\0'))
4503 hook.argc = argc - optind;
4504 hook.argv = argv + optind;
4506 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4509 * Increment optind by the number of arguments the
4510 * encoding routine processed. After each call to
4511 * getopt(3), optind points to the argument that
4512 * getopt should process _next_. In this case,
4513 * that means it points to the first command string
4514 * argument, if there is one. Once we increment
4515 * this, it should point to either the next command
4516 * line argument, or it should be past the end of
4523 while (isspace(*tstr) && (*tstr != '\0'))
4525 hook.argc = argc - optind;
4526 hook.argv = argv + optind;
4528 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4531 * Increment optind by the number of arguments the
4532 * encoding routine processed. After each call to
4533 * getopt(3), optind points to the argument that
4534 * getopt should process _next_. In this case,
4535 * that means it points to the first command string
4536 * argument, if there is one. Once we increment
4537 * this, it should point to either the next command
4538 * line argument, or it should be past the end of
4550 if (arglist & CAM_ARG_CMD_OUT) {
4551 warnx("command must either be "
4552 "read or write, not both");
4554 goto scsicmd_bailout;
4556 arglist |= CAM_ARG_CMD_IN;
4558 data_bytes = strtol(optarg, NULL, 0);
4559 if (data_bytes <= 0) {
4560 warnx("invalid number of input bytes %d",
4563 goto scsicmd_bailout;
4565 hook.argc = argc - optind;
4566 hook.argv = argv + optind;
4569 datastr = cget(&hook, NULL);
4571 * If the user supplied "-" instead of a format, he
4572 * wants the data to be written to stdout.
4574 if ((datastr != NULL)
4575 && (datastr[0] == '-'))
4578 data_ptr = (u_int8_t *)malloc(data_bytes);
4579 if (data_ptr == NULL) {
4580 warnx("can't malloc memory for data_ptr");
4582 goto scsicmd_bailout;
4586 if (arglist & CAM_ARG_CMD_IN) {
4587 warnx("command must either be "
4588 "read or write, not both");
4590 goto scsicmd_bailout;
4592 arglist |= CAM_ARG_CMD_OUT;
4593 flags = CAM_DIR_OUT;
4594 data_bytes = strtol(optarg, NULL, 0);
4595 if (data_bytes <= 0) {
4596 warnx("invalid number of output bytes %d",
4599 goto scsicmd_bailout;
4601 hook.argc = argc - optind;
4602 hook.argv = argv + optind;
4604 datastr = cget(&hook, NULL);
4605 data_ptr = (u_int8_t *)malloc(data_bytes);
4606 if (data_ptr == NULL) {
4607 warnx("can't malloc memory for data_ptr");
4609 goto scsicmd_bailout;
4611 bzero(data_ptr, data_bytes);
4613 * If the user supplied "-" instead of a format, he
4614 * wants the data to be read from stdin.
4616 if ((datastr != NULL)
4617 && (datastr[0] == '-'))
4620 buff_encode_visit(data_ptr, data_bytes, datastr,
4626 hook.argc = argc - optind;
4627 hook.argv = argv + optind;
4629 resstr = cget(&hook, NULL);
4630 if ((resstr != NULL) && (resstr[0] == '-'))
4640 * If fd_data is set, and we're writing to the device, we need to
4641 * read the data the user wants written from stdin.
4643 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4645 int amt_to_read = data_bytes;
4646 u_int8_t *buf_ptr = data_ptr;
4648 for (amt_read = 0; amt_to_read > 0;
4649 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4650 if (amt_read == -1) {
4651 warn("error reading data from stdin");
4653 goto scsicmd_bailout;
4655 amt_to_read -= amt_read;
4656 buf_ptr += amt_read;
4660 if (arglist & CAM_ARG_ERR_RECOVER)
4661 flags |= CAM_PASS_ERR_RECOVER;
4663 /* Disable freezing the device queue */
4664 flags |= CAM_DEV_QFRZDIS;
4668 * This is taken from the SCSI-3 draft spec.
4669 * (T10/1157D revision 0.3)
4670 * The top 3 bits of an opcode are the group code.
4671 * The next 5 bits are the command code.
4672 * Group 0: six byte commands
4673 * Group 1: ten byte commands
4674 * Group 2: ten byte commands
4676 * Group 4: sixteen byte commands
4677 * Group 5: twelve byte commands
4678 * Group 6: vendor specific
4679 * Group 7: vendor specific
4681 switch((cdb[0] >> 5) & 0x7) {
4692 /* computed by buff_encode_visit */
4703 * We should probably use csio_build_visit or something like that
4704 * here, but it's easier to encode arguments as you go. The
4705 * alternative would be skipping the CDB argument and then encoding
4706 * it here, since we've got the data buffer argument by now.
4708 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4710 cam_fill_csio(&ccb->csio,
4711 /*retries*/ retry_count,
4714 /*tag_action*/ task_attr,
4715 /*data_ptr*/ data_ptr,
4716 /*dxfer_len*/ data_bytes,
4717 /*sense_len*/ SSD_FULL_SIZE,
4718 /*cdb_len*/ cdb_len,
4719 /*timeout*/ timeout ? timeout : 5000);
4722 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4724 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4726 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4728 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4730 cam_fill_ataio(&ccb->ataio,
4731 /*retries*/ retry_count,
4735 /*data_ptr*/ data_ptr,
4736 /*dxfer_len*/ data_bytes,
4737 /*timeout*/ timeout ? timeout : 5000);
4740 if (((retval = cam_send_ccb(device, ccb)) < 0)
4741 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4742 const char warnstr[] = "error sending command";
4749 if (arglist & CAM_ARG_VERBOSE) {
4750 cam_error_print(device, ccb, CAM_ESF_ALL,
4751 CAM_EPF_ALL, stderr);
4755 goto scsicmd_bailout;
4758 if (atacmd_len && need_res) {
4760 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4762 fprintf(stdout, "\n");
4765 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4766 ccb->ataio.res.status,
4767 ccb->ataio.res.error,
4768 ccb->ataio.res.lba_low,
4769 ccb->ataio.res.lba_mid,
4770 ccb->ataio.res.lba_high,
4771 ccb->ataio.res.device,
4772 ccb->ataio.res.lba_low_exp,
4773 ccb->ataio.res.lba_mid_exp,
4774 ccb->ataio.res.lba_high_exp,
4775 ccb->ataio.res.sector_count,
4776 ccb->ataio.res.sector_count_exp);
4782 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4784 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4785 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4786 && (arglist & CAM_ARG_CMD_IN)
4787 && (valid_bytes > 0)) {
4789 buff_decode_visit(data_ptr, valid_bytes, datastr,
4791 fprintf(stdout, "\n");
4793 ssize_t amt_written;
4794 int amt_to_write = valid_bytes;
4795 u_int8_t *buf_ptr = data_ptr;
4797 for (amt_written = 0; (amt_to_write > 0) &&
4798 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4799 amt_to_write -= amt_written;
4800 buf_ptr += amt_written;
4802 if (amt_written == -1) {
4803 warn("error writing data to stdout");
4805 goto scsicmd_bailout;
4806 } else if ((amt_written == 0)
4807 && (amt_to_write > 0)) {
4808 warnx("only wrote %u bytes out of %u",
4809 valid_bytes - amt_to_write, valid_bytes);
4816 if ((data_bytes > 0) && (data_ptr != NULL))
4825 camdebug(int argc, char **argv, char *combinedopt)
4828 path_id_t bus = CAM_BUS_WILDCARD;
4829 target_id_t target = CAM_TARGET_WILDCARD;
4830 lun_id_t lun = CAM_LUN_WILDCARD;
4831 char *tstr, *tmpstr = NULL;
4835 bzero(&ccb, sizeof(union ccb));
4837 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4840 arglist |= CAM_ARG_DEBUG_INFO;
4841 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4844 arglist |= CAM_ARG_DEBUG_PERIPH;
4845 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4848 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4849 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4852 arglist |= CAM_ARG_DEBUG_TRACE;
4853 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4856 arglist |= CAM_ARG_DEBUG_XPT;
4857 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4860 arglist |= CAM_ARG_DEBUG_CDB;
4861 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4864 arglist |= CAM_ARG_DEBUG_PROBE;
4865 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4872 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4873 warnx("error opening transport layer device %s", XPT_DEVICE);
4874 warn("%s", XPT_DEVICE);
4881 warnx("you must specify \"off\", \"all\" or a bus,");
4882 warnx("bus:target, or bus:target:lun");
4889 while (isspace(*tstr) && (*tstr != '\0'))
4892 if (strncmp(tstr, "off", 3) == 0) {
4893 ccb.cdbg.flags = CAM_DEBUG_NONE;
4894 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4895 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4896 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4897 } else if (strncmp(tstr, "all", 3) != 0) {
4898 tmpstr = (char *)strtok(tstr, ":");
4899 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4900 bus = strtol(tmpstr, NULL, 0);
4901 arglist |= CAM_ARG_BUS;
4902 tmpstr = (char *)strtok(NULL, ":");
4903 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4904 target = strtol(tmpstr, NULL, 0);
4905 arglist |= CAM_ARG_TARGET;
4906 tmpstr = (char *)strtok(NULL, ":");
4907 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4908 lun = strtol(tmpstr, NULL, 0);
4909 arglist |= CAM_ARG_LUN;
4914 warnx("you must specify \"all\", \"off\", or a bus,");
4915 warnx("bus:target, or bus:target:lun to debug");
4921 ccb.ccb_h.func_code = XPT_DEBUG;
4922 ccb.ccb_h.path_id = bus;
4923 ccb.ccb_h.target_id = target;
4924 ccb.ccb_h.target_lun = lun;
4926 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4927 warn("CAMIOCOMMAND ioctl failed");
4932 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4933 CAM_FUNC_NOTAVAIL) {
4934 warnx("CAM debugging not available");
4935 warnx("you need to put options CAMDEBUG in"
4936 " your kernel config file!");
4938 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4940 warnx("XPT_DEBUG CCB failed with status %#x",
4944 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4946 "Debugging turned off\n");
4949 "Debugging enabled for "
4951 bus, target, (uintmax_t)lun);
4962 tagcontrol(struct cam_device *device, int argc, char **argv,
4972 ccb = cam_getccb(device);
4975 warnx("tagcontrol: error allocating ccb");
4979 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4982 numtags = strtol(optarg, NULL, 0);
4984 warnx("tag count %d is < 0", numtags);
4986 goto tagcontrol_bailout;
4997 cam_path_string(device, pathstr, sizeof(pathstr));
5000 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
5001 ccb->ccb_h.func_code = XPT_REL_SIMQ;
5002 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5003 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5004 ccb->crs.openings = numtags;
5007 if (cam_send_ccb(device, ccb) < 0) {
5008 perror("error sending XPT_REL_SIMQ CCB");
5010 goto tagcontrol_bailout;
5013 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5014 warnx("XPT_REL_SIMQ CCB failed");
5015 cam_error_print(device, ccb, CAM_ESF_ALL,
5016 CAM_EPF_ALL, stderr);
5018 goto tagcontrol_bailout;
5023 fprintf(stdout, "%stagged openings now %d\n",
5024 pathstr, ccb->crs.openings);
5027 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5029 ccb->ccb_h.func_code = XPT_GDEV_STATS;
5031 if (cam_send_ccb(device, ccb) < 0) {
5032 perror("error sending XPT_GDEV_STATS CCB");
5034 goto tagcontrol_bailout;
5037 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5038 warnx("XPT_GDEV_STATS CCB failed");
5039 cam_error_print(device, ccb, CAM_ESF_ALL,
5040 CAM_EPF_ALL, stderr);
5042 goto tagcontrol_bailout;
5045 if (arglist & CAM_ARG_VERBOSE) {
5046 fprintf(stdout, "%s", pathstr);
5047 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5048 fprintf(stdout, "%s", pathstr);
5049 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5050 fprintf(stdout, "%s", pathstr);
5051 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5052 fprintf(stdout, "%s", pathstr);
5053 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5054 fprintf(stdout, "%s", pathstr);
5055 fprintf(stdout, "held %d\n", ccb->cgds.held);
5056 fprintf(stdout, "%s", pathstr);
5057 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5058 fprintf(stdout, "%s", pathstr);
5059 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5062 fprintf(stdout, "%s", pathstr);
5063 fprintf(stdout, "device openings: ");
5065 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5066 ccb->cgds.dev_active);
5076 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5080 cam_path_string(device, pathstr, sizeof(pathstr));
5082 if (cts->transport == XPORT_SPI) {
5083 struct ccb_trans_settings_spi *spi =
5084 &cts->xport_specific.spi;
5086 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5088 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5091 if (spi->sync_offset != 0) {
5094 freq = scsi_calc_syncsrate(spi->sync_period);
5095 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5096 pathstr, freq / 1000, freq % 1000);
5100 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5101 fprintf(stdout, "%soffset: %d\n", pathstr,
5105 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5106 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5107 (0x01 << spi->bus_width) * 8);
5110 if (spi->valid & CTS_SPI_VALID_DISC) {
5111 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5112 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5113 "enabled" : "disabled");
5116 if (cts->transport == XPORT_FC) {
5117 struct ccb_trans_settings_fc *fc =
5118 &cts->xport_specific.fc;
5120 if (fc->valid & CTS_FC_VALID_WWNN)
5121 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5122 (long long) fc->wwnn);
5123 if (fc->valid & CTS_FC_VALID_WWPN)
5124 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5125 (long long) fc->wwpn);
5126 if (fc->valid & CTS_FC_VALID_PORT)
5127 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5128 if (fc->valid & CTS_FC_VALID_SPEED)
5129 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5130 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5132 if (cts->transport == XPORT_SAS) {
5133 struct ccb_trans_settings_sas *sas =
5134 &cts->xport_specific.sas;
5136 if (sas->valid & CTS_SAS_VALID_SPEED)
5137 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5138 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5140 if (cts->transport == XPORT_ATA) {
5141 struct ccb_trans_settings_pata *pata =
5142 &cts->xport_specific.ata;
5144 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5145 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5146 ata_mode2string(pata->mode));
5148 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5149 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5152 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5153 fprintf(stdout, "%sPIO transaction length: %d\n",
5154 pathstr, pata->bytecount);
5157 if (cts->transport == XPORT_SATA) {
5158 struct ccb_trans_settings_sata *sata =
5159 &cts->xport_specific.sata;
5161 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5162 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5165 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5166 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5167 ata_mode2string(sata->mode));
5169 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5170 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5173 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5174 fprintf(stdout, "%sPIO transaction length: %d\n",
5175 pathstr, sata->bytecount);
5177 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5178 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5181 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5182 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5185 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5186 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5190 if (cts->protocol == PROTO_ATA) {
5191 struct ccb_trans_settings_ata *ata=
5192 &cts->proto_specific.ata;
5194 if (ata->valid & CTS_ATA_VALID_TQ) {
5195 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5196 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5197 "enabled" : "disabled");
5200 if (cts->protocol == PROTO_SCSI) {
5201 struct ccb_trans_settings_scsi *scsi=
5202 &cts->proto_specific.scsi;
5204 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5205 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5206 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5207 "enabled" : "disabled");
5211 if (cts->protocol == PROTO_NVME) {
5212 struct ccb_trans_settings_nvme *nvmex =
5213 &cts->xport_specific.nvme;
5215 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5216 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5217 NVME_MAJOR(nvmex->spec),
5218 NVME_MINOR(nvmex->spec));
5220 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5221 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5222 nvmex->lanes, nvmex->max_lanes);
5223 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5224 nvmex->speed, nvmex->max_speed);
5231 * Get a path inquiry CCB for the specified device.
5234 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5239 ccb = cam_getccb(device);
5241 warnx("get_cpi: couldn't allocate CCB");
5244 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5245 ccb->ccb_h.func_code = XPT_PATH_INQ;
5246 if (cam_send_ccb(device, ccb) < 0) {
5247 warn("get_cpi: error sending Path Inquiry CCB");
5248 if (arglist & CAM_ARG_VERBOSE)
5249 cam_error_print(device, ccb, CAM_ESF_ALL,
5250 CAM_EPF_ALL, stderr);
5252 goto get_cpi_bailout;
5254 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5255 if (arglist & CAM_ARG_VERBOSE)
5256 cam_error_print(device, ccb, CAM_ESF_ALL,
5257 CAM_EPF_ALL, stderr);
5259 goto get_cpi_bailout;
5261 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5269 * Get a get device CCB for the specified device.
5272 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5277 ccb = cam_getccb(device);
5279 warnx("get_cgd: couldn't allocate CCB");
5282 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5283 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5284 if (cam_send_ccb(device, ccb) < 0) {
5285 warn("get_cgd: error sending Path Inquiry CCB");
5286 if (arglist & CAM_ARG_VERBOSE)
5287 cam_error_print(device, ccb, CAM_ESF_ALL,
5288 CAM_EPF_ALL, stderr);
5290 goto get_cgd_bailout;
5292 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5293 if (arglist & CAM_ARG_VERBOSE)
5294 cam_error_print(device, ccb, CAM_ESF_ALL,
5295 CAM_EPF_ALL, stderr);
5297 goto get_cgd_bailout;
5299 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5307 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5311 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5312 int timeout, int verbosemode)
5314 union ccb *ccb = NULL;
5315 struct scsi_vpd_supported_page_list sup_pages;
5319 ccb = cam_getccb(dev);
5321 warn("Unable to allocate CCB");
5326 /* cam_getccb cleans up the header, caller has to zero the payload */
5327 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5329 bzero(&sup_pages, sizeof(sup_pages));
5331 scsi_inquiry(&ccb->csio,
5332 /*retries*/ retry_count,
5334 /* tag_action */ MSG_SIMPLE_Q_TAG,
5335 /* inq_buf */ (u_int8_t *)&sup_pages,
5336 /* inq_len */ sizeof(sup_pages),
5338 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5339 /* sense_len */ SSD_FULL_SIZE,
5340 /* timeout */ timeout ? timeout : 5000);
5342 /* Disable freezing the device queue */
5343 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5345 if (retry_count != 0)
5346 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5348 if (cam_send_ccb(dev, ccb) < 0) {
5355 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5356 if (verbosemode != 0)
5357 cam_error_print(dev, ccb, CAM_ESF_ALL,
5358 CAM_EPF_ALL, stderr);
5363 for (i = 0; i < sup_pages.length; i++) {
5364 if (sup_pages.list[i] == page_id) {
5377 * devtype is filled in with the type of device.
5378 * Returns 0 for success, non-zero for failure.
5381 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5382 int verbosemode, camcontrol_devtype *devtype)
5384 struct ccb_getdev cgd;
5387 retval = get_cgd(dev, &cgd);
5391 switch (cgd.protocol) {
5397 *devtype = CC_DT_ATA;
5399 break; /*NOTREACHED*/
5401 *devtype = CC_DT_NVME;
5403 break; /*NOTREACHED*/
5405 *devtype = CC_DT_MMCSD;
5407 break; /*NOTREACHED*/
5409 *devtype = CC_DT_UNKNOWN;
5411 break; /*NOTREACHED*/
5414 if (retry_count == -1) {
5416 * For a retry count of -1, used only the cached data to avoid
5417 * I/O to the drive. Sending the identify command to the drive
5418 * can cause issues for SATL attachaed drives since identify is
5419 * not an NCQ command.
5421 if (cgd.ident_data.config != 0)
5422 *devtype = CC_DT_SATL;
5424 *devtype = CC_DT_SCSI;
5427 * Check for the ATA Information VPD page (0x89). If this is an
5428 * ATA device behind a SCSI to ATA translation layer (SATL),
5429 * this VPD page should be present.
5431 * If that VPD page isn't present, or we get an error back from
5432 * the INQUIRY command, we'll just treat it as a normal SCSI
5435 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5436 timeout, verbosemode);
5438 *devtype = CC_DT_SATL;
5440 *devtype = CC_DT_SCSI;
5449 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5450 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5451 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5452 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5453 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5454 int is48bit, camcontrol_devtype devtype)
5458 if (devtype == CC_DT_ATA) {
5459 cam_fill_ataio(&ccb->ataio,
5460 /*retries*/ retry_count,
5463 /*tag_action*/ tag_action,
5464 /*data_ptr*/ data_ptr,
5465 /*dxfer_len*/ dxfer_len,
5466 /*timeout*/ timeout);
5467 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5468 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5471 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5474 if (auxiliary != 0) {
5475 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5476 ccb->ataio.aux = auxiliary;
5479 if (ata_flags & AP_FLAG_CHK_COND)
5480 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5482 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5483 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5484 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5485 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5487 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5488 protocol |= AP_EXTEND;
5490 retval = scsi_ata_pass(&ccb->csio,
5491 /*retries*/ retry_count,
5494 /*tag_action*/ tag_action,
5495 /*protocol*/ protocol,
5496 /*ata_flags*/ ata_flags,
5497 /*features*/ features,
5498 /*sector_count*/ sector_count,
5500 /*command*/ command,
5503 /*auxiliary*/ auxiliary,
5505 /*data_ptr*/ data_ptr,
5506 /*dxfer_len*/ dxfer_len,
5507 /*cdb_storage*/ cdb_storage,
5508 /*cdb_storage_len*/ cdb_storage_len,
5509 /*minimum_cmd_size*/ 0,
5510 /*sense_len*/ sense_len,
5511 /*timeout*/ timeout);
5518 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5519 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5523 switch (ccb->ccb_h.func_code) {
5526 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5529 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5530 * or 16 byte, and need to see what
5532 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5533 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5535 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5536 if ((opcode != ATA_PASS_12)
5537 && (opcode != ATA_PASS_16)) {
5539 warnx("%s: unsupported opcode %02x", __func__, opcode);
5543 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5545 /* Note: the _ccb() variant returns 0 for an error */
5552 switch (error_code) {
5553 case SSD_DESC_CURRENT_ERROR:
5554 case SSD_DESC_DEFERRED_ERROR: {
5555 struct scsi_sense_data_desc *sense;
5556 struct scsi_sense_ata_ret_desc *desc;
5559 sense = (struct scsi_sense_data_desc *)
5560 &ccb->csio.sense_data;
5562 desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len -
5563 ccb->csio.sense_resid, SSD_DESC_ATA);
5564 if (desc_ptr == NULL) {
5565 cam_error_print(dev, ccb, CAM_ESF_ALL,
5566 CAM_EPF_ALL, stderr);
5570 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5572 *error = desc->error;
5573 *count = (desc->count_15_8 << 8) |
5575 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5576 ((uint64_t)desc->lba_39_32 << 32) |
5577 ((uint64_t)desc->lba_31_24 << 24) |
5578 (desc->lba_23_16 << 16) |
5579 (desc->lba_15_8 << 8) |
5581 *device = desc->device;
5582 *status = desc->status;
5585 * If the extend bit isn't set, the result is for a
5586 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5587 * command without the extend bit set. This means
5588 * that the device is supposed to return 28-bit
5589 * status. The count field is only 8 bits, and the
5590 * LBA field is only 8 bits.
5592 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5598 case SSD_CURRENT_ERROR:
5599 case SSD_DEFERRED_ERROR: {
5601 struct scsi_sense_data_fixed *sense;
5604 * XXX KDM need to support fixed sense data.
5606 warnx("%s: Fixed sense data not supported yet",
5610 break; /*NOTREACHED*/
5621 struct ata_res *res;
5624 * In this case, we have an ATA command, and we need to
5625 * fill in the requested values from the result register
5628 res = &ccb->ataio.res;
5629 *error = res->error;
5630 *status = res->status;
5631 *device = res->device;
5632 *count = res->sector_count;
5633 *lba = (res->lba_high << 16) |
5634 (res->lba_mid << 8) |
5636 if (res->flags & CAM_ATAIO_48BIT) {
5637 *count |= (res->sector_count_exp << 8);
5638 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5639 ((uint64_t)res->lba_mid_exp << 32) |
5640 ((uint64_t)res->lba_high_exp << 40);
5642 *lba |= (res->device & 0xf) << 24;
5655 cpi_print(struct ccb_pathinq *cpi)
5657 char adapter_str[1024];
5660 snprintf(adapter_str, sizeof(adapter_str),
5661 "%s%d:", cpi->dev_name, cpi->unit_number);
5663 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5666 for (i = 1; i < UINT8_MAX; i = i << 1) {
5669 if ((i & cpi->hba_inquiry) == 0)
5672 fprintf(stdout, "%s supports ", adapter_str);
5676 str = "MDP message";
5679 str = "32 bit wide SCSI";
5682 str = "16 bit wide SCSI";
5685 str = "SDTR message";
5688 str = "linked CDBs";
5691 str = "tag queue messages";
5694 str = "soft reset alternative";
5697 str = "SATA Port Multiplier";
5700 str = "unknown PI bit set";
5703 fprintf(stdout, "%s\n", str);
5706 for (i = 1; i < UINT32_MAX; i = i << 1) {
5709 if ((i & cpi->hba_misc) == 0)
5712 fprintf(stdout, "%s ", adapter_str);
5716 str = "can understand ata_ext requests";
5719 str = "64bit extended LUNs supported";
5722 str = "bus scans from high ID to low ID";
5725 str = "removable devices not included in scan";
5727 case PIM_NOINITIATOR:
5728 str = "initiator role not supported";
5730 case PIM_NOBUSRESET:
5731 str = "user has disabled initial BUS RESET or"
5732 " controller is in target/mixed mode";
5735 str = "do not send 6-byte commands";
5738 str = "scan bus sequentially";
5741 str = "unmapped I/O supported";
5744 str = "does its own scanning";
5747 str = "unknown PIM bit set";
5750 fprintf(stdout, "%s\n", str);
5753 for (i = 1; i < UINT16_MAX; i = i << 1) {
5756 if ((i & cpi->target_sprt) == 0)
5759 fprintf(stdout, "%s supports ", adapter_str);
5762 str = "target mode processor mode";
5765 str = "target mode phase cog. mode";
5767 case PIT_DISCONNECT:
5768 str = "disconnects in target mode";
5771 str = "terminate I/O message in target mode";
5774 str = "group 6 commands in target mode";
5777 str = "group 7 commands in target mode";
5780 str = "unknown PIT bit set";
5784 fprintf(stdout, "%s\n", str);
5786 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5788 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5790 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5792 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5793 adapter_str, cpi->hpath_id);
5794 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5796 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5797 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5798 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5799 adapter_str, cpi->hba_vendor);
5800 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5801 adapter_str, cpi->hba_device);
5802 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5803 adapter_str, cpi->hba_subvendor);
5804 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5805 adapter_str, cpi->hba_subdevice);
5806 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5807 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5808 if (cpi->base_transfer_speed > 1000)
5809 fprintf(stdout, "%d.%03dMB/sec\n",
5810 cpi->base_transfer_speed / 1000,
5811 cpi->base_transfer_speed % 1000);
5813 fprintf(stdout, "%dKB/sec\n",
5814 (cpi->base_transfer_speed % 1000) * 1000);
5815 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5816 adapter_str, cpi->maxio);
5820 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5821 struct ccb_trans_settings *cts)
5827 ccb = cam_getccb(device);
5830 warnx("get_print_cts: error allocating ccb");
5834 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5836 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5838 if (user_settings == 0)
5839 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5841 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5843 if (cam_send_ccb(device, ccb) < 0) {
5844 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5845 if (arglist & CAM_ARG_VERBOSE)
5846 cam_error_print(device, ccb, CAM_ESF_ALL,
5847 CAM_EPF_ALL, stderr);
5849 goto get_print_cts_bailout;
5852 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5853 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5854 if (arglist & CAM_ARG_VERBOSE)
5855 cam_error_print(device, ccb, CAM_ESF_ALL,
5856 CAM_EPF_ALL, stderr);
5858 goto get_print_cts_bailout;
5862 cts_print(device, &ccb->cts);
5865 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5867 get_print_cts_bailout:
5875 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
5876 int timeout, int argc, char **argv, char *combinedopt)
5880 int user_settings = 0;
5882 int disc_enable = -1, tag_enable = -1;
5885 double syncrate = -1;
5888 int change_settings = 0, send_tur = 0;
5889 struct ccb_pathinq cpi;
5891 ccb = cam_getccb(device);
5893 warnx("ratecontrol: error allocating ccb");
5896 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5905 if (strncasecmp(optarg, "enable", 6) == 0)
5907 else if (strncasecmp(optarg, "disable", 7) == 0)
5910 warnx("-D argument \"%s\" is unknown", optarg);
5912 goto ratecontrol_bailout;
5914 change_settings = 1;
5917 mode = ata_string2mode(optarg);
5919 warnx("unknown mode '%s'", optarg);
5921 goto ratecontrol_bailout;
5923 change_settings = 1;
5926 offset = strtol(optarg, NULL, 0);
5928 warnx("offset value %d is < 0", offset);
5930 goto ratecontrol_bailout;
5932 change_settings = 1;
5938 syncrate = atof(optarg);
5940 warnx("sync rate %f is < 0", syncrate);
5942 goto ratecontrol_bailout;
5944 change_settings = 1;
5947 if (strncasecmp(optarg, "enable", 6) == 0)
5949 else if (strncasecmp(optarg, "disable", 7) == 0)
5952 warnx("-T argument \"%s\" is unknown", optarg);
5954 goto ratecontrol_bailout;
5956 change_settings = 1;
5962 bus_width = strtol(optarg, NULL, 0);
5963 if (bus_width < 0) {
5964 warnx("bus width %d is < 0", bus_width);
5966 goto ratecontrol_bailout;
5968 change_settings = 1;
5974 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5976 * Grab path inquiry information, so we can determine whether
5977 * or not the initiator is capable of the things that the user
5980 ccb->ccb_h.func_code = XPT_PATH_INQ;
5981 if (cam_send_ccb(device, ccb) < 0) {
5982 perror("error sending XPT_PATH_INQ CCB");
5983 if (arglist & CAM_ARG_VERBOSE) {
5984 cam_error_print(device, ccb, CAM_ESF_ALL,
5985 CAM_EPF_ALL, stderr);
5988 goto ratecontrol_bailout;
5990 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5991 warnx("XPT_PATH_INQ CCB failed");
5992 if (arglist & CAM_ARG_VERBOSE) {
5993 cam_error_print(device, ccb, CAM_ESF_ALL,
5994 CAM_EPF_ALL, stderr);
5997 goto ratecontrol_bailout;
5999 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
6000 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
6002 fprintf(stdout, "%s parameters:\n",
6003 user_settings ? "User" : "Current");
6005 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
6007 goto ratecontrol_bailout;
6009 if (arglist & CAM_ARG_VERBOSE)
6012 if (change_settings) {
6013 int didsettings = 0;
6014 struct ccb_trans_settings_spi *spi = NULL;
6015 struct ccb_trans_settings_pata *pata = NULL;
6016 struct ccb_trans_settings_sata *sata = NULL;
6017 struct ccb_trans_settings_ata *ata = NULL;
6018 struct ccb_trans_settings_scsi *scsi = NULL;
6020 if (ccb->cts.transport == XPORT_SPI)
6021 spi = &ccb->cts.xport_specific.spi;
6022 if (ccb->cts.transport == XPORT_ATA)
6023 pata = &ccb->cts.xport_specific.ata;
6024 if (ccb->cts.transport == XPORT_SATA)
6025 sata = &ccb->cts.xport_specific.sata;
6026 if (ccb->cts.protocol == PROTO_ATA)
6027 ata = &ccb->cts.proto_specific.ata;
6028 if (ccb->cts.protocol == PROTO_SCSI)
6029 scsi = &ccb->cts.proto_specific.scsi;
6030 ccb->cts.xport_specific.valid = 0;
6031 ccb->cts.proto_specific.valid = 0;
6032 if (spi && disc_enable != -1) {
6033 spi->valid |= CTS_SPI_VALID_DISC;
6034 if (disc_enable == 0)
6035 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6037 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6040 if (tag_enable != -1) {
6041 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6042 warnx("HBA does not support tagged queueing, "
6043 "so you cannot modify tag settings");
6045 goto ratecontrol_bailout;
6048 ata->valid |= CTS_SCSI_VALID_TQ;
6049 if (tag_enable == 0)
6050 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6052 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6055 scsi->valid |= CTS_SCSI_VALID_TQ;
6056 if (tag_enable == 0)
6057 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6059 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6063 if (spi && offset != -1) {
6064 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6065 warnx("HBA is not capable of changing offset");
6067 goto ratecontrol_bailout;
6069 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6070 spi->sync_offset = offset;
6073 if (spi && syncrate != -1) {
6074 int prelim_sync_period;
6076 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6077 warnx("HBA is not capable of changing "
6080 goto ratecontrol_bailout;
6082 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6084 * The sync rate the user gives us is in MHz.
6085 * We need to translate it into KHz for this
6090 * Next, we calculate a "preliminary" sync period
6091 * in tenths of a nanosecond.
6094 prelim_sync_period = 0;
6096 prelim_sync_period = 10000000 / syncrate;
6098 scsi_calc_syncparam(prelim_sync_period);
6101 if (sata && syncrate != -1) {
6102 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6103 warnx("HBA is not capable of changing "
6106 goto ratecontrol_bailout;
6108 if (!user_settings) {
6109 warnx("You can modify only user rate "
6110 "settings for SATA");
6112 goto ratecontrol_bailout;
6114 sata->revision = ata_speed2revision(syncrate * 100);
6115 if (sata->revision < 0) {
6116 warnx("Invalid rate %f", syncrate);
6118 goto ratecontrol_bailout;
6120 sata->valid |= CTS_SATA_VALID_REVISION;
6123 if ((pata || sata) && mode != -1) {
6124 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6125 warnx("HBA is not capable of changing "
6128 goto ratecontrol_bailout;
6130 if (!user_settings) {
6131 warnx("You can modify only user mode "
6132 "settings for ATA/SATA");
6134 goto ratecontrol_bailout;
6138 pata->valid |= CTS_ATA_VALID_MODE;
6141 sata->valid |= CTS_SATA_VALID_MODE;
6146 * The bus_width argument goes like this:
6150 * Therefore, if you shift the number of bits given on the
6151 * command line right by 4, you should get the correct
6154 if (spi && bus_width != -1) {
6156 * We might as well validate things here with a
6157 * decipherable error message, rather than what
6158 * will probably be an indecipherable error message
6159 * by the time it gets back to us.
6161 if ((bus_width == 16)
6162 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6163 warnx("HBA does not support 16 bit bus width");
6165 goto ratecontrol_bailout;
6166 } else if ((bus_width == 32)
6167 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6168 warnx("HBA does not support 32 bit bus width");
6170 goto ratecontrol_bailout;
6171 } else if ((bus_width != 8)
6172 && (bus_width != 16)
6173 && (bus_width != 32)) {
6174 warnx("Invalid bus width %d", bus_width);
6176 goto ratecontrol_bailout;
6178 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6179 spi->bus_width = bus_width >> 4;
6182 if (didsettings == 0) {
6183 goto ratecontrol_bailout;
6185 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6186 if (cam_send_ccb(device, ccb) < 0) {
6187 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
6188 if (arglist & CAM_ARG_VERBOSE) {
6189 cam_error_print(device, ccb, CAM_ESF_ALL,
6190 CAM_EPF_ALL, stderr);
6193 goto ratecontrol_bailout;
6195 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6196 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6197 if (arglist & CAM_ARG_VERBOSE) {
6198 cam_error_print(device, ccb, CAM_ESF_ALL,
6199 CAM_EPF_ALL, stderr);
6202 goto ratecontrol_bailout;
6206 retval = testunitready(device, task_attr, retry_count, timeout,
6207 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6209 * If the TUR didn't succeed, just bail.
6213 fprintf(stderr, "Test Unit Ready failed\n");
6214 goto ratecontrol_bailout;
6217 if ((change_settings || send_tur) && !quiet &&
6218 (ccb->cts.transport == XPORT_ATA ||
6219 ccb->cts.transport == XPORT_SATA || send_tur)) {
6220 fprintf(stdout, "New parameters:\n");
6221 retval = get_print_cts(device, user_settings, 0, NULL);
6224 ratecontrol_bailout:
6230 scsiformat(struct cam_device *device, int argc, char **argv,
6231 char *combinedopt, int task_attr, int retry_count, int timeout)
6235 int ycount = 0, quiet = 0;
6236 int error = 0, retval = 0;
6237 int use_timeout = 10800 * 1000;
6239 struct format_defect_list_header fh;
6240 u_int8_t *data_ptr = NULL;
6241 u_int32_t dxfer_len = 0;
6243 int num_warnings = 0;
6246 ccb = cam_getccb(device);
6249 warnx("scsiformat: error allocating ccb");
6253 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6255 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6276 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6277 "following device:\n");
6279 error = scsidoinquiry(device, argc, argv, combinedopt,
6280 task_attr, retry_count, timeout);
6283 warnx("scsiformat: error sending inquiry");
6284 goto scsiformat_bailout;
6289 if (!get_confirmation()) {
6291 goto scsiformat_bailout;
6296 use_timeout = timeout;
6299 fprintf(stdout, "Current format timeout is %d seconds\n",
6300 use_timeout / 1000);
6304 * If the user hasn't disabled questions and didn't specify a
6305 * timeout on the command line, ask them if they want the current
6309 && (timeout == 0)) {
6311 int new_timeout = 0;
6313 fprintf(stdout, "Enter new timeout in seconds or press\n"
6314 "return to keep the current timeout [%d] ",
6315 use_timeout / 1000);
6317 if (fgets(str, sizeof(str), stdin) != NULL) {
6319 new_timeout = atoi(str);
6322 if (new_timeout != 0) {
6323 use_timeout = new_timeout * 1000;
6324 fprintf(stdout, "Using new timeout value %d\n",
6325 use_timeout / 1000);
6330 * Keep this outside the if block below to silence any unused
6331 * variable warnings.
6333 bzero(&fh, sizeof(fh));
6336 * If we're in immediate mode, we've got to include the format
6339 if (immediate != 0) {
6340 fh.byte2 = FU_DLH_IMMED;
6341 data_ptr = (u_int8_t *)&fh;
6342 dxfer_len = sizeof(fh);
6343 byte2 = FU_FMT_DATA;
6344 } else if (quiet == 0) {
6345 fprintf(stdout, "Formatting...");
6349 scsi_format_unit(&ccb->csio,
6350 /* retries */ retry_count,
6352 /* tag_action */ task_attr,
6355 /* data_ptr */ data_ptr,
6356 /* dxfer_len */ dxfer_len,
6357 /* sense_len */ SSD_FULL_SIZE,
6358 /* timeout */ use_timeout);
6360 /* Disable freezing the device queue */
6361 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6363 if (arglist & CAM_ARG_ERR_RECOVER)
6364 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6366 if (((retval = cam_send_ccb(device, ccb)) < 0)
6367 || ((immediate == 0)
6368 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6369 const char errstr[] = "error sending format command";
6376 if (arglist & CAM_ARG_VERBOSE) {
6377 cam_error_print(device, ccb, CAM_ESF_ALL,
6378 CAM_EPF_ALL, stderr);
6381 goto scsiformat_bailout;
6385 * If we ran in non-immediate mode, we already checked for errors
6386 * above and printed out any necessary information. If we're in
6387 * immediate mode, we need to loop through and get status
6388 * information periodically.
6390 if (immediate == 0) {
6392 fprintf(stdout, "Format Complete\n");
6394 goto scsiformat_bailout;
6401 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6404 * There's really no need to do error recovery or
6405 * retries here, since we're just going to sit in a
6406 * loop and wait for the device to finish formatting.
6408 scsi_test_unit_ready(&ccb->csio,
6411 /* tag_action */ task_attr,
6412 /* sense_len */ SSD_FULL_SIZE,
6413 /* timeout */ 5000);
6415 /* Disable freezing the device queue */
6416 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6418 retval = cam_send_ccb(device, ccb);
6421 * If we get an error from the ioctl, bail out. SCSI
6422 * errors are expected.
6425 warn("error sending CAMIOCOMMAND ioctl");
6426 if (arglist & CAM_ARG_VERBOSE) {
6427 cam_error_print(device, ccb, CAM_ESF_ALL,
6428 CAM_EPF_ALL, stderr);
6431 goto scsiformat_bailout;
6434 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6436 if ((status != CAM_REQ_CMP)
6437 && (status == CAM_SCSI_STATUS_ERROR)
6438 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6439 struct scsi_sense_data *sense;
6440 int error_code, sense_key, asc, ascq;
6442 sense = &ccb->csio.sense_data;
6443 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6444 ccb->csio.sense_resid, &error_code, &sense_key,
6445 &asc, &ascq, /*show_errors*/ 1);
6448 * According to the SCSI-2 and SCSI-3 specs, a
6449 * drive that is in the middle of a format should
6450 * return NOT READY with an ASC of "logical unit
6451 * not ready, format in progress". The sense key
6452 * specific bytes will then be a progress indicator.
6454 if ((sense_key == SSD_KEY_NOT_READY)
6455 && (asc == 0x04) && (ascq == 0x04)) {
6458 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6459 ccb->csio.sense_resid, sks) == 0)
6462 u_int64_t percentage;
6464 val = scsi_2btoul(&sks[1]);
6465 percentage = 10000ull * val;
6468 "\rFormatting: %ju.%02u %% "
6470 (uintmax_t)(percentage /
6472 (unsigned)((percentage /
6476 } else if ((quiet == 0)
6477 && (++num_warnings <= 1)) {
6478 warnx("Unexpected SCSI Sense Key "
6479 "Specific value returned "
6481 scsi_sense_print(device, &ccb->csio,
6483 warnx("Unable to print status "
6484 "information, but format will "
6486 warnx("will exit when format is "
6491 warnx("Unexpected SCSI error during format");
6492 cam_error_print(device, ccb, CAM_ESF_ALL,
6493 CAM_EPF_ALL, stderr);
6495 goto scsiformat_bailout;
6498 } else if (status != CAM_REQ_CMP) {
6499 warnx("Unexpected CAM status %#x", status);
6500 if (arglist & CAM_ARG_VERBOSE)
6501 cam_error_print(device, ccb, CAM_ESF_ALL,
6502 CAM_EPF_ALL, stderr);
6504 goto scsiformat_bailout;
6507 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6510 fprintf(stdout, "\nFormat Complete\n");
6520 scsisanitize(struct cam_device *device, int argc, char **argv,
6521 char *combinedopt, int task_attr, int retry_count, int timeout)
6524 u_int8_t action = 0;
6526 int ycount = 0, quiet = 0;
6527 int error = 0, retval = 0;
6528 int use_timeout = 10800 * 1000;
6534 const char *pattern = NULL;
6535 u_int8_t *data_ptr = NULL;
6536 u_int32_t dxfer_len = 0;
6538 int num_warnings = 0;
6541 ccb = cam_getccb(device);
6544 warnx("scsisanitize: error allocating ccb");
6548 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6550 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6553 if (strcasecmp(optarg, "overwrite") == 0)
6554 action = SSZ_SERVICE_ACTION_OVERWRITE;
6555 else if (strcasecmp(optarg, "block") == 0)
6556 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6557 else if (strcasecmp(optarg, "crypto") == 0)
6558 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6559 else if (strcasecmp(optarg, "exitfailure") == 0)
6560 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6562 warnx("invalid service operation \"%s\"",
6565 goto scsisanitize_bailout;
6569 passes = strtol(optarg, NULL, 0);
6570 if (passes < 1 || passes > 31) {
6571 warnx("invalid passes value %d", passes);
6573 goto scsisanitize_bailout;
6604 warnx("an action is required");
6606 goto scsisanitize_bailout;
6607 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6608 struct scsi_sanitize_parameter_list *pl;
6612 if (pattern == NULL) {
6613 warnx("overwrite action requires -P argument");
6615 goto scsisanitize_bailout;
6617 fd = open(pattern, O_RDONLY);
6619 warn("cannot open pattern file %s", pattern);
6621 goto scsisanitize_bailout;
6623 if (fstat(fd, &sb) < 0) {
6624 warn("cannot stat pattern file %s", pattern);
6626 goto scsisanitize_bailout;
6629 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6630 warnx("pattern file size exceeds maximum value %d",
6631 SSZPL_MAX_PATTERN_LENGTH);
6633 goto scsisanitize_bailout;
6635 dxfer_len = sizeof(*pl) + sz;
6636 data_ptr = calloc(1, dxfer_len);
6637 if (data_ptr == NULL) {
6638 warnx("cannot allocate parameter list buffer");
6640 goto scsisanitize_bailout;
6643 amt = read(fd, data_ptr + sizeof(*pl), sz);
6645 warn("cannot read pattern file");
6647 goto scsisanitize_bailout;
6648 } else if (amt != sz) {
6649 warnx("short pattern file read");
6651 goto scsisanitize_bailout;
6654 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6660 pl->byte1 |= SSZPL_INVERT;
6661 scsi_ulto2b(sz, pl->length);
6667 else if (invert != 0)
6669 else if (pattern != NULL)
6674 warnx("%s argument only valid with overwrite "
6677 goto scsisanitize_bailout;
6682 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6683 "following device:\n");
6685 error = scsidoinquiry(device, argc, argv, combinedopt,
6686 task_attr, retry_count, timeout);
6689 warnx("scsisanitize: error sending inquiry");
6690 goto scsisanitize_bailout;
6695 if (!get_confirmation()) {
6697 goto scsisanitize_bailout;
6702 use_timeout = timeout;
6705 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6706 use_timeout / 1000);
6710 * If the user hasn't disabled questions and didn't specify a
6711 * timeout on the command line, ask them if they want the current
6715 && (timeout == 0)) {
6717 int new_timeout = 0;
6719 fprintf(stdout, "Enter new timeout in seconds or press\n"
6720 "return to keep the current timeout [%d] ",
6721 use_timeout / 1000);
6723 if (fgets(str, sizeof(str), stdin) != NULL) {
6725 new_timeout = atoi(str);
6728 if (new_timeout != 0) {
6729 use_timeout = new_timeout * 1000;
6730 fprintf(stdout, "Using new timeout value %d\n",
6731 use_timeout / 1000);
6737 byte2 |= SSZ_UNRESTRICTED_EXIT;
6741 scsi_sanitize(&ccb->csio,
6742 /* retries */ retry_count,
6744 /* tag_action */ task_attr,
6747 /* data_ptr */ data_ptr,
6748 /* dxfer_len */ dxfer_len,
6749 /* sense_len */ SSD_FULL_SIZE,
6750 /* timeout */ use_timeout);
6752 /* Disable freezing the device queue */
6753 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6755 if (arglist & CAM_ARG_ERR_RECOVER)
6756 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6758 if (cam_send_ccb(device, ccb) < 0) {
6759 warn("error sending sanitize command");
6761 goto scsisanitize_bailout;
6764 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6765 struct scsi_sense_data *sense;
6766 int error_code, sense_key, asc, ascq;
6768 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6769 CAM_SCSI_STATUS_ERROR) {
6770 sense = &ccb->csio.sense_data;
6771 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6772 ccb->csio.sense_resid, &error_code, &sense_key,
6773 &asc, &ascq, /*show_errors*/ 1);
6775 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6776 asc == 0x20 && ascq == 0x00)
6777 warnx("sanitize is not supported by "
6780 warnx("error sanitizing this device");
6782 warnx("error sanitizing this device");
6784 if (arglist & CAM_ARG_VERBOSE) {
6785 cam_error_print(device, ccb, CAM_ESF_ALL,
6786 CAM_EPF_ALL, stderr);
6789 goto scsisanitize_bailout;
6793 * If we ran in non-immediate mode, we already checked for errors
6794 * above and printed out any necessary information. If we're in
6795 * immediate mode, we need to loop through and get status
6796 * information periodically.
6798 if (immediate == 0) {
6800 fprintf(stdout, "Sanitize Complete\n");
6802 goto scsisanitize_bailout;
6809 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6812 * There's really no need to do error recovery or
6813 * retries here, since we're just going to sit in a
6814 * loop and wait for the device to finish sanitizing.
6816 scsi_test_unit_ready(&ccb->csio,
6819 /* tag_action */ task_attr,
6820 /* sense_len */ SSD_FULL_SIZE,
6821 /* timeout */ 5000);
6823 /* Disable freezing the device queue */
6824 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6826 retval = cam_send_ccb(device, ccb);
6829 * If we get an error from the ioctl, bail out. SCSI
6830 * errors are expected.
6833 warn("error sending CAMIOCOMMAND ioctl");
6834 if (arglist & CAM_ARG_VERBOSE) {
6835 cam_error_print(device, ccb, CAM_ESF_ALL,
6836 CAM_EPF_ALL, stderr);
6839 goto scsisanitize_bailout;
6842 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6844 if ((status != CAM_REQ_CMP)
6845 && (status == CAM_SCSI_STATUS_ERROR)
6846 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6847 struct scsi_sense_data *sense;
6848 int error_code, sense_key, asc, ascq;
6850 sense = &ccb->csio.sense_data;
6851 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6852 ccb->csio.sense_resid, &error_code, &sense_key,
6853 &asc, &ascq, /*show_errors*/ 1);
6856 * According to the SCSI-3 spec, a drive that is in the
6857 * middle of a sanitize should return NOT READY with an
6858 * ASC of "logical unit not ready, sanitize in
6859 * progress". The sense key specific bytes will then
6860 * be a progress indicator.
6862 if ((sense_key == SSD_KEY_NOT_READY)
6863 && (asc == 0x04) && (ascq == 0x1b)) {
6866 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6867 ccb->csio.sense_resid, sks) == 0)
6870 u_int64_t percentage;
6872 val = scsi_2btoul(&sks[1]);
6873 percentage = 10000 * val;
6876 "\rSanitizing: %ju.%02u %% "
6878 (uintmax_t)(percentage /
6880 (unsigned)((percentage /
6884 } else if ((quiet == 0)
6885 && (++num_warnings <= 1)) {
6886 warnx("Unexpected SCSI Sense Key "
6887 "Specific value returned "
6888 "during sanitize:");
6889 scsi_sense_print(device, &ccb->csio,
6891 warnx("Unable to print status "
6892 "information, but sanitze will "
6894 warnx("will exit when sanitize is "
6899 warnx("Unexpected SCSI error during sanitize");
6900 cam_error_print(device, ccb, CAM_ESF_ALL,
6901 CAM_EPF_ALL, stderr);
6903 goto scsisanitize_bailout;
6906 } else if (status != CAM_REQ_CMP) {
6907 warnx("Unexpected CAM status %#x", status);
6908 if (arglist & CAM_ARG_VERBOSE)
6909 cam_error_print(device, ccb, CAM_ESF_ALL,
6910 CAM_EPF_ALL, stderr);
6912 goto scsisanitize_bailout;
6914 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6917 fprintf(stdout, "\nSanitize Complete\n");
6919 scsisanitize_bailout:
6922 if (data_ptr != NULL)
6930 scsireportluns(struct cam_device *device, int argc, char **argv,
6931 char *combinedopt, int task_attr, int retry_count, int timeout)
6934 int c, countonly, lunsonly;
6935 struct scsi_report_luns_data *lundata;
6937 uint8_t report_type;
6938 uint32_t list_len, i, j;
6943 report_type = RPL_REPORT_DEFAULT;
6944 ccb = cam_getccb(device);
6947 warnx("%s: error allocating ccb", __func__);
6951 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6956 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6965 if (strcasecmp(optarg, "default") == 0)
6966 report_type = RPL_REPORT_DEFAULT;
6967 else if (strcasecmp(optarg, "wellknown") == 0)
6968 report_type = RPL_REPORT_WELLKNOWN;
6969 else if (strcasecmp(optarg, "all") == 0)
6970 report_type = RPL_REPORT_ALL;
6972 warnx("%s: invalid report type \"%s\"",
6983 if ((countonly != 0)
6984 && (lunsonly != 0)) {
6985 warnx("%s: you can only specify one of -c or -l", __func__);
6990 * According to SPC-4, the allocation length must be at least 16
6991 * bytes -- enough for the header and one LUN.
6993 alloc_len = sizeof(*lundata) + 8;
6997 lundata = malloc(alloc_len);
6999 if (lundata == NULL) {
7000 warn("%s: error mallocing %d bytes", __func__, alloc_len);
7005 scsi_report_luns(&ccb->csio,
7006 /*retries*/ retry_count,
7008 /*tag_action*/ task_attr,
7009 /*select_report*/ report_type,
7010 /*rpl_buf*/ lundata,
7011 /*alloc_len*/ alloc_len,
7012 /*sense_len*/ SSD_FULL_SIZE,
7013 /*timeout*/ timeout ? timeout : 5000);
7015 /* Disable freezing the device queue */
7016 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7018 if (arglist & CAM_ARG_ERR_RECOVER)
7019 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7021 if (cam_send_ccb(device, ccb) < 0) {
7022 warn("error sending REPORT LUNS command");
7024 if (arglist & CAM_ARG_VERBOSE)
7025 cam_error_print(device, ccb, CAM_ESF_ALL,
7026 CAM_EPF_ALL, stderr);
7032 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7033 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7039 list_len = scsi_4btoul(lundata->length);
7042 * If we need to list the LUNs, and our allocation
7043 * length was too short, reallocate and retry.
7045 if ((countonly == 0)
7046 && (list_len > (alloc_len - sizeof(*lundata)))) {
7047 alloc_len = list_len + sizeof(*lundata);
7053 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7054 ((list_len / 8) > 1) ? "s" : "");
7059 for (i = 0; i < (list_len / 8); i++) {
7063 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7065 fprintf(stdout, ",");
7066 switch (lundata->luns[i].lundata[j] &
7067 RPL_LUNDATA_ATYP_MASK) {
7068 case RPL_LUNDATA_ATYP_PERIPH:
7069 if ((lundata->luns[i].lundata[j] &
7070 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7071 fprintf(stdout, "%d:",
7072 lundata->luns[i].lundata[j] &
7073 RPL_LUNDATA_PERIPH_BUS_MASK);
7075 && ((lundata->luns[i].lundata[j+2] &
7076 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7079 fprintf(stdout, "%d",
7080 lundata->luns[i].lundata[j+1]);
7082 case RPL_LUNDATA_ATYP_FLAT: {
7084 tmplun[0] = lundata->luns[i].lundata[j] &
7085 RPL_LUNDATA_FLAT_LUN_MASK;
7086 tmplun[1] = lundata->luns[i].lundata[j+1];
7088 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7092 case RPL_LUNDATA_ATYP_LUN:
7093 fprintf(stdout, "%d:%d:%d",
7094 (lundata->luns[i].lundata[j+1] &
7095 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7096 lundata->luns[i].lundata[j] &
7097 RPL_LUNDATA_LUN_TARG_MASK,
7098 lundata->luns[i].lundata[j+1] &
7099 RPL_LUNDATA_LUN_LUN_MASK);
7101 case RPL_LUNDATA_ATYP_EXTLUN: {
7102 int field_len_code, eam_code;
7104 eam_code = lundata->luns[i].lundata[j] &
7105 RPL_LUNDATA_EXT_EAM_MASK;
7106 field_len_code = (lundata->luns[i].lundata[j] &
7107 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7109 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7110 && (field_len_code == 0x00)) {
7111 fprintf(stdout, "%d",
7112 lundata->luns[i].lundata[j+1]);
7113 } else if ((eam_code ==
7114 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7115 && (field_len_code == 0x03)) {
7119 * This format takes up all 8 bytes.
7120 * If we aren't starting at offset 0,
7124 fprintf(stdout, "Invalid "
7127 "specified format", j);
7131 bzero(tmp_lun, sizeof(tmp_lun));
7132 bcopy(&lundata->luns[i].lundata[j+1],
7133 &tmp_lun[1], sizeof(tmp_lun) - 1);
7134 fprintf(stdout, "%#jx",
7135 (intmax_t)scsi_8btou64(tmp_lun));
7138 fprintf(stderr, "Unknown Extended LUN"
7139 "Address method %#x, length "
7140 "code %#x", eam_code,
7147 fprintf(stderr, "Unknown LUN address method "
7148 "%#x\n", lundata->luns[i].lundata[0] &
7149 RPL_LUNDATA_ATYP_MASK);
7153 * For the flat addressing method, there are no
7154 * other levels after it.
7159 fprintf(stdout, "\n");
7172 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7173 char *combinedopt, int task_attr, int retry_count, int timeout)
7176 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7177 struct scsi_read_capacity_data rcap;
7178 struct scsi_read_capacity_data_long rcaplong;
7193 ccb = cam_getccb(device);
7196 warnx("%s: error allocating ccb", __func__);
7200 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7202 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7232 if ((blocksizeonly != 0)
7233 && (numblocks != 0)) {
7234 warnx("%s: you can only specify one of -b or -N", __func__);
7239 if ((blocksizeonly != 0)
7240 && (sizeonly != 0)) {
7241 warnx("%s: you can only specify one of -b or -s", __func__);
7248 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7254 && (blocksizeonly != 0)) {
7255 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7263 scsi_read_capacity(&ccb->csio,
7264 /*retries*/ retry_count,
7266 /*tag_action*/ task_attr,
7269 /*timeout*/ timeout ? timeout : 5000);
7271 /* Disable freezing the device queue */
7272 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7274 if (arglist & CAM_ARG_ERR_RECOVER)
7275 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7277 if (cam_send_ccb(device, ccb) < 0) {
7278 warn("error sending READ CAPACITY command");
7280 if (arglist & CAM_ARG_VERBOSE)
7281 cam_error_print(device, ccb, CAM_ESF_ALL,
7282 CAM_EPF_ALL, stderr);
7288 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7289 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7294 maxsector = scsi_4btoul(rcap.addr);
7295 block_len = scsi_4btoul(rcap.length);
7298 * A last block of 2^32-1 means that the true capacity is over 2TB,
7299 * and we need to issue the long READ CAPACITY to get the real
7300 * capacity. Otherwise, we're all set.
7302 if (maxsector != 0xffffffff)
7306 scsi_read_capacity_16(&ccb->csio,
7307 /*retries*/ retry_count,
7309 /*tag_action*/ task_attr,
7313 /*rcap_buf*/ (uint8_t *)&rcaplong,
7314 /*rcap_buf_len*/ sizeof(rcaplong),
7315 /*sense_len*/ SSD_FULL_SIZE,
7316 /*timeout*/ timeout ? timeout : 5000);
7318 /* Disable freezing the device queue */
7319 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7321 if (arglist & CAM_ARG_ERR_RECOVER)
7322 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7324 if (cam_send_ccb(device, ccb) < 0) {
7325 warn("error sending READ CAPACITY (16) command");
7327 if (arglist & CAM_ARG_VERBOSE)
7328 cam_error_print(device, ccb, CAM_ESF_ALL,
7329 CAM_EPF_ALL, stderr);
7335 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7336 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7341 maxsector = scsi_8btou64(rcaplong.addr);
7342 block_len = scsi_4btoul(rcaplong.length);
7345 if (blocksizeonly == 0) {
7347 * Humanize implies !quiet, and also implies numblocks.
7349 if (humanize != 0) {
7354 tmpbytes = (maxsector + 1) * block_len;
7355 ret = humanize_number(tmpstr, sizeof(tmpstr),
7356 tmpbytes, "", HN_AUTOSCALE,
7359 HN_DIVISOR_1000 : 0));
7361 warnx("%s: humanize_number failed!", __func__);
7365 fprintf(stdout, "Device Size: %s%s", tmpstr,
7366 (sizeonly == 0) ? ", " : "\n");
7367 } else if (numblocks != 0) {
7368 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7369 "Blocks: " : "", (uintmax_t)maxsector + 1,
7370 (sizeonly == 0) ? ", " : "\n");
7372 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7373 "Last Block: " : "", (uintmax_t)maxsector,
7374 (sizeonly == 0) ? ", " : "\n");
7378 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7379 "Block Length: " : "", block_len, (quiet == 0) ?
7388 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7389 int retry_count, int timeout)
7393 uint8_t *smp_request = NULL, *smp_response = NULL;
7394 int request_size = 0, response_size = 0;
7395 int fd_request = 0, fd_response = 0;
7396 char *datastr = NULL;
7397 struct get_hook hook;
7402 * Note that at the moment we don't support sending SMP CCBs to
7403 * devices that aren't probed by CAM.
7405 ccb = cam_getccb(device);
7407 warnx("%s: error allocating CCB", __func__);
7411 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7413 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7416 arglist |= CAM_ARG_CMD_IN;
7417 response_size = strtol(optarg, NULL, 0);
7418 if (response_size <= 0) {
7419 warnx("invalid number of response bytes %d",
7422 goto smpcmd_bailout;
7424 hook.argc = argc - optind;
7425 hook.argv = argv + optind;
7428 datastr = cget(&hook, NULL);
7430 * If the user supplied "-" instead of a format, he
7431 * wants the data to be written to stdout.
7433 if ((datastr != NULL)
7434 && (datastr[0] == '-'))
7437 smp_response = (u_int8_t *)malloc(response_size);
7438 if (smp_response == NULL) {
7439 warn("can't malloc memory for SMP response");
7441 goto smpcmd_bailout;
7445 arglist |= CAM_ARG_CMD_OUT;
7446 request_size = strtol(optarg, NULL, 0);
7447 if (request_size <= 0) {
7448 warnx("invalid number of request bytes %d",
7451 goto smpcmd_bailout;
7453 hook.argc = argc - optind;
7454 hook.argv = argv + optind;
7456 datastr = cget(&hook, NULL);
7457 smp_request = (u_int8_t *)malloc(request_size);
7458 if (smp_request == NULL) {
7459 warn("can't malloc memory for SMP request");
7461 goto smpcmd_bailout;
7463 bzero(smp_request, request_size);
7465 * If the user supplied "-" instead of a format, he
7466 * wants the data to be read from stdin.
7468 if ((datastr != NULL)
7469 && (datastr[0] == '-'))
7472 buff_encode_visit(smp_request, request_size,
7483 * If fd_data is set, and we're writing to the device, we need to
7484 * read the data the user wants written from stdin.
7486 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7488 int amt_to_read = request_size;
7489 u_int8_t *buf_ptr = smp_request;
7491 for (amt_read = 0; amt_to_read > 0;
7492 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7493 if (amt_read == -1) {
7494 warn("error reading data from stdin");
7496 goto smpcmd_bailout;
7498 amt_to_read -= amt_read;
7499 buf_ptr += amt_read;
7503 if (((arglist & CAM_ARG_CMD_IN) == 0)
7504 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7505 warnx("%s: need both the request (-r) and response (-R) "
7506 "arguments", __func__);
7508 goto smpcmd_bailout;
7511 flags |= CAM_DEV_QFRZDIS;
7513 cam_fill_smpio(&ccb->smpio,
7514 /*retries*/ retry_count,
7517 /*smp_request*/ smp_request,
7518 /*smp_request_len*/ request_size,
7519 /*smp_response*/ smp_response,
7520 /*smp_response_len*/ response_size,
7521 /*timeout*/ timeout ? timeout : 5000);
7523 ccb->smpio.flags = SMP_FLAG_NONE;
7525 if (((retval = cam_send_ccb(device, ccb)) < 0)
7526 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7527 const char warnstr[] = "error sending command";
7534 if (arglist & CAM_ARG_VERBOSE) {
7535 cam_error_print(device, ccb, CAM_ESF_ALL,
7536 CAM_EPF_ALL, stderr);
7540 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7541 && (response_size > 0)) {
7542 if (fd_response == 0) {
7543 buff_decode_visit(smp_response, response_size,
7544 datastr, arg_put, NULL);
7545 fprintf(stdout, "\n");
7547 ssize_t amt_written;
7548 int amt_to_write = response_size;
7549 u_int8_t *buf_ptr = smp_response;
7551 for (amt_written = 0; (amt_to_write > 0) &&
7552 (amt_written = write(STDOUT_FILENO, buf_ptr,
7553 amt_to_write)) > 0;){
7554 amt_to_write -= amt_written;
7555 buf_ptr += amt_written;
7557 if (amt_written == -1) {
7558 warn("error writing data to stdout");
7560 goto smpcmd_bailout;
7561 } else if ((amt_written == 0)
7562 && (amt_to_write > 0)) {
7563 warnx("only wrote %u bytes out of %u",
7564 response_size - amt_to_write,
7573 if (smp_request != NULL)
7576 if (smp_response != NULL)
7583 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7584 int retry_count, int timeout)
7588 int32_t mmc_opcode = 0, mmc_arg = 0;
7589 int32_t mmc_flags = -1;
7592 int is_bw_4 = 0, is_bw_1 = 0;
7593 int is_highspeed = 0, is_stdspeed = 0;
7594 int is_info_request = 0;
7596 uint8_t mmc_data_byte = 0;
7598 /* For IO_RW_EXTENDED command */
7599 uint8_t *mmc_data = NULL;
7600 struct mmc_data mmc_d;
7601 int mmc_data_len = 0;
7604 * Note that at the moment we don't support sending SMP CCBs to
7605 * devices that aren't probed by CAM.
7607 ccb = cam_getccb(device);
7609 warnx("%s: error allocating CCB", __func__);
7613 bzero(&(&ccb->ccb_h)[1],
7614 sizeof(union ccb) - sizeof(struct ccb_hdr));
7616 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7625 if (!strcmp(optarg, "high"))
7631 is_info_request = 1;
7634 mmc_opcode = strtol(optarg, NULL, 0);
7635 if (mmc_opcode < 0) {
7636 warnx("invalid MMC opcode %d",
7639 goto mmccmd_bailout;
7643 mmc_arg = strtol(optarg, NULL, 0);
7645 warnx("invalid MMC arg %d",
7648 goto mmccmd_bailout;
7652 mmc_flags = strtol(optarg, NULL, 0);
7653 if (mmc_flags < 0) {
7654 warnx("invalid MMC flags %d",
7657 goto mmccmd_bailout;
7661 mmc_data_len = strtol(optarg, NULL, 0);
7662 if (mmc_data_len <= 0) {
7663 warnx("invalid MMC data len %d",
7666 goto mmccmd_bailout;
7673 mmc_data_byte = strtol(optarg, NULL, 0);
7679 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7681 /* If flags are left default, supply the right flags */
7683 switch (mmc_opcode) {
7684 case MMC_GO_IDLE_STATE:
7685 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7687 case IO_SEND_OP_COND:
7688 mmc_flags = MMC_RSP_R4;
7690 case SD_SEND_RELATIVE_ADDR:
7691 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7693 case MMC_SELECT_CARD:
7694 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7695 mmc_arg = mmc_arg << 16;
7697 case SD_IO_RW_DIRECT:
7698 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7699 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7701 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7703 case SD_IO_RW_EXTENDED:
7704 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7705 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7706 int len_arg = mmc_data_len;
7707 if (mmc_data_len == 512)
7711 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7713 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7716 mmc_flags = MMC_RSP_R1;
7720 // Switch bus width instead of sending IO command
7721 if (is_bw_4 || is_bw_1) {
7722 struct ccb_trans_settings_mmc *cts;
7723 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7724 ccb->ccb_h.flags = 0;
7725 cts = &ccb->cts.proto_specific.mmc;
7726 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7727 cts->ios_valid = MMC_BW;
7728 if (((retval = cam_send_ccb(device, ccb)) < 0)
7729 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7730 warn("Error sending command");
7732 printf("Parameters set OK\n");
7738 // Switch bus speed instead of sending IO command
7739 if (is_stdspeed || is_highspeed) {
7740 struct ccb_trans_settings_mmc *cts;
7741 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7742 ccb->ccb_h.flags = 0;
7743 cts = &ccb->cts.proto_specific.mmc;
7744 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
7745 cts->ios_valid = MMC_BT;
7746 if (((retval = cam_send_ccb(device, ccb)) < 0)
7747 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7748 warn("Error sending command");
7750 printf("Speed set OK (HS: %d)\n", is_highspeed);
7756 // Get information about controller and its settings
7757 if (is_info_request) {
7758 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
7759 ccb->ccb_h.flags = 0;
7760 struct ccb_trans_settings_mmc *cts;
7761 cts = &ccb->cts.proto_specific.mmc;
7762 if (((retval = cam_send_ccb(device, ccb)) < 0)
7763 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7764 warn("Error sending command");
7767 printf("Host controller information\n");
7768 printf("Host OCR: 0x%x\n", cts->host_ocr);
7769 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
7770 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
7771 printf("Supported bus width: ");
7772 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
7774 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
7776 printf("\nCurrent settings:\n");
7777 printf("Bus width: ");
7778 switch (cts->ios.bus_width) {
7789 printf("Freq: %d.%03d MHz%s\n",
7790 cts->ios.clock / 1000000,
7791 (cts->ios.clock / 1000) % 1000,
7792 cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : "");
7796 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
7798 if (mmc_data_len > 0) {
7799 flags |= CAM_DIR_IN;
7800 mmc_data = malloc(mmc_data_len);
7801 memset(mmc_data, 0, mmc_data_len);
7802 memset(&mmc_d, 0, sizeof(mmc_d));
7803 mmc_d.len = mmc_data_len;
7804 mmc_d.data = mmc_data;
7805 mmc_d.flags = MMC_DATA_READ;
7806 } else flags |= CAM_DIR_NONE;
7808 cam_fill_mmcio(&ccb->mmcio,
7809 /*retries*/ retry_count,
7812 /*mmc_opcode*/ mmc_opcode,
7813 /*mmc_arg*/ mmc_arg,
7814 /*mmc_flags*/ mmc_flags,
7815 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
7816 /*timeout*/ timeout ? timeout : 5000);
7818 if (((retval = cam_send_ccb(device, ccb)) < 0)
7819 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7820 const char warnstr[] = "error sending command";
7827 if (arglist & CAM_ARG_VERBOSE) {
7828 cam_error_print(device, ccb, CAM_ESF_ALL,
7829 CAM_EPF_ALL, stderr);
7833 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
7834 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
7835 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
7836 ccb->mmcio.cmd.resp[1],
7837 ccb->mmcio.cmd.resp[2],
7838 ccb->mmcio.cmd.resp[3]);
7840 switch (mmc_opcode) {
7841 case SD_IO_RW_DIRECT:
7842 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
7843 SD_R5_DATA(ccb->mmcio.cmd.resp),
7844 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
7846 case SD_IO_RW_EXTENDED:
7847 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
7848 hexdump(mmc_data, mmc_data_len, NULL, 0);
7850 case SD_SEND_RELATIVE_ADDR:
7851 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
7854 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
7861 if (mmc_data_len > 0 && mmc_data != NULL)
7868 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7869 char *combinedopt, int retry_count, int timeout)
7872 struct smp_report_general_request *request = NULL;
7873 struct smp_report_general_response *response = NULL;
7874 struct sbuf *sb = NULL;
7876 int c, long_response = 0;
7880 * Note that at the moment we don't support sending SMP CCBs to
7881 * devices that aren't probed by CAM.
7883 ccb = cam_getccb(device);
7885 warnx("%s: error allocating CCB", __func__);
7889 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7891 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7900 request = malloc(sizeof(*request));
7901 if (request == NULL) {
7902 warn("%s: unable to allocate %zd bytes", __func__,
7908 response = malloc(sizeof(*response));
7909 if (response == NULL) {
7910 warn("%s: unable to allocate %zd bytes", __func__,
7917 smp_report_general(&ccb->smpio,
7921 /*request_len*/ sizeof(*request),
7922 (uint8_t *)response,
7923 /*response_len*/ sizeof(*response),
7924 /*long_response*/ long_response,
7927 if (((retval = cam_send_ccb(device, ccb)) < 0)
7928 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7929 const char warnstr[] = "error sending command";
7936 if (arglist & CAM_ARG_VERBOSE) {
7937 cam_error_print(device, ccb, CAM_ESF_ALL,
7938 CAM_EPF_ALL, stderr);
7945 * If the device supports the long response bit, try again and see
7946 * if we can get all of the data.
7948 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7949 && (long_response == 0)) {
7950 ccb->ccb_h.status = CAM_REQ_INPROG;
7951 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7957 * XXX KDM detect and decode SMP errors here.
7959 sb = sbuf_new_auto();
7961 warnx("%s: error allocating sbuf", __func__);
7965 smp_report_general_sbuf(response, sizeof(*response), sb);
7967 if (sbuf_finish(sb) != 0) {
7968 warnx("%s: sbuf_finish", __func__);
7972 printf("%s", sbuf_data(sb));
7978 if (request != NULL)
7981 if (response != NULL)
7990 static struct camcontrol_opts phy_ops[] = {
7991 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7992 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7993 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7994 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7995 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7996 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7997 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7998 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7999 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
8004 smpphycontrol(struct cam_device *device, int argc, char **argv,
8005 char *combinedopt, int retry_count, int timeout)
8008 struct smp_phy_control_request *request = NULL;
8009 struct smp_phy_control_response *response = NULL;
8010 int long_response = 0;
8013 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
8015 uint64_t attached_dev_name = 0;
8016 int dev_name_set = 0;
8017 uint32_t min_plr = 0, max_plr = 0;
8018 uint32_t pp_timeout_val = 0;
8019 int slumber_partial = 0;
8020 int set_pp_timeout_val = 0;
8024 * Note that at the moment we don't support sending SMP CCBs to
8025 * devices that aren't probed by CAM.
8027 ccb = cam_getccb(device);
8029 warnx("%s: error allocating CCB", __func__);
8033 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8035 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8043 if (strcasecmp(optarg, "enable") == 0)
8045 else if (strcasecmp(optarg, "disable") == 0)
8048 warnx("%s: Invalid argument %s", __func__,
8055 slumber_partial |= enable <<
8056 SMP_PC_SAS_SLUMBER_SHIFT;
8059 slumber_partial |= enable <<
8060 SMP_PC_SAS_PARTIAL_SHIFT;
8063 slumber_partial |= enable <<
8064 SMP_PC_SATA_SLUMBER_SHIFT;
8067 slumber_partial |= enable <<
8068 SMP_PC_SATA_PARTIAL_SHIFT;
8071 warnx("%s: programmer error", __func__);
8074 break; /*NOTREACHED*/
8079 attached_dev_name = (uintmax_t)strtoumax(optarg,
8088 * We don't do extensive checking here, so this
8089 * will continue to work when new speeds come out.
8091 min_plr = strtoul(optarg, NULL, 0);
8093 || (min_plr > 0xf)) {
8094 warnx("%s: invalid link rate %x",
8102 * We don't do extensive checking here, so this
8103 * will continue to work when new speeds come out.
8105 max_plr = strtoul(optarg, NULL, 0);
8107 || (max_plr > 0xf)) {
8108 warnx("%s: invalid link rate %x",
8115 camcontrol_optret optreturn;
8116 cam_argmask argnums;
8119 if (phy_op_set != 0) {
8120 warnx("%s: only one phy operation argument "
8121 "(-o) allowed", __func__);
8129 * Allow the user to specify the phy operation
8130 * numerically, as well as with a name. This will
8131 * future-proof it a bit, so options that are added
8132 * in future specs can be used.
8134 if (isdigit(optarg[0])) {
8135 phy_operation = strtoul(optarg, NULL, 0);
8136 if ((phy_operation == 0)
8137 || (phy_operation > 0xff)) {
8138 warnx("%s: invalid phy operation %#x",
8139 __func__, phy_operation);
8145 optreturn = getoption(phy_ops, optarg, &phy_operation,
8148 if (optreturn == CC_OR_AMBIGUOUS) {
8149 warnx("%s: ambiguous option %s", __func__,
8154 } else if (optreturn == CC_OR_NOT_FOUND) {
8155 warnx("%s: option %s not found", __func__,
8167 pp_timeout_val = strtoul(optarg, NULL, 0);
8168 if (pp_timeout_val > 15) {
8169 warnx("%s: invalid partial pathway timeout "
8170 "value %u, need a value less than 16",
8171 __func__, pp_timeout_val);
8175 set_pp_timeout_val = 1;
8183 warnx("%s: a PHY (-p phy) argument is required",__func__);
8188 if (((dev_name_set != 0)
8189 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8190 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8191 && (dev_name_set == 0))) {
8192 warnx("%s: -d name and -o setdevname arguments both "
8193 "required to set device name", __func__);
8198 request = malloc(sizeof(*request));
8199 if (request == NULL) {
8200 warn("%s: unable to allocate %zd bytes", __func__,
8206 response = malloc(sizeof(*response));
8207 if (response == NULL) {
8208 warn("%s: unable to allocate %zd bytes", __func__,
8214 smp_phy_control(&ccb->smpio,
8219 (uint8_t *)response,
8222 /*expected_exp_change_count*/ 0,
8225 (set_pp_timeout_val != 0) ? 1 : 0,
8233 if (((retval = cam_send_ccb(device, ccb)) < 0)
8234 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8235 const char warnstr[] = "error sending command";
8242 if (arglist & CAM_ARG_VERBOSE) {
8244 * Use CAM_EPF_NORMAL so we only get one line of
8245 * SMP command decoding.
8247 cam_error_print(device, ccb, CAM_ESF_ALL,
8248 CAM_EPF_NORMAL, stderr);
8254 /* XXX KDM print out something here for success? */
8259 if (request != NULL)
8262 if (response != NULL)
8269 smpmaninfo(struct cam_device *device, int argc, char **argv,
8270 char *combinedopt, int retry_count, int timeout)
8273 struct smp_report_manuf_info_request request;
8274 struct smp_report_manuf_info_response response;
8275 struct sbuf *sb = NULL;
8276 int long_response = 0;
8281 * Note that at the moment we don't support sending SMP CCBs to
8282 * devices that aren't probed by CAM.
8284 ccb = cam_getccb(device);
8286 warnx("%s: error allocating CCB", __func__);
8290 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8292 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8301 bzero(&request, sizeof(request));
8302 bzero(&response, sizeof(response));
8304 smp_report_manuf_info(&ccb->smpio,
8309 (uint8_t *)&response,
8314 if (((retval = cam_send_ccb(device, ccb)) < 0)
8315 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8316 const char warnstr[] = "error sending command";
8323 if (arglist & CAM_ARG_VERBOSE) {
8324 cam_error_print(device, ccb, CAM_ESF_ALL,
8325 CAM_EPF_ALL, stderr);
8331 sb = sbuf_new_auto();
8333 warnx("%s: error allocating sbuf", __func__);
8337 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8339 if (sbuf_finish(sb) != 0) {
8340 warnx("%s: sbuf_finish", __func__);
8344 printf("%s", sbuf_data(sb));
8358 getdevid(struct cam_devitem *item)
8361 union ccb *ccb = NULL;
8363 struct cam_device *dev;
8365 dev = cam_open_btl(item->dev_match.path_id,
8366 item->dev_match.target_id,
8367 item->dev_match.target_lun, O_RDWR, NULL);
8370 warnx("%s", cam_errbuf);
8375 item->device_id_len = 0;
8377 ccb = cam_getccb(dev);
8379 warnx("%s: error allocating CCB", __func__);
8384 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8387 * On the first try, we just probe for the size of the data, and
8388 * then allocate that much memory and try again.
8391 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8392 ccb->ccb_h.flags = CAM_DIR_IN;
8393 ccb->cdai.flags = CDAI_FLAG_NONE;
8394 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8395 ccb->cdai.bufsiz = item->device_id_len;
8396 if (item->device_id_len != 0)
8397 ccb->cdai.buf = (uint8_t *)item->device_id;
8399 if (cam_send_ccb(dev, ccb) < 0) {
8400 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8405 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8406 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8411 if (item->device_id_len == 0) {
8413 * This is our first time through. Allocate the buffer,
8414 * and then go back to get the data.
8416 if (ccb->cdai.provsiz == 0) {
8417 warnx("%s: invalid .provsiz field returned with "
8418 "XPT_GDEV_ADVINFO CCB", __func__);
8422 item->device_id_len = ccb->cdai.provsiz;
8423 item->device_id = malloc(item->device_id_len);
8424 if (item->device_id == NULL) {
8425 warn("%s: unable to allocate %d bytes", __func__,
8426 item->device_id_len);
8430 ccb->ccb_h.status = CAM_REQ_INPROG;
8436 cam_close_device(dev);
8445 * XXX KDM merge this code with getdevtree()?
8448 buildbusdevlist(struct cam_devlist *devlist)
8451 int bufsize, fd = -1;
8452 struct dev_match_pattern *patterns;
8453 struct cam_devitem *item = NULL;
8454 int skip_device = 0;
8457 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8458 warn("couldn't open %s", XPT_DEVICE);
8462 bzero(&ccb, sizeof(union ccb));
8464 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8465 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8466 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8468 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8469 bufsize = sizeof(struct dev_match_result) * 100;
8470 ccb.cdm.match_buf_len = bufsize;
8471 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8472 if (ccb.cdm.matches == NULL) {
8473 warnx("can't malloc memory for matches");
8477 ccb.cdm.num_matches = 0;
8478 ccb.cdm.num_patterns = 2;
8479 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8480 ccb.cdm.num_patterns;
8482 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8483 if (patterns == NULL) {
8484 warnx("can't malloc memory for patterns");
8489 ccb.cdm.patterns = patterns;
8490 bzero(patterns, ccb.cdm.pattern_buf_len);
8492 patterns[0].type = DEV_MATCH_DEVICE;
8493 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8494 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8495 patterns[1].type = DEV_MATCH_PERIPH;
8496 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8497 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8500 * We do the ioctl multiple times if necessary, in case there are
8501 * more than 100 nodes in the EDT.
8506 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8507 warn("error sending CAMIOCOMMAND ioctl");
8512 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8513 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8514 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8515 warnx("got CAM error %#x, CDM error %d\n",
8516 ccb.ccb_h.status, ccb.cdm.status);
8521 for (i = 0; i < ccb.cdm.num_matches; i++) {
8522 switch (ccb.cdm.matches[i].type) {
8523 case DEV_MATCH_DEVICE: {
8524 struct device_match_result *dev_result;
8527 &ccb.cdm.matches[i].result.device_result;
8529 if (dev_result->flags &
8530 DEV_RESULT_UNCONFIGURED) {
8536 item = malloc(sizeof(*item));
8538 warn("%s: unable to allocate %zd bytes",
8539 __func__, sizeof(*item));
8543 bzero(item, sizeof(*item));
8544 bcopy(dev_result, &item->dev_match,
8545 sizeof(*dev_result));
8546 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8549 if (getdevid(item) != 0) {
8555 case DEV_MATCH_PERIPH: {
8556 struct periph_match_result *periph_result;
8559 &ccb.cdm.matches[i].result.periph_result;
8561 if (skip_device != 0)
8563 item->num_periphs++;
8564 item->periph_matches = realloc(
8565 item->periph_matches,
8567 sizeof(struct periph_match_result));
8568 if (item->periph_matches == NULL) {
8569 warn("%s: error allocating periph "
8574 bcopy(periph_result, &item->periph_matches[
8575 item->num_periphs - 1],
8576 sizeof(*periph_result));
8580 fprintf(stderr, "%s: unexpected match "
8581 "type %d\n", __func__,
8582 ccb.cdm.matches[i].type);
8585 break; /*NOTREACHED*/
8588 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8589 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8597 free(ccb.cdm.matches);
8600 freebusdevlist(devlist);
8606 freebusdevlist(struct cam_devlist *devlist)
8608 struct cam_devitem *item, *item2;
8610 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8611 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8613 free(item->device_id);
8614 free(item->periph_matches);
8619 static struct cam_devitem *
8620 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8622 struct cam_devitem *item;
8624 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8625 struct scsi_vpd_id_descriptor *idd;
8628 * XXX KDM look for LUN IDs as well?
8630 idd = scsi_get_devid(item->device_id,
8631 item->device_id_len,
8632 scsi_devid_is_sas_target);
8636 if (scsi_8btou64(idd->identifier) == sasaddr)
8644 smpphylist(struct cam_device *device, int argc, char **argv,
8645 char *combinedopt, int retry_count, int timeout)
8647 struct smp_report_general_request *rgrequest = NULL;
8648 struct smp_report_general_response *rgresponse = NULL;
8649 struct smp_discover_request *disrequest = NULL;
8650 struct smp_discover_response *disresponse = NULL;
8651 struct cam_devlist devlist;
8653 int long_response = 0;
8660 * Note that at the moment we don't support sending SMP CCBs to
8661 * devices that aren't probed by CAM.
8663 ccb = cam_getccb(device);
8665 warnx("%s: error allocating CCB", __func__);
8669 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8670 STAILQ_INIT(&devlist.dev_queue);
8672 rgrequest = malloc(sizeof(*rgrequest));
8673 if (rgrequest == NULL) {
8674 warn("%s: unable to allocate %zd bytes", __func__,
8675 sizeof(*rgrequest));
8680 rgresponse = malloc(sizeof(*rgresponse));
8681 if (rgresponse == NULL) {
8682 warn("%s: unable to allocate %zd bytes", __func__,
8683 sizeof(*rgresponse));
8688 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8701 smp_report_general(&ccb->smpio,
8705 /*request_len*/ sizeof(*rgrequest),
8706 (uint8_t *)rgresponse,
8707 /*response_len*/ sizeof(*rgresponse),
8708 /*long_response*/ long_response,
8711 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8713 if (((retval = cam_send_ccb(device, ccb)) < 0)
8714 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8715 const char warnstr[] = "error sending command";
8722 if (arglist & CAM_ARG_VERBOSE) {
8723 cam_error_print(device, ccb, CAM_ESF_ALL,
8724 CAM_EPF_ALL, stderr);
8730 num_phys = rgresponse->num_phys;
8732 if (num_phys == 0) {
8734 fprintf(stdout, "%s: No Phys reported\n", __func__);
8739 devlist.path_id = device->path_id;
8741 retval = buildbusdevlist(&devlist);
8746 fprintf(stdout, "%d PHYs:\n", num_phys);
8747 fprintf(stdout, "PHY Attached SAS Address\n");
8750 disrequest = malloc(sizeof(*disrequest));
8751 if (disrequest == NULL) {
8752 warn("%s: unable to allocate %zd bytes", __func__,
8753 sizeof(*disrequest));
8758 disresponse = malloc(sizeof(*disresponse));
8759 if (disresponse == NULL) {
8760 warn("%s: unable to allocate %zd bytes", __func__,
8761 sizeof(*disresponse));
8766 for (i = 0; i < num_phys; i++) {
8767 struct cam_devitem *item;
8768 struct device_match_result *dev_match;
8769 char vendor[16], product[48], revision[16];
8773 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8775 ccb->ccb_h.status = CAM_REQ_INPROG;
8776 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8778 smp_discover(&ccb->smpio,
8782 sizeof(*disrequest),
8783 (uint8_t *)disresponse,
8784 sizeof(*disresponse),
8786 /*ignore_zone_group*/ 0,
8790 if (((retval = cam_send_ccb(device, ccb)) < 0)
8791 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
8792 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
8793 const char warnstr[] = "error sending command";
8800 if (arglist & CAM_ARG_VERBOSE) {
8801 cam_error_print(device, ccb, CAM_ESF_ALL,
8802 CAM_EPF_ALL, stderr);
8808 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
8810 fprintf(stdout, "%3d <vacant>\n", i);
8814 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
8817 item = findsasdevice(&devlist,
8818 scsi_8btou64(disresponse->attached_sas_address));
8822 || (item != NULL)) {
8823 fprintf(stdout, "%3d 0x%016jx", i,
8824 (uintmax_t)scsi_8btou64(
8825 disresponse->attached_sas_address));
8827 fprintf(stdout, "\n");
8830 } else if (quiet != 0)
8833 dev_match = &item->dev_match;
8835 if (dev_match->protocol == PROTO_SCSI) {
8836 cam_strvis(vendor, dev_match->inq_data.vendor,
8837 sizeof(dev_match->inq_data.vendor),
8839 cam_strvis(product, dev_match->inq_data.product,
8840 sizeof(dev_match->inq_data.product),
8842 cam_strvis(revision, dev_match->inq_data.revision,
8843 sizeof(dev_match->inq_data.revision),
8845 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8847 } else if ((dev_match->protocol == PROTO_ATA)
8848 || (dev_match->protocol == PROTO_SATAPM)) {
8849 cam_strvis(product, dev_match->ident_data.model,
8850 sizeof(dev_match->ident_data.model),
8852 cam_strvis(revision, dev_match->ident_data.revision,
8853 sizeof(dev_match->ident_data.revision),
8855 sprintf(tmpstr, "<%s %s>", product, revision);
8857 sprintf(tmpstr, "<>");
8859 fprintf(stdout, " %-33s ", tmpstr);
8862 * If we have 0 periphs, that's a bug...
8864 if (item->num_periphs == 0) {
8865 fprintf(stdout, "\n");
8869 fprintf(stdout, "(");
8870 for (j = 0; j < item->num_periphs; j++) {
8872 fprintf(stdout, ",");
8874 fprintf(stdout, "%s%d",
8875 item->periph_matches[j].periph_name,
8876 item->periph_matches[j].unit_number);
8879 fprintf(stdout, ")\n");
8893 freebusdevlist(&devlist);
8899 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
8901 struct ata_res *res;
8903 res = &ccb->ataio.res;
8904 if (res->status & ATA_STATUS_ERROR) {
8905 if (arglist & CAM_ARG_VERBOSE) {
8906 cam_error_print(device, ccb, CAM_ESF_ALL,
8907 CAM_EPF_ALL, stderr);
8908 printf("error = 0x%02x, sector_count = 0x%04x, "
8909 "device = 0x%02x, status = 0x%02x\n",
8910 res->error, res->sector_count,
8911 res->device, res->status);
8917 if (arglist & CAM_ARG_VERBOSE) {
8918 fprintf(stdout, "%s%d: Raw native check power data:\n",
8919 device->device_name, device->dev_unit_num);
8920 /* res is 4 byte aligned */
8921 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
8923 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
8924 "status = 0x%02x\n", res->error, res->sector_count,
8925 res->device, res->status);
8928 printf("%s%d: ", device->device_name, device->dev_unit_num);
8929 switch (res->sector_count) {
8931 printf("Standby mode\n");
8934 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
8937 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
8940 printf("Idle mode\n");
8943 printf("Active or Idle mode\n");
8946 printf("Unknown mode 0x%02x\n", res->sector_count);
8954 atapm(struct cam_device *device, int argc, char **argv,
8955 char *combinedopt, int retry_count, int timeout)
8961 u_int8_t ata_flags = 0;
8964 ccb = cam_getccb(device);
8967 warnx("%s: error allocating ccb", __func__);
8971 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8980 if (strcmp(argv[1], "idle") == 0) {
8982 cmd = ATA_IDLE_IMMEDIATE;
8985 } else if (strcmp(argv[1], "standby") == 0) {
8987 cmd = ATA_STANDBY_IMMEDIATE;
8989 cmd = ATA_STANDBY_CMD;
8990 } else if (strcmp(argv[1], "powermode") == 0) {
8991 cmd = ATA_CHECK_POWER_MODE;
8992 ata_flags = AP_FLAG_CHK_COND;
9001 else if (t <= (240 * 5))
9003 else if (t <= (252 * 5))
9004 /* special encoding for 21 minutes */
9006 else if (t <= (11 * 30 * 60))
9007 sc = (t - 1) / (30 * 60) + 241;
9011 retval = ata_do_cmd(device,
9013 /*retries*/retry_count,
9014 /*flags*/CAM_DIR_NONE,
9015 /*protocol*/AP_PROTO_NON_DATA,
9016 /*ata_flags*/ata_flags,
9017 /*tag_action*/MSG_SIMPLE_Q_TAG,
9024 /*timeout*/timeout ? timeout : 30 * 1000,
9029 if (retval || cmd != ATA_CHECK_POWER_MODE)
9032 return (atapm_proc_resp(device, ccb));
9036 ataaxm(struct cam_device *device, int argc, char **argv,
9037 char *combinedopt, int retry_count, int timeout)
9045 ccb = cam_getccb(device);
9048 warnx("%s: error allocating ccb", __func__);
9052 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9062 if (strcmp(argv[1], "apm") == 0) {
9078 retval = ata_do_28bit_cmd(device,
9080 /*retries*/retry_count,
9081 /*flags*/CAM_DIR_NONE,
9082 /*protocol*/AP_PROTO_NON_DATA,
9083 /*tag_action*/MSG_SIMPLE_Q_TAG,
9084 /*command*/ATA_SETFEATURES,
9090 /*timeout*/timeout ? timeout : 30 * 1000,
9098 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9099 int show_sa_errors, int sa_set, int service_action,
9100 int timeout_desc, int task_attr, int retry_count, int timeout,
9101 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9103 union ccb *ccb = NULL;
9104 uint8_t *buf = NULL;
9105 uint32_t alloc_len = 0, num_opcodes;
9106 uint32_t valid_len = 0;
9107 uint32_t avail_len = 0;
9108 struct scsi_report_supported_opcodes_all *all_hdr;
9109 struct scsi_report_supported_opcodes_one *one;
9114 * Make it clear that we haven't yet allocated or filled anything.
9119 ccb = cam_getccb(device);
9121 warnx("couldn't allocate CCB");
9126 /* cam_getccb cleans up the header, caller has to zero the payload */
9127 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9129 if (opcode_set != 0) {
9130 options |= RSO_OPTIONS_OC;
9132 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9135 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9136 sizeof(struct scsi_report_supported_opcodes_descr));
9139 if (timeout_desc != 0) {
9140 options |= RSO_RCTD;
9141 alloc_len += num_opcodes *
9142 sizeof(struct scsi_report_supported_opcodes_timeout);
9146 options |= RSO_OPTIONS_OC_SA;
9147 if (show_sa_errors != 0)
9148 options &= ~RSO_OPTIONS_OC;
9157 buf = malloc(alloc_len);
9159 warn("Unable to allocate %u bytes", alloc_len);
9163 bzero(buf, alloc_len);
9165 scsi_report_supported_opcodes(&ccb->csio,
9166 /*retries*/ retry_count,
9168 /*tag_action*/ task_attr,
9169 /*options*/ options,
9170 /*req_opcode*/ opcode,
9171 /*req_service_action*/ service_action,
9173 /*dxfer_len*/ alloc_len,
9174 /*sense_len*/ SSD_FULL_SIZE,
9175 /*timeout*/ timeout ? timeout : 10000);
9177 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9179 if (retry_count != 0)
9180 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9182 if (cam_send_ccb(device, ccb) < 0) {
9183 perror("error sending REPORT SUPPORTED OPERATION CODES");
9188 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9189 if (verbosemode != 0)
9190 cam_error_print(device, ccb, CAM_ESF_ALL,
9191 CAM_EPF_ALL, stderr);
9196 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9198 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9199 && (valid_len >= sizeof(*all_hdr))) {
9200 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9201 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9202 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9203 && (valid_len >= sizeof(*one))) {
9204 uint32_t cdb_length;
9206 one = (struct scsi_report_supported_opcodes_one *)buf;
9207 cdb_length = scsi_2btoul(one->cdb_length);
9208 avail_len = sizeof(*one) + cdb_length;
9209 if (one->support & RSO_ONE_CTDP) {
9210 struct scsi_report_supported_opcodes_timeout *td;
9212 td = (struct scsi_report_supported_opcodes_timeout *)
9214 if (valid_len >= (avail_len + sizeof(td->length))) {
9215 avail_len += scsi_2btoul(td->length) +
9218 avail_len += sizeof(*td);
9224 * avail_len could be zero if we didn't get enough data back from
9225 * thet target to determine
9227 if ((avail_len != 0)
9228 && (avail_len > valid_len)) {
9229 alloc_len = avail_len;
9233 *fill_len = valid_len;
9245 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9246 int req_sa, uint8_t *buf, uint32_t valid_len)
9248 struct scsi_report_supported_opcodes_one *one;
9249 struct scsi_report_supported_opcodes_timeout *td;
9250 uint32_t cdb_len = 0, td_len = 0;
9251 const char *op_desc = NULL;
9255 one = (struct scsi_report_supported_opcodes_one *)buf;
9258 * If we don't have the full single opcode descriptor, no point in
9261 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9263 warnx("Only %u bytes returned, not enough to verify support",
9269 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9271 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9274 printf(", SA 0x%x", req_sa);
9277 switch (one->support & RSO_ONE_SUP_MASK) {
9278 case RSO_ONE_SUP_UNAVAIL:
9279 printf("No command support information currently available\n");
9281 case RSO_ONE_SUP_NOT_SUP:
9282 printf("Command not supported\n");
9285 break; /*NOTREACHED*/
9286 case RSO_ONE_SUP_AVAIL:
9287 printf("Command is supported, complies with a SCSI standard\n");
9289 case RSO_ONE_SUP_VENDOR:
9290 printf("Command is supported, vendor-specific "
9291 "implementation\n");
9294 printf("Unknown command support flags 0x%#x\n",
9295 one->support & RSO_ONE_SUP_MASK);
9300 * If we don't have the CDB length, it isn't exactly an error, the
9301 * command probably isn't supported.
9303 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9307 cdb_len = scsi_2btoul(one->cdb_length);
9310 * If our valid data doesn't include the full reported length,
9311 * return. The caller should have detected this and adjusted his
9312 * allocation length to get all of the available data.
9314 if (valid_len < sizeof(*one) + cdb_len) {
9320 * If all we have is the opcode, there is no point in printing out
9328 printf("CDB usage bitmap:");
9329 for (i = 0; i < cdb_len; i++) {
9330 printf(" %02x", one->cdb_usage[i]);
9335 * If we don't have a timeout descriptor, we're done.
9337 if ((one->support & RSO_ONE_CTDP) == 0)
9341 * If we don't have enough valid length to include the timeout
9342 * descriptor length, we're done.
9344 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9347 td = (struct scsi_report_supported_opcodes_timeout *)
9348 &buf[sizeof(*one) + cdb_len];
9349 td_len = scsi_2btoul(td->length);
9350 td_len += sizeof(td->length);
9353 * If we don't have the full timeout descriptor, we're done.
9355 if (td_len < sizeof(*td))
9359 * If we don't have enough valid length to contain the full timeout
9360 * descriptor, we're done.
9362 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9365 printf("Timeout information:\n");
9366 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9367 printf("Nominal timeout: %u seconds\n",
9368 scsi_4btoul(td->nominal_time));
9369 printf("Recommended timeout: %u seconds\n",
9370 scsi_4btoul(td->recommended_time));
9377 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9380 struct scsi_report_supported_opcodes_all *hdr;
9381 struct scsi_report_supported_opcodes_descr *desc;
9382 uint32_t avail_len = 0, used_len = 0;
9386 if (valid_len < sizeof(*hdr)) {
9387 warnx("%s: not enough returned data (%u bytes) opcode list",
9388 __func__, valid_len);
9392 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9393 avail_len = scsi_4btoul(hdr->length);
9394 avail_len += sizeof(hdr->length);
9396 * Take the lesser of the amount of data the drive claims is
9397 * available, and the amount of data the HBA says was returned.
9399 avail_len = MIN(avail_len, valid_len);
9401 used_len = sizeof(hdr->length);
9403 printf("%-6s %4s %8s ",
9404 "Opcode", "SA", "CDB len" );
9407 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9408 printf(" Description\n");
9410 while ((avail_len - used_len) > sizeof(*desc)) {
9411 struct scsi_report_supported_opcodes_timeout *td;
9413 const char *op_desc = NULL;
9415 cur_ptr = &buf[used_len];
9416 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9418 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9419 if (op_desc == NULL)
9420 op_desc = "UNKNOWN";
9422 printf("0x%02x %#4x %8u ", desc->opcode,
9423 scsi_2btoul(desc->service_action),
9424 scsi_2btoul(desc->cdb_length));
9426 used_len += sizeof(*desc);
9428 if ((desc->flags & RSO_CTDP) == 0) {
9429 printf(" %s\n", op_desc);
9434 * If we don't have enough space to fit a timeout
9435 * descriptor, then we're done.
9437 if (avail_len - used_len < sizeof(*td)) {
9438 used_len = avail_len;
9439 printf(" %s\n", op_desc);
9442 cur_ptr = &buf[used_len];
9443 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9444 td_len = scsi_2btoul(td->length);
9445 td_len += sizeof(td->length);
9449 * If the given timeout descriptor length is less than what
9450 * we understand, skip it.
9452 if (td_len < sizeof(*td)) {
9453 printf(" %s\n", op_desc);
9457 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9458 scsi_4btoul(td->nominal_time),
9459 scsi_4btoul(td->recommended_time), op_desc);
9466 scsiopcodes(struct cam_device *device, int argc, char **argv,
9467 char *combinedopt, int task_attr, int retry_count, int timeout,
9471 uint32_t opcode = 0, service_action = 0;
9472 int td_set = 0, opcode_set = 0, sa_set = 0;
9473 int show_sa_errors = 1;
9474 uint32_t valid_len = 0;
9475 uint8_t *buf = NULL;
9479 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9485 opcode = strtoul(optarg, &endptr, 0);
9486 if (*endptr != '\0') {
9487 warnx("Invalid opcode \"%s\", must be a number",
9492 if (opcode > 0xff) {
9493 warnx("Invalid opcode 0x%#x, must be between"
9494 "0 and 0xff inclusive", opcode);
9501 service_action = strtoul(optarg, &endptr, 0);
9502 if (*endptr != '\0') {
9503 warnx("Invalid service action \"%s\", must "
9504 "be a number", optarg);
9508 if (service_action > 0xffff) {
9509 warnx("Invalid service action 0x%#x, must "
9510 "be between 0 and 0xffff inclusive",
9525 && (opcode_set == 0)) {
9526 warnx("You must specify an opcode with -o if a service "
9531 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9532 sa_set, service_action, td_set, task_attr,
9533 retry_count, timeout, verbosemode, &valid_len,
9538 if ((opcode_set != 0)
9540 retval = scsiprintoneopcode(device, opcode, sa_set,
9541 service_action, buf, valid_len);
9543 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9554 scsireprobe(struct cam_device *device)
9559 ccb = cam_getccb(device);
9562 warnx("%s: error allocating ccb", __func__);
9566 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9568 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9570 if (cam_send_ccb(device, ccb) < 0) {
9571 warn("error sending XPT_REPROBE_LUN CCB");
9576 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9577 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9589 usage(int printlong)
9592 fprintf(printlong ? stdout : stderr,
9593 "usage: camcontrol <command> [device id][generic args][command args]\n"
9594 " camcontrol devlist [-b] [-v]\n"
9595 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9596 " camcontrol tur [dev_id][generic args]\n"
9597 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9598 " camcontrol identify [dev_id][generic args] [-v]\n"
9599 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9600 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9602 " camcontrol start [dev_id][generic args]\n"
9603 " camcontrol stop [dev_id][generic args]\n"
9604 " camcontrol load [dev_id][generic args]\n"
9605 " camcontrol eject [dev_id][generic args]\n"
9606 " camcontrol reprobe [dev_id][generic args]\n"
9607 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9608 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9609 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9610 " [-q][-s][-S offset][-X]\n"
9611 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9612 " [-P pagectl][-e | -b][-d]\n"
9613 " camcontrol cmd [dev_id][generic args]\n"
9614 " <-a cmd [args] | -c cmd [args]>\n"
9615 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9616 " camcontrol smpcmd [dev_id][generic args]\n"
9617 " <-r len fmt [args]> <-R len fmt [args]>\n"
9618 " camcontrol smprg [dev_id][generic args][-l]\n"
9619 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9620 " [-o operation][-d name][-m rate][-M rate]\n"
9621 " [-T pp_timeout][-a enable|disable]\n"
9622 " [-A enable|disable][-s enable|disable]\n"
9623 " [-S enable|disable]\n"
9624 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9625 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9626 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9627 " <all|bus[:target[:lun]]|off>\n"
9628 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9629 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9630 " [-D <enable|disable>][-M mode][-O offset]\n"
9631 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9632 " [-U][-W bus_width]\n"
9633 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9634 " camcontrol sanitize [dev_id][generic args]\n"
9635 " [-a overwrite|block|crypto|exitfailure]\n"
9636 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9638 " camcontrol idle [dev_id][generic args][-t time]\n"
9639 " camcontrol standby [dev_id][generic args][-t time]\n"
9640 " camcontrol sleep [dev_id][generic args]\n"
9641 " camcontrol powermode [dev_id][generic args]\n"
9642 " camcontrol apm [dev_id][generic args][-l level]\n"
9643 " camcontrol aam [dev_id][generic args][-l level]\n"
9644 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9646 " camcontrol security [dev_id][generic args]\n"
9647 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9648 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9649 " [-U <user|master>] [-y]\n"
9650 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9651 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9652 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9653 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9654 " [-s scope][-S][-T type][-U]\n"
9655 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9656 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9657 " [-p part][-s start][-T type][-V vol]\n"
9658 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9660 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9661 " [-o rep_opts] [-P print_opts]\n"
9662 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9663 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9664 " [-S power_src] [-T timer]\n"
9665 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9666 " <-s <-f format -T time | -U >>\n"
9667 " camcontrol devtype [dev_id]\n"
9669 " camcontrol help\n");
9673 "Specify one of the following options:\n"
9674 "devlist list all CAM devices\n"
9675 "periphlist list all CAM peripheral drivers attached to a device\n"
9676 "tur send a test unit ready to the named device\n"
9677 "inquiry send a SCSI inquiry command to the named device\n"
9678 "identify send a ATA identify command to the named device\n"
9679 "reportluns send a SCSI report luns command to the device\n"
9680 "readcap send a SCSI read capacity command to the device\n"
9681 "start send a Start Unit command to the device\n"
9682 "stop send a Stop Unit command to the device\n"
9683 "load send a Start Unit command to the device with the load bit set\n"
9684 "eject send a Stop Unit command to the device with the eject bit set\n"
9685 "reprobe update capacity information of the given device\n"
9686 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9687 "reset reset all buses, the given bus, bus:target:lun or device\n"
9688 "defects read the defect list of the specified device\n"
9689 "modepage display or edit (-e) the given mode page\n"
9690 "cmd send the given SCSI command, may need -i or -o as well\n"
9691 "smpcmd send the given SMP command, requires -o and -i\n"
9692 "smprg send the SMP Report General command\n"
9693 "smppc send the SMP PHY Control command, requires -p\n"
9694 "smpphylist display phys attached to a SAS expander\n"
9695 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9696 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9697 "tags report or set the number of transaction slots for a device\n"
9698 "negotiate report or set device negotiation parameters\n"
9699 "format send the SCSI FORMAT UNIT command to the named device\n"
9700 "sanitize send the SCSI SANITIZE command to the named device\n"
9701 "idle send the ATA IDLE command to the named device\n"
9702 "standby send the ATA STANDBY command to the named device\n"
9703 "sleep send the ATA SLEEP command to the named device\n"
9704 "powermode send the ATA CHECK POWER MODE command to the named device\n"
9705 "fwdownload program firmware of the named device with the given image\n"
9706 "security report or send ATA security commands to the named device\n"
9707 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9708 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9709 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9710 "zone manage Zoned Block (Shingled) devices\n"
9711 "epc send ATA Extended Power Conditions commands\n"
9712 "timestamp report or set the device's timestamp\n"
9713 "devtype report the type of device\n"
9714 "help this message\n"
9715 "Device Identifiers:\n"
9716 "bus:target specify the bus and target, lun defaults to 0\n"
9717 "bus:target:lun specify the bus, target and lun\n"
9718 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
9719 "Generic arguments:\n"
9720 "-v be verbose, print out sense information\n"
9721 "-t timeout command timeout in seconds, overrides default timeout\n"
9722 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
9723 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
9724 "-E have the kernel attempt to perform SCSI error recovery\n"
9725 "-C count specify the SCSI command retry count (needs -E to work)\n"
9726 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
9727 "modepage arguments:\n"
9728 "-l list all available mode pages\n"
9729 "-m page specify the mode page to view or edit\n"
9730 "-e edit the specified mode page\n"
9731 "-b force view to binary mode\n"
9732 "-d disable block descriptors for mode sense\n"
9733 "-P pgctl page control field 0-3\n"
9734 "defects arguments:\n"
9735 "-f format specify defect list format (block, bfi or phys)\n"
9736 "-G get the grown defect list\n"
9737 "-P get the permanent defect list\n"
9738 "inquiry arguments:\n"
9739 "-D get the standard inquiry data\n"
9740 "-S get the serial number\n"
9741 "-R get the transfer rate, etc.\n"
9742 "reportluns arguments:\n"
9743 "-c only report a count of available LUNs\n"
9744 "-l only print out luns, and not a count\n"
9745 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
9746 "readcap arguments\n"
9747 "-b only report the blocksize\n"
9748 "-h human readable device size, base 2\n"
9749 "-H human readable device size, base 10\n"
9750 "-N print the number of blocks instead of last block\n"
9751 "-q quiet, print numbers only\n"
9752 "-s only report the last block/device size\n"
9754 "-c cdb [args] specify the SCSI CDB\n"
9755 "-i len fmt specify input data and input data format\n"
9756 "-o len fmt [args] specify output data and output data fmt\n"
9757 "smpcmd arguments:\n"
9758 "-r len fmt [args] specify the SMP command to be sent\n"
9759 "-R len fmt [args] specify SMP response format\n"
9760 "smprg arguments:\n"
9761 "-l specify the long response format\n"
9762 "smppc arguments:\n"
9763 "-p phy specify the PHY to operate on\n"
9764 "-l specify the long request/response format\n"
9765 "-o operation specify the phy control operation\n"
9766 "-d name set the attached device name\n"
9767 "-m rate set the minimum physical link rate\n"
9768 "-M rate set the maximum physical link rate\n"
9769 "-T pp_timeout set the partial pathway timeout value\n"
9770 "-a enable|disable enable or disable SATA slumber\n"
9771 "-A enable|disable enable or disable SATA partial phy power\n"
9772 "-s enable|disable enable or disable SAS slumber\n"
9773 "-S enable|disable enable or disable SAS partial phy power\n"
9774 "smpphylist arguments:\n"
9775 "-l specify the long response format\n"
9776 "-q only print phys with attached devices\n"
9777 "smpmaninfo arguments:\n"
9778 "-l specify the long response format\n"
9779 "debug arguments:\n"
9780 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
9781 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
9782 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
9783 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
9785 "-N tags specify the number of tags to use for this device\n"
9786 "-q be quiet, don't report the number of tags\n"
9787 "-v report a number of tag-related parameters\n"
9788 "negotiate arguments:\n"
9789 "-a send a test unit ready after negotiation\n"
9790 "-c report/set current negotiation settings\n"
9791 "-D <arg> \"enable\" or \"disable\" disconnection\n"
9792 "-M mode set ATA mode\n"
9793 "-O offset set command delay offset\n"
9794 "-q be quiet, don't report anything\n"
9795 "-R syncrate synchronization rate in MHz\n"
9796 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
9797 "-U report/set user negotiation settings\n"
9798 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
9799 "-v also print a Path Inquiry CCB for the controller\n"
9800 "format arguments:\n"
9801 "-q be quiet, don't print status messages\n"
9802 "-r run in report only mode\n"
9803 "-w don't send immediate format command\n"
9804 "-y don't ask any questions\n"
9805 "sanitize arguments:\n"
9806 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
9807 "-c passes overwrite passes to perform (1 to 31)\n"
9808 "-I invert overwrite pattern after each pass\n"
9809 "-P pattern path to overwrite pattern file\n"
9810 "-q be quiet, don't print status messages\n"
9811 "-r run in report only mode\n"
9812 "-U run operation in unrestricted completion exit mode\n"
9813 "-w don't send immediate sanitize command\n"
9814 "-y don't ask any questions\n"
9815 "idle/standby arguments:\n"
9816 "-t <arg> number of seconds before respective state.\n"
9817 "fwdownload arguments:\n"
9818 "-f fw_image path to firmware image file\n"
9819 "-q don't print informational messages, only errors\n"
9820 "-s run in simulation mode\n"
9821 "-v print info for every firmware segment sent to device\n"
9822 "-y don't ask any questions\n"
9823 "security arguments:\n"
9824 "-d pwd disable security using the given password for the selected\n"
9826 "-e pwd erase the device using the given pwd for the selected user\n"
9827 "-f freeze the security configuration of the specified device\n"
9828 "-h pwd enhanced erase the device using the given pwd for the\n"
9830 "-k pwd unlock the device using the given pwd for the selected\n"
9832 "-l <high|maximum> specifies which security level to set: high or maximum\n"
9833 "-q be quiet, do not print any status messages\n"
9834 "-s pwd password the device (enable security) using the given\n"
9835 " pwd for the selected user\n"
9836 "-T timeout overrides the timeout (seconds) used for erase operation\n"
9837 "-U <user|master> specifies which user to set: user or master\n"
9838 "-y don't ask any questions\n"
9840 "-f freeze the HPA configuration of the device\n"
9841 "-l lock the HPA configuration of the device\n"
9842 "-P make the HPA max sectors persist\n"
9843 "-p pwd Set the HPA configuration password required for unlock\n"
9845 "-q be quiet, do not print any status messages\n"
9846 "-s sectors configures the maximum user accessible sectors of the\n"
9848 "-U pwd unlock the HPA configuration of the device\n"
9849 "-y don't ask any questions\n"
9850 "persist arguments:\n"
9851 "-i action specify read_keys, read_reservation, report_cap, or\n"
9852 " read_full_status\n"
9853 "-o action specify register, register_ignore, reserve, release,\n"
9854 " clear, preempt, preempt_abort, register_move, replace_lost\n"
9855 "-a set the All Target Ports (ALL_TG_PT) bit\n"
9856 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
9857 "-k key specify the Reservation Key\n"
9858 "-K sa_key specify the Service Action Reservation Key\n"
9859 "-p set the Activate Persist Through Power Loss bit\n"
9860 "-R rtp specify the Relative Target Port\n"
9861 "-s scope specify the scope: lun, extent, element or a number\n"
9862 "-S specify Transport ID for register, requires -I\n"
9863 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
9864 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
9865 "-U unregister the current initiator for register_move\n"
9866 "attrib arguments:\n"
9867 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
9869 "-w attr specify an attribute to write, one -w argument per attr\n"
9870 "-a attr_num only display this attribute number\n"
9871 "-c get cached attributes\n"
9872 "-e elem_addr request attributes for the given element in a changer\n"
9873 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
9874 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
9875 " field_none, field_desc, field_num, field_size, field_rw\n"
9876 "-p partition request attributes for the given partition\n"
9877 "-s start_attr request attributes starting at the given number\n"
9878 "-T elem_type specify the element type (used with -e)\n"
9879 "-V logical_vol specify the logical volume ID\n"
9880 "opcodes arguments:\n"
9881 "-o opcode specify the individual opcode to list\n"
9882 "-s service_action specify the service action for the opcode\n"
9883 "-N do not return SCSI error for unsupported SA\n"
9884 "-T request nominal and recommended timeout values\n"
9886 "-c cmd required: rz, open, close, finish, or rwp\n"
9887 "-a apply the action to all zones\n"
9888 "-l LBA specify the zone starting LBA\n"
9889 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
9890 " closed, full, ro, offline, reset, nonseq, nonwp\n"
9891 "-P print_opt report zones printing: normal, summary, script\n"
9893 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
9894 " source, status, list\n"
9895 "-d disable power mode (timer, state)\n"
9896 "-D delayed entry (goto)\n"
9897 "-e enable power mode (timer, state)\n"
9898 "-H hold power mode (goto)\n"
9899 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
9901 "-P only display power mode (status)\n"
9902 "-r rst_src restore settings from: default, saved (restore)\n"
9903 "-s save mode (timer, state, restore)\n"
9904 "-S power_src set power source: battery, nonbattery (source)\n"
9905 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
9906 "timestamp arguments:\n"
9907 "-r report the timestamp of the device\n"
9908 "-f format report the timestamp of the device with the given\n"
9909 " strftime(3) format string\n"
9910 "-m report the timestamp of the device as milliseconds since\n"
9911 " January 1st, 1970\n"
9912 "-U report the time with UTC instead of the local time zone\n"
9913 "-s set the timestamp of the device\n"
9914 "-f format the format of the time string passed into strptime(3)\n"
9915 "-T time the time value passed into strptime(3)\n"
9916 "-U set the timestamp of the device to UTC time\n"
9921 main(int argc, char **argv)
9924 char *device = NULL;
9926 struct cam_device *cam_dev = NULL;
9927 int timeout = 0, retry_count = 1;
9928 camcontrol_optret optreturn;
9930 const char *mainopt = "C:En:Q:t:u:v";
9931 const char *subopt = NULL;
9932 char combinedopt[256];
9933 int error = 0, optstart = 2;
9934 int task_attr = MSG_SIMPLE_Q_TAG;
9940 cmdlist = CAM_CMD_NONE;
9941 arglist = CAM_ARG_NONE;
9949 * Get the base option.
9951 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
9953 if (optreturn == CC_OR_AMBIGUOUS) {
9954 warnx("ambiguous option %s", argv[1]);
9957 } else if (optreturn == CC_OR_NOT_FOUND) {
9958 warnx("option %s not found", argv[1]);
9964 * Ahh, getopt(3) is a pain.
9966 * This is a gross hack. There really aren't many other good
9967 * options (excuse the pun) for parsing options in a situation like
9968 * this. getopt is kinda braindead, so you end up having to run
9969 * through the options twice, and give each invocation of getopt
9970 * the option string for the other invocation.
9972 * You would think that you could just have two groups of options.
9973 * The first group would get parsed by the first invocation of
9974 * getopt, and the second group would get parsed by the second
9975 * invocation of getopt. It doesn't quite work out that way. When
9976 * the first invocation of getopt finishes, it leaves optind pointing
9977 * to the argument _after_ the first argument in the second group.
9978 * So when the second invocation of getopt comes around, it doesn't
9979 * recognize the first argument it gets and then bails out.
9981 * A nice alternative would be to have a flag for getopt that says
9982 * "just keep parsing arguments even when you encounter an unknown
9983 * argument", but there isn't one. So there's no real clean way to
9984 * easily parse two sets of arguments without having one invocation
9985 * of getopt know about the other.
9987 * Without this hack, the first invocation of getopt would work as
9988 * long as the generic arguments are first, but the second invocation
9989 * (in the subfunction) would fail in one of two ways. In the case
9990 * where you don't set optreset, it would fail because optind may be
9991 * pointing to the argument after the one it should be pointing at.
9992 * In the case where you do set optreset, and reset optind, it would
9993 * fail because getopt would run into the first set of options, which
9994 * it doesn't understand.
9996 * All of this would "sort of" work if you could somehow figure out
9997 * whether optind had been incremented one option too far. The
9998 * mechanics of that, however, are more daunting than just giving
9999 * both invocations all of the expect options for either invocation.
10001 * Needless to say, I wouldn't mind if someone invented a better
10002 * (non-GPL!) command line parsing interface than getopt. I
10003 * wouldn't mind if someone added more knobs to getopt to make it
10004 * work better. Who knows, I may talk myself into doing it someday,
10005 * if the standards weenies let me. As it is, it just leads to
10006 * hackery like this and causes people to avoid it in some cases.
10008 * KDM, September 8th, 1998
10010 if (subopt != NULL)
10011 sprintf(combinedopt, "%s%s", mainopt, subopt);
10013 sprintf(combinedopt, "%s", mainopt);
10016 * For these options we do not parse optional device arguments and
10017 * we do not open a passthrough device.
10019 if ((cmdlist == CAM_CMD_RESCAN)
10020 || (cmdlist == CAM_CMD_RESET)
10021 || (cmdlist == CAM_CMD_DEVTREE)
10022 || (cmdlist == CAM_CMD_USAGE)
10023 || (cmdlist == CAM_CMD_DEBUG))
10027 && (argc > 2 && argv[2][0] != '-')) {
10031 if (isdigit(argv[2][0])) {
10032 /* device specified as bus:target[:lun] */
10033 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10035 errx(1, "numeric device specification must "
10036 "be either bus:target, or "
10038 /* default to 0 if lun was not specified */
10039 if ((arglist & CAM_ARG_LUN) == 0) {
10041 arglist |= CAM_ARG_LUN;
10045 if (cam_get_device(argv[2], name, sizeof name, &unit)
10047 errx(1, "%s", cam_errbuf);
10048 device = strdup(name);
10049 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10054 * Start getopt processing at argv[2/3], since we've already
10055 * accepted argv[1..2] as the command name, and as a possible
10061 * Now we run through the argument list looking for generic
10062 * options, and ignoring options that possibly belong to
10065 while ((c = getopt(argc, argv, combinedopt))!= -1){
10068 retry_count = strtol(optarg, NULL, 0);
10069 if (retry_count < 0)
10070 errx(1, "retry count %d is < 0",
10072 arglist |= CAM_ARG_RETRIES;
10075 arglist |= CAM_ARG_ERR_RECOVER;
10078 arglist |= CAM_ARG_DEVICE;
10080 while (isspace(*tstr) && (*tstr != '\0'))
10082 device = (char *)strdup(tstr);
10086 int table_entry = 0;
10089 while (isspace(*tstr) && (*tstr != '\0'))
10091 if (isdigit(*tstr)) {
10092 task_attr = strtol(tstr, &endptr, 0);
10093 if (*endptr != '\0') {
10094 errx(1, "Invalid queue option "
10099 scsi_nv_status status;
10101 table_size = sizeof(task_attrs) /
10102 sizeof(task_attrs[0]);
10103 status = scsi_get_nv(task_attrs,
10104 table_size, tstr, &table_entry,
10105 SCSI_NV_FLAG_IG_CASE);
10106 if (status == SCSI_NV_FOUND)
10107 task_attr = task_attrs[
10108 table_entry].value;
10110 errx(1, "%s option %s",
10111 (status == SCSI_NV_AMBIGUOUS)?
10112 "ambiguous" : "invalid",
10119 timeout = strtol(optarg, NULL, 0);
10121 errx(1, "invalid timeout %d", timeout);
10122 /* Convert the timeout from seconds to ms */
10124 arglist |= CAM_ARG_TIMEOUT;
10127 arglist |= CAM_ARG_UNIT;
10128 unit = strtol(optarg, NULL, 0);
10131 arglist |= CAM_ARG_VERBOSE;
10139 * For most commands we'll want to open the passthrough device
10140 * associated with the specified device. In the case of the rescan
10141 * commands, we don't use a passthrough device at all, just the
10142 * transport layer device.
10144 if (devopen == 1) {
10145 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10146 && (((arglist & CAM_ARG_DEVICE) == 0)
10147 || ((arglist & CAM_ARG_UNIT) == 0))) {
10148 errx(1, "subcommand \"%s\" requires a valid device "
10149 "identifier", argv[1]);
10152 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10153 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10154 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10156 errx(1,"%s", cam_errbuf);
10160 * Reset optind to 2, and reset getopt, so these routines can parse
10161 * the arguments again.
10167 case CAM_CMD_DEVLIST:
10168 error = getdevlist(cam_dev);
10171 error = atahpa(cam_dev, retry_count, timeout,
10172 argc, argv, combinedopt);
10174 case CAM_CMD_DEVTREE:
10175 error = getdevtree(argc, argv, combinedopt);
10177 case CAM_CMD_DEVTYPE:
10178 error = getdevtype(cam_dev);
10181 error = testunitready(cam_dev, task_attr, retry_count,
10184 case CAM_CMD_INQUIRY:
10185 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10186 task_attr, retry_count, timeout);
10188 case CAM_CMD_IDENTIFY:
10189 error = identify(cam_dev, retry_count, timeout);
10191 case CAM_CMD_STARTSTOP:
10192 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10193 arglist & CAM_ARG_EJECT, task_attr,
10194 retry_count, timeout);
10196 case CAM_CMD_RESCAN:
10197 error = dorescan_or_reset(argc, argv, 1);
10199 case CAM_CMD_RESET:
10200 error = dorescan_or_reset(argc, argv, 0);
10202 case CAM_CMD_READ_DEFECTS:
10203 error = readdefects(cam_dev, argc, argv, combinedopt,
10204 task_attr, retry_count, timeout);
10206 case CAM_CMD_MODE_PAGE:
10207 modepage(cam_dev, argc, argv, combinedopt,
10208 task_attr, retry_count, timeout);
10210 case CAM_CMD_SCSI_CMD:
10211 error = scsicmd(cam_dev, argc, argv, combinedopt,
10212 task_attr, retry_count, timeout);
10214 case CAM_CMD_MMCSD_CMD:
10215 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10216 retry_count, timeout);
10218 case CAM_CMD_SMP_CMD:
10219 error = smpcmd(cam_dev, argc, argv, combinedopt,
10220 retry_count, timeout);
10222 case CAM_CMD_SMP_RG:
10223 error = smpreportgeneral(cam_dev, argc, argv,
10224 combinedopt, retry_count,
10227 case CAM_CMD_SMP_PC:
10228 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10229 retry_count, timeout);
10231 case CAM_CMD_SMP_PHYLIST:
10232 error = smpphylist(cam_dev, argc, argv, combinedopt,
10233 retry_count, timeout);
10235 case CAM_CMD_SMP_MANINFO:
10236 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10237 retry_count, timeout);
10239 case CAM_CMD_DEBUG:
10240 error = camdebug(argc, argv, combinedopt);
10243 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10246 error = ratecontrol(cam_dev, task_attr, retry_count,
10247 timeout, argc, argv, combinedopt);
10249 case CAM_CMD_FORMAT:
10250 error = scsiformat(cam_dev, argc, argv,
10251 combinedopt, task_attr, retry_count,
10254 case CAM_CMD_REPORTLUNS:
10255 error = scsireportluns(cam_dev, argc, argv,
10256 combinedopt, task_attr,
10257 retry_count, timeout);
10259 case CAM_CMD_READCAP:
10260 error = scsireadcapacity(cam_dev, argc, argv,
10261 combinedopt, task_attr,
10262 retry_count, timeout);
10265 case CAM_CMD_STANDBY:
10266 case CAM_CMD_SLEEP:
10267 case CAM_CMD_POWER_MODE:
10268 error = atapm(cam_dev, argc, argv,
10269 combinedopt, retry_count, timeout);
10273 error = ataaxm(cam_dev, argc, argv,
10274 combinedopt, retry_count, timeout);
10276 case CAM_CMD_SECURITY:
10277 error = atasecurity(cam_dev, retry_count, timeout,
10278 argc, argv, combinedopt);
10280 case CAM_CMD_DOWNLOAD_FW:
10281 error = fwdownload(cam_dev, argc, argv, combinedopt,
10282 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10285 case CAM_CMD_SANITIZE:
10286 error = scsisanitize(cam_dev, argc, argv,
10287 combinedopt, task_attr,
10288 retry_count, timeout);
10290 case CAM_CMD_PERSIST:
10291 error = scsipersist(cam_dev, argc, argv, combinedopt,
10292 task_attr, retry_count, timeout,
10293 arglist & CAM_ARG_VERBOSE,
10294 arglist & CAM_ARG_ERR_RECOVER);
10296 case CAM_CMD_ATTRIB:
10297 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10298 task_attr, retry_count, timeout,
10299 arglist & CAM_ARG_VERBOSE,
10300 arglist & CAM_ARG_ERR_RECOVER);
10302 case CAM_CMD_OPCODES:
10303 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10304 task_attr, retry_count, timeout,
10305 arglist & CAM_ARG_VERBOSE);
10307 case CAM_CMD_REPROBE:
10308 error = scsireprobe(cam_dev);
10311 error = zone(cam_dev, argc, argv, combinedopt,
10312 task_attr, retry_count, timeout,
10313 arglist & CAM_ARG_VERBOSE);
10316 error = epc(cam_dev, argc, argv, combinedopt,
10317 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10319 case CAM_CMD_TIMESTAMP:
10320 error = timestamp(cam_dev, argc, argv, combinedopt,
10321 task_attr, retry_count, timeout,
10322 arglist & CAM_ARG_VERBOSE);
10324 case CAM_CMD_USAGE:
10333 if (cam_dev != NULL)
10334 cam_close_device(cam_dev);