2 * Copyright (c) 1997-2007 Kenneth D. Merry
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/ioctl.h>
33 #include <sys/stdint.h>
34 #include <sys/types.h>
36 #include <sys/endian.h>
55 #include <cam/cam_debug.h>
56 #include <cam/cam_ccb.h>
57 #include <cam/scsi/scsi_all.h>
58 #include <cam/scsi/scsi_da.h>
59 #include <cam/scsi/scsi_pass.h>
60 #include <cam/scsi/scsi_message.h>
61 #include <cam/scsi/smp_all.h>
62 #include <cam/ata/ata_all.h>
63 #include <cam/mmc/mmc_all.h>
65 #include "camcontrol.h"
67 #include "nvmecontrol_ext.h"
71 CAM_CMD_NONE = 0x00000000,
72 CAM_CMD_DEVLIST = 0x00000001,
73 CAM_CMD_TUR = 0x00000002,
74 CAM_CMD_INQUIRY = 0x00000003,
75 CAM_CMD_STARTSTOP = 0x00000004,
76 CAM_CMD_RESCAN = 0x00000005,
77 CAM_CMD_READ_DEFECTS = 0x00000006,
78 CAM_CMD_MODE_PAGE = 0x00000007,
79 CAM_CMD_SCSI_CMD = 0x00000008,
80 CAM_CMD_DEVTREE = 0x00000009,
81 CAM_CMD_USAGE = 0x0000000a,
82 CAM_CMD_DEBUG = 0x0000000b,
83 CAM_CMD_RESET = 0x0000000c,
84 CAM_CMD_FORMAT = 0x0000000d,
85 CAM_CMD_TAG = 0x0000000e,
86 CAM_CMD_RATE = 0x0000000f,
87 CAM_CMD_DETACH = 0x00000010,
88 CAM_CMD_REPORTLUNS = 0x00000011,
89 CAM_CMD_READCAP = 0x00000012,
90 CAM_CMD_IDENTIFY = 0x00000013,
91 CAM_CMD_IDLE = 0x00000014,
92 CAM_CMD_STANDBY = 0x00000015,
93 CAM_CMD_SLEEP = 0x00000016,
94 CAM_CMD_SMP_CMD = 0x00000017,
95 CAM_CMD_SMP_RG = 0x00000018,
96 CAM_CMD_SMP_PC = 0x00000019,
97 CAM_CMD_SMP_PHYLIST = 0x0000001a,
98 CAM_CMD_SMP_MANINFO = 0x0000001b,
99 CAM_CMD_DOWNLOAD_FW = 0x0000001c,
100 CAM_CMD_SECURITY = 0x0000001d,
101 CAM_CMD_HPA = 0x0000001e,
102 CAM_CMD_SANITIZE = 0x0000001f,
103 CAM_CMD_PERSIST = 0x00000020,
104 CAM_CMD_APM = 0x00000021,
105 CAM_CMD_AAM = 0x00000022,
106 CAM_CMD_ATTRIB = 0x00000023,
107 CAM_CMD_OPCODES = 0x00000024,
108 CAM_CMD_REPROBE = 0x00000025,
109 CAM_CMD_ZONE = 0x00000026,
110 CAM_CMD_EPC = 0x00000027,
111 CAM_CMD_TIMESTAMP = 0x00000028,
112 CAM_CMD_MMCSD_CMD = 0x00000029,
113 CAM_CMD_POWER_MODE = 0x0000002a,
114 CAM_CMD_DEVTYPE = 0x0000002b,
115 CAM_CMD_AMA = 0x0000002c,
119 CAM_ARG_NONE = 0x00000000,
120 CAM_ARG_VERBOSE = 0x00000001,
121 CAM_ARG_DEVICE = 0x00000002,
122 CAM_ARG_BUS = 0x00000004,
123 CAM_ARG_TARGET = 0x00000008,
124 CAM_ARG_LUN = 0x00000010,
125 CAM_ARG_EJECT = 0x00000020,
126 CAM_ARG_UNIT = 0x00000040,
127 CAM_ARG_FORMAT_BLOCK = 0x00000080,
128 CAM_ARG_FORMAT_BFI = 0x00000100,
129 CAM_ARG_FORMAT_PHYS = 0x00000200,
130 CAM_ARG_PLIST = 0x00000400,
131 CAM_ARG_GLIST = 0x00000800,
132 CAM_ARG_GET_SERIAL = 0x00001000,
133 CAM_ARG_GET_STDINQ = 0x00002000,
134 CAM_ARG_GET_XFERRATE = 0x00004000,
135 CAM_ARG_INQ_MASK = 0x00007000,
136 CAM_ARG_TIMEOUT = 0x00020000,
137 CAM_ARG_CMD_IN = 0x00040000,
138 CAM_ARG_CMD_OUT = 0x00080000,
139 CAM_ARG_ERR_RECOVER = 0x00200000,
140 CAM_ARG_RETRIES = 0x00400000,
141 CAM_ARG_START_UNIT = 0x00800000,
142 CAM_ARG_DEBUG_INFO = 0x01000000,
143 CAM_ARG_DEBUG_TRACE = 0x02000000,
144 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
145 CAM_ARG_DEBUG_CDB = 0x08000000,
146 CAM_ARG_DEBUG_XPT = 0x10000000,
147 CAM_ARG_DEBUG_PERIPH = 0x20000000,
148 CAM_ARG_DEBUG_PROBE = 0x40000000,
151 struct camcontrol_opts {
159 struct ata_set_max_pwd
162 u_int8_t password[32];
163 u_int16_t reserved2[239];
166 static struct scsi_nv task_attrs[] = {
167 { "simple", MSG_SIMPLE_Q_TAG },
168 { "head", MSG_HEAD_OF_Q_TAG },
169 { "ordered", MSG_ORDERED_Q_TAG },
170 { "iwr", MSG_IGN_WIDE_RESIDUE },
171 { "aca", MSG_ACA_TASK }
174 static const char scsicmd_opts[] = "a:c:dfi:o:r";
175 static const char readdefect_opts[] = "f:GPqsS:X";
176 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
177 static const char smprg_opts[] = "l";
178 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
179 static const char smpphylist_opts[] = "lq";
183 static struct camcontrol_opts option_table[] = {
185 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
186 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
187 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
188 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
189 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
190 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
191 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
192 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
193 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHlNqs"},
194 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
195 #endif /* MINIMALISTIC */
196 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
197 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
199 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
200 {"mmcsdcmd", CAM_CMD_MMCSD_CMD, CAM_ARG_NONE, "c:a:f:Wb:l:41S:I"},
201 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
202 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
203 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
204 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
205 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
206 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
207 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
208 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
209 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
210 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
211 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
212 #endif /* MINIMALISTIC */
213 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
214 {"devtype", CAM_CMD_DEVTYPE, CAM_ARG_NONE, ""},
216 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
217 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "6bdelm:DLP:"},
218 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
219 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
220 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
221 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
222 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
223 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
224 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
225 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
226 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
227 {"powermode", CAM_CMD_POWER_MODE, CAM_ARG_NONE, ""},
228 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
229 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
230 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
231 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
232 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
233 {"ama", CAM_CMD_AMA, CAM_ARG_NONE, "fqs:"},
234 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
235 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
236 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
237 {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
238 {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
239 {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
240 #endif /* MINIMALISTIC */
241 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
242 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
243 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
248 struct device_match_result dev_match;
250 struct periph_match_result *periph_matches;
251 struct scsi_vpd_device_id *device_id;
253 STAILQ_ENTRY(cam_devitem) links;
257 STAILQ_HEAD(, cam_devitem) dev_queue;
261 static cam_cmdmask cmdlist;
262 static cam_argmask arglist;
264 static const char *devtype_names[] = {
274 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
275 uint32_t *cmdnum, cam_argmask *argnum,
276 const char **subopt);
278 static int getdevlist(struct cam_device *device);
279 #endif /* MINIMALISTIC */
280 static int getdevtree(int argc, char **argv, char *combinedopt);
281 static int getdevtype(struct cam_device *device);
282 static int print_dev_scsi(struct device_match_result *dev_result, char *tmpstr);
283 static int print_dev_ata(struct device_match_result *dev_result, char *tmpstr);
284 static int print_dev_semb(struct device_match_result *dev_result, char *tmpstr);
285 static int print_dev_mmcsd(struct device_match_result *dev_result,
288 static int print_dev_nvme(struct device_match_result *dev_result, char *tmpstr);
291 static int testunitready(struct cam_device *device, int task_attr,
292 int retry_count, int timeout, int quiet);
293 static int scsistart(struct cam_device *device, int startstop, int loadeject,
294 int task_attr, int retry_count, int timeout);
295 static int scsiinquiry(struct cam_device *device, int task_attr,
296 int retry_count, int timeout);
297 static int scsiserial(struct cam_device *device, int task_attr,
298 int retry_count, int timeout);
299 #endif /* MINIMALISTIC */
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 reprobe(struct cam_device *device);
303 static int dorescan_or_reset(int argc, char **argv, int rescan);
304 static int rescan_or_reset_bus(path_id_t bus, int rescan);
305 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
306 lun_id_t lun, int scan);
308 static int readdefects(struct cam_device *device, int argc, char **argv,
309 char *combinedopt, int task_attr, int retry_count,
311 static void modepage(struct cam_device *device, int argc, char **argv,
312 char *combinedopt, int task_attr, int retry_count,
314 static int scsicmd(struct cam_device *device, int argc, char **argv,
315 char *combinedopt, int task_attr, int retry_count,
317 static int smpcmd(struct cam_device *device, int argc, char **argv,
318 char *combinedopt, int retry_count, int timeout);
319 static int mmcsdcmd(struct cam_device *device, int argc, char **argv,
320 char *combinedopt, int retry_count, int timeout);
321 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
322 char *combinedopt, int retry_count, int timeout);
323 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
324 char *combinedopt, int retry_count, int timeout);
325 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
326 char *combinedopt, int retry_count, int timeout);
327 static int getdevid(struct cam_devitem *item);
328 static int buildbusdevlist(struct cam_devlist *devlist);
329 static void freebusdevlist(struct cam_devlist *devlist);
330 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
332 static int smpphylist(struct cam_device *device, int argc, char **argv,
333 char *combinedopt, int retry_count, int timeout);
334 static int tagcontrol(struct cam_device *device, int argc, char **argv,
336 static void cts_print(struct cam_device *device,
337 struct ccb_trans_settings *cts);
338 static void cpi_print(struct ccb_pathinq *cpi);
339 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
340 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
341 static int get_print_cts(struct cam_device *device, int user_settings,
342 int quiet, struct ccb_trans_settings *cts);
343 static int ratecontrol(struct cam_device *device, int task_attr,
344 int retry_count, int timeout, int argc, char **argv,
346 static int scsiformat(struct cam_device *device, int argc, char **argv,
347 char *combinedopt, int task_attr, int retry_count,
349 static int sanitize(struct cam_device *device, int argc, char **argv,
350 char *combinedopt, int task_attr, int retry_count,
352 static int scsireportluns(struct cam_device *device, int argc, char **argv,
353 char *combinedopt, int task_attr, int retry_count,
355 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
356 char *combinedopt, int task_attr, int retry_count,
358 static int atapm(struct cam_device *device, int argc, char **argv,
359 char *combinedopt, int retry_count, int timeout);
360 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
361 int argc, char **argv, char *combinedopt);
362 static int atahpa(struct cam_device *device, int retry_count, int timeout,
363 int argc, char **argv, char *combinedopt);
364 static int ataama(struct cam_device *device, int retry_count, int timeout,
365 int argc, char **argv, char *combinedopt);
366 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
367 int sa_set, int req_sa, uint8_t *buf,
369 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
371 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
372 char *combinedopt, int task_attr, int retry_count,
373 int timeout, int verbose);
375 #endif /* MINIMALISTIC */
377 #define min(a,b) (((a)<(b))?(a):(b))
380 #define max(a,b) (((a)>(b))?(a):(b))
384 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
385 cam_argmask *argnum, const char **subopt)
387 struct camcontrol_opts *opts;
390 for (opts = table; (opts != NULL) && (opts->optname != NULL);
392 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
393 *cmdnum = opts->cmdnum;
394 *argnum = opts->argnum;
395 *subopt = opts->subopt;
396 if (++num_matches > 1)
397 return (CC_OR_AMBIGUOUS);
402 return (CC_OR_FOUND);
404 return (CC_OR_NOT_FOUND);
409 getdevlist(struct cam_device *device)
415 ccb = cam_getccb(device);
417 ccb->ccb_h.func_code = XPT_GDEVLIST;
418 ccb->ccb_h.flags = CAM_DIR_NONE;
419 ccb->ccb_h.retry_count = 1;
421 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
422 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
423 if (cam_send_ccb(device, ccb) < 0) {
424 warn("error getting device list");
431 switch (ccb->cgdl.status) {
432 case CAM_GDEVLIST_MORE_DEVS:
433 strcpy(status, "MORE");
435 case CAM_GDEVLIST_LAST_DEVICE:
436 strcpy(status, "LAST");
438 case CAM_GDEVLIST_LIST_CHANGED:
439 strcpy(status, "CHANGED");
441 case CAM_GDEVLIST_ERROR:
442 strcpy(status, "ERROR");
447 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
448 ccb->cgdl.periph_name,
449 ccb->cgdl.unit_number,
450 ccb->cgdl.generation,
455 * If the list has changed, we need to start over from the
458 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
466 #endif /* MINIMALISTIC */
469 getdevtree(int argc, char **argv, char *combinedopt)
480 while ((c = getopt(argc, argv, combinedopt)) != -1) {
483 if ((arglist & CAM_ARG_VERBOSE) == 0)
491 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
492 warn("couldn't open %s", XPT_DEVICE);
496 bzero(&ccb, sizeof(union ccb));
498 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
499 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
500 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
502 ccb.ccb_h.func_code = XPT_DEV_MATCH;
503 bufsize = sizeof(struct dev_match_result) * 100;
504 ccb.cdm.match_buf_len = bufsize;
505 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
506 if (ccb.cdm.matches == NULL) {
507 warnx("can't malloc memory for matches");
511 ccb.cdm.num_matches = 0;
514 * We fetch all nodes, since we display most of them in the default
515 * case, and all in the verbose case.
517 ccb.cdm.num_patterns = 0;
518 ccb.cdm.pattern_buf_len = 0;
521 * We do the ioctl multiple times if necessary, in case there are
522 * more than 100 nodes in the EDT.
525 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
526 warn("error sending CAMIOCOMMAND ioctl");
531 if ((ccb.ccb_h.status != CAM_REQ_CMP)
532 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
533 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
534 warnx("got CAM error %#x, CDM error %d\n",
535 ccb.ccb_h.status, ccb.cdm.status);
540 for (i = 0; i < ccb.cdm.num_matches; i++) {
541 switch (ccb.cdm.matches[i].type) {
542 case DEV_MATCH_BUS: {
543 struct bus_match_result *bus_result;
546 * Only print the bus information if the
547 * user turns on the verbose flag.
549 if ((busonly == 0) &&
550 (arglist & CAM_ARG_VERBOSE) == 0)
554 &ccb.cdm.matches[i].result.bus_result;
557 fprintf(stdout, ")\n");
561 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
563 bus_result->dev_name,
564 bus_result->unit_number,
566 (busonly ? "" : ":"));
569 case DEV_MATCH_DEVICE: {
570 struct device_match_result *dev_result;
577 &ccb.cdm.matches[i].result.device_result;
579 if ((dev_result->flags
580 & DEV_RESULT_UNCONFIGURED)
581 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
587 if (dev_result->protocol == PROTO_SCSI) {
588 if (print_dev_scsi(dev_result,
593 } else if (dev_result->protocol == PROTO_ATA ||
594 dev_result->protocol == PROTO_SATAPM) {
595 if (print_dev_ata(dev_result,
600 } else if (dev_result->protocol == PROTO_MMCSD){
601 if (print_dev_mmcsd(dev_result,
606 } else if (dev_result->protocol == PROTO_SEMB) {
607 if (print_dev_semb(dev_result,
613 } else if (dev_result->protocol == PROTO_NVME) {
614 if (print_dev_nvme(dev_result,
621 sprintf(tmpstr, "<>");
624 fprintf(stdout, ")\n");
628 fprintf(stdout, "%-33s at scbus%d "
629 "target %d lun %jx (",
632 dev_result->target_id,
633 (uintmax_t)dev_result->target_lun);
639 case DEV_MATCH_PERIPH: {
640 struct periph_match_result *periph_result;
643 &ccb.cdm.matches[i].result.periph_result;
645 if (busonly || skip_device != 0)
649 fprintf(stdout, ",");
651 fprintf(stdout, "%s%d",
652 periph_result->periph_name,
653 periph_result->unit_number);
659 fprintf(stdout, "unknown match type\n");
664 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
665 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
668 fprintf(stdout, ")\n");
676 getdevtype(struct cam_device *cam_dev)
678 camcontrol_devtype dt;
682 * Get the device type and report it, request no I/O be done to do this.
684 error = get_device_type(cam_dev, -1, 0, 0, &dt);
685 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
686 fprintf(stdout, "illegal\n");
689 fprintf(stdout, "%s\n", devtype_names[dt]);
694 print_dev_scsi(struct device_match_result *dev_result, char *tmpstr)
696 char vendor[16], product[48], revision[16];
698 cam_strvis(vendor, dev_result->inq_data.vendor,
699 sizeof(dev_result->inq_data.vendor), sizeof(vendor));
700 cam_strvis(product, dev_result->inq_data.product,
701 sizeof(dev_result->inq_data.product), sizeof(product));
702 cam_strvis(revision, dev_result->inq_data.revision,
703 sizeof(dev_result->inq_data.revision), sizeof(revision));
704 sprintf(tmpstr, "<%s %s %s>", vendor, product, revision);
710 print_dev_ata(struct device_match_result *dev_result, char *tmpstr)
712 char product[48], revision[16];
714 cam_strvis(product, dev_result->ident_data.model,
715 sizeof(dev_result->ident_data.model), sizeof(product));
716 cam_strvis(revision, dev_result->ident_data.revision,
717 sizeof(dev_result->ident_data.revision), sizeof(revision));
718 sprintf(tmpstr, "<%s %s>", product, revision);
724 print_dev_semb(struct device_match_result *dev_result, char *tmpstr)
726 struct sep_identify_data *sid;
727 char vendor[16], product[48], revision[16], fw[5];
729 sid = (struct sep_identify_data *)&dev_result->ident_data;
730 cam_strvis(vendor, sid->vendor_id,
731 sizeof(sid->vendor_id), sizeof(vendor));
732 cam_strvis(product, sid->product_id,
733 sizeof(sid->product_id), sizeof(product));
734 cam_strvis(revision, sid->product_rev,
735 sizeof(sid->product_rev), sizeof(revision));
736 cam_strvis(fw, sid->firmware_rev,
737 sizeof(sid->firmware_rev), sizeof(fw));
738 sprintf(tmpstr, "<%s %s %s %s>", vendor, product, revision, fw);
744 print_dev_mmcsd(struct device_match_result *dev_result, char *tmpstr)
747 struct ccb_dev_advinfo *advi;
748 struct cam_device *dev;
749 struct mmc_params mmc_ident_data;
751 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
752 dev_result->target_lun, O_RDWR, NULL);
754 warnx("%s", cam_errbuf);
758 ccb = cam_getccb(dev);
760 warnx("couldn't allocate CCB");
761 cam_close_device(dev);
766 advi->ccb_h.flags = CAM_DIR_IN;
767 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
768 advi->flags = CDAI_FLAG_NONE;
769 advi->buftype = CDAI_TYPE_MMC_PARAMS;
770 advi->bufsiz = sizeof(struct mmc_params);
771 advi->buf = (uint8_t *)&mmc_ident_data;
773 if (cam_send_ccb(dev, ccb) < 0) {
774 warn("error sending XPT_DEV_ADVINFO CCB");
776 cam_close_device(dev);
780 if (strlen(mmc_ident_data.model) > 0) {
781 sprintf(tmpstr, "<%s>", mmc_ident_data.model);
783 sprintf(tmpstr, "<%s card>",
784 mmc_ident_data.card_features &
785 CARD_FEATURE_SDIO ? "SDIO" : "unknown");
789 cam_close_device(dev);
795 nvme_get_cdata(struct cam_device *dev, struct nvme_controller_data *cdata)
798 struct ccb_dev_advinfo *advi;
800 ccb = cam_getccb(dev);
802 warnx("couldn't allocate CCB");
803 cam_close_device(dev);
808 advi->ccb_h.flags = CAM_DIR_IN;
809 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
810 advi->flags = CDAI_FLAG_NONE;
811 advi->buftype = CDAI_TYPE_NVME_CNTRL;
812 advi->bufsiz = sizeof(struct nvme_controller_data);
813 advi->buf = (uint8_t *)cdata;
815 if (cam_send_ccb(dev, ccb) < 0) {
816 warn("error sending XPT_DEV_ADVINFO CCB");
818 cam_close_device(dev);
821 if (advi->ccb_h.status != CAM_REQ_CMP) {
822 warnx("got CAM error %#x", advi->ccb_h.status);
824 cam_close_device(dev);
832 print_dev_nvme(struct device_match_result *dev_result, char *tmpstr)
834 struct cam_device *dev;
835 struct nvme_controller_data cdata;
836 char vendor[64], product[64];
838 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
839 dev_result->target_lun, O_RDWR, NULL);
841 warnx("%s", cam_errbuf);
845 if (nvme_get_cdata(dev, &cdata))
848 cam_strvis(vendor, cdata.mn, sizeof(cdata.mn), sizeof(vendor));
849 cam_strvis(product, cdata.fr, sizeof(cdata.fr), sizeof(product));
850 sprintf(tmpstr, "<%s %s>", vendor, product);
852 cam_close_device(dev);
859 testunitready(struct cam_device *device, int task_attr, int retry_count,
860 int timeout, int quiet)
865 ccb = cam_getccb(device);
867 scsi_test_unit_ready(&ccb->csio,
868 /* retries */ retry_count,
870 /* tag_action */ task_attr,
871 /* sense_len */ SSD_FULL_SIZE,
872 /* timeout */ timeout ? timeout : 5000);
874 /* Disable freezing the device queue */
875 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
877 if (arglist & CAM_ARG_ERR_RECOVER)
878 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
880 if (cam_send_ccb(device, ccb) < 0) {
882 warn("error sending TEST UNIT READY command");
887 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
889 fprintf(stdout, "Unit is ready\n");
892 fprintf(stdout, "Unit is not ready\n");
895 if (arglist & CAM_ARG_VERBOSE) {
896 cam_error_print(device, ccb, CAM_ESF_ALL,
897 CAM_EPF_ALL, stderr);
907 scsistart(struct cam_device *device, int startstop, int loadeject,
908 int task_attr, int retry_count, int timeout)
913 ccb = cam_getccb(device);
916 * If we're stopping, send an ordered tag so the drive in question
917 * will finish any previously queued writes before stopping. If
918 * the device isn't capable of tagged queueing, or if tagged
919 * queueing is turned off, the tag action is a no-op. We override
920 * the default simple tag, although this also has the effect of
921 * overriding the user's wishes if he wanted to specify a simple
925 && (task_attr == MSG_SIMPLE_Q_TAG))
926 task_attr = MSG_ORDERED_Q_TAG;
928 scsi_start_stop(&ccb->csio,
929 /* retries */ retry_count,
931 /* tag_action */ task_attr,
932 /* start/stop */ startstop,
933 /* load_eject */ loadeject,
935 /* sense_len */ SSD_FULL_SIZE,
936 /* timeout */ timeout ? timeout : 120000);
938 /* Disable freezing the device queue */
939 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
941 if (arglist & CAM_ARG_ERR_RECOVER)
942 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
944 if (cam_send_ccb(device, ccb) < 0) {
945 warn("error sending START STOP UNIT command");
950 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
952 fprintf(stdout, "Unit started successfully");
954 fprintf(stdout,", Media loaded\n");
956 fprintf(stdout,"\n");
958 fprintf(stdout, "Unit stopped successfully");
960 fprintf(stdout, ", Media ejected\n");
962 fprintf(stdout, "\n");
968 "Error received from start unit command\n");
971 "Error received from stop unit command\n");
973 if (arglist & CAM_ARG_VERBOSE) {
974 cam_error_print(device, ccb, CAM_ESF_ALL,
975 CAM_EPF_ALL, stderr);
985 scsidoinquiry(struct cam_device *device, int argc, char **argv,
986 char *combinedopt, int task_attr, int retry_count, int timeout)
991 while ((c = getopt(argc, argv, combinedopt)) != -1) {
994 arglist |= CAM_ARG_GET_STDINQ;
997 arglist |= CAM_ARG_GET_XFERRATE;
1000 arglist |= CAM_ARG_GET_SERIAL;
1008 * If the user didn't specify any inquiry options, he wants all of
1011 if ((arglist & CAM_ARG_INQ_MASK) == 0)
1012 arglist |= CAM_ARG_INQ_MASK;
1014 if (arglist & CAM_ARG_GET_STDINQ)
1015 error = scsiinquiry(device, task_attr, retry_count, timeout);
1020 if (arglist & CAM_ARG_GET_SERIAL)
1021 scsiserial(device, task_attr, retry_count, timeout);
1023 if (arglist & CAM_ARG_GET_XFERRATE)
1024 error = camxferrate(device);
1030 scsiinquiry(struct cam_device *device, int task_attr, int retry_count,
1034 struct scsi_inquiry_data *inq_buf;
1037 ccb = cam_getccb(device);
1040 warnx("couldn't allocate CCB");
1044 /* cam_getccb cleans up the header, caller has to zero the payload */
1045 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1047 inq_buf = (struct scsi_inquiry_data *)malloc(
1048 sizeof(struct scsi_inquiry_data));
1050 if (inq_buf == NULL) {
1052 warnx("can't malloc memory for inquiry\n");
1055 bzero(inq_buf, sizeof(*inq_buf));
1058 * Note that although the size of the inquiry buffer is the full
1059 * 256 bytes specified in the SCSI spec, we only tell the device
1060 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
1061 * two reasons for this:
1063 * - The SCSI spec says that when a length field is only 1 byte,
1064 * a value of 0 will be interpreted as 256. Therefore
1065 * scsi_inquiry() will convert an inq_len (which is passed in as
1066 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
1067 * to 0. Evidently, very few devices meet the spec in that
1068 * regard. Some devices, like many Seagate disks, take the 0 as
1069 * 0, and don't return any data. One Pioneer DVD-R drive
1070 * returns more data than the command asked for.
1072 * So, since there are numerous devices that just don't work
1073 * right with the full inquiry size, we don't send the full size.
1075 * - The second reason not to use the full inquiry data length is
1076 * that we don't need it here. The only reason we issue a
1077 * standard inquiry is to get the vendor name, device name,
1078 * and revision so scsi_print_inquiry() can print them.
1080 * If, at some point in the future, more inquiry data is needed for
1081 * some reason, this code should use a procedure similar to the
1082 * probe code. i.e., issue a short inquiry, and determine from
1083 * the additional length passed back from the device how much
1084 * inquiry data the device supports. Once the amount the device
1085 * supports is determined, issue an inquiry for that amount and no
1090 scsi_inquiry(&ccb->csio,
1091 /* retries */ retry_count,
1093 /* tag_action */ task_attr,
1094 /* inq_buf */ (u_int8_t *)inq_buf,
1095 /* inq_len */ SHORT_INQUIRY_LENGTH,
1098 /* sense_len */ SSD_FULL_SIZE,
1099 /* timeout */ timeout ? timeout : 5000);
1101 /* Disable freezing the device queue */
1102 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1104 if (arglist & CAM_ARG_ERR_RECOVER)
1105 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1107 if (cam_send_ccb(device, ccb) < 0) {
1108 warn("error sending INQUIRY command");
1113 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1116 if (arglist & CAM_ARG_VERBOSE) {
1117 cam_error_print(device, ccb, CAM_ESF_ALL,
1118 CAM_EPF_ALL, stderr);
1129 fprintf(stdout, "%s%d: ", device->device_name,
1130 device->dev_unit_num);
1131 scsi_print_inquiry(inq_buf);
1139 scsiserial(struct cam_device *device, int task_attr, int retry_count,
1143 struct scsi_vpd_unit_serial_number *serial_buf;
1144 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
1147 ccb = cam_getccb(device);
1150 warnx("couldn't allocate CCB");
1154 /* cam_getccb cleans up the header, caller has to zero the payload */
1155 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1157 serial_buf = (struct scsi_vpd_unit_serial_number *)
1158 malloc(sizeof(*serial_buf));
1160 if (serial_buf == NULL) {
1162 warnx("can't malloc memory for serial number");
1166 scsi_inquiry(&ccb->csio,
1167 /*retries*/ retry_count,
1169 /* tag_action */ task_attr,
1170 /* inq_buf */ (u_int8_t *)serial_buf,
1171 /* inq_len */ sizeof(*serial_buf),
1173 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
1174 /* sense_len */ SSD_FULL_SIZE,
1175 /* timeout */ timeout ? timeout : 5000);
1177 /* Disable freezing the device queue */
1178 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1180 if (arglist & CAM_ARG_ERR_RECOVER)
1181 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1183 if (cam_send_ccb(device, ccb) < 0) {
1184 warn("error sending INQUIRY command");
1190 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1193 if (arglist & CAM_ARG_VERBOSE) {
1194 cam_error_print(device, ccb, CAM_ESF_ALL,
1195 CAM_EPF_ALL, stderr);
1206 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1207 serial_num[serial_buf->length] = '\0';
1209 if ((arglist & CAM_ARG_GET_STDINQ)
1210 || (arglist & CAM_ARG_GET_XFERRATE))
1211 fprintf(stdout, "%s%d: Serial Number ",
1212 device->device_name, device->dev_unit_num);
1214 fprintf(stdout, "%.60s\n", serial_num);
1222 camxferrate(struct cam_device *device)
1224 struct ccb_pathinq cpi;
1226 u_int32_t speed = 0;
1231 if ((retval = get_cpi(device, &cpi)) != 0)
1234 ccb = cam_getccb(device);
1237 warnx("couldn't allocate CCB");
1241 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
1243 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1244 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1246 if (((retval = cam_send_ccb(device, ccb)) < 0)
1247 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1248 const char error_string[] = "error getting transfer settings";
1253 warnx(error_string);
1255 if (arglist & CAM_ARG_VERBOSE)
1256 cam_error_print(device, ccb, CAM_ESF_ALL,
1257 CAM_EPF_ALL, stderr);
1261 goto xferrate_bailout;
1265 speed = cpi.base_transfer_speed;
1267 if (ccb->cts.transport == XPORT_SPI) {
1268 struct ccb_trans_settings_spi *spi =
1269 &ccb->cts.xport_specific.spi;
1271 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1272 freq = scsi_calc_syncsrate(spi->sync_period);
1275 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1276 speed *= (0x01 << spi->bus_width);
1278 } else if (ccb->cts.transport == XPORT_FC) {
1279 struct ccb_trans_settings_fc *fc =
1280 &ccb->cts.xport_specific.fc;
1282 if (fc->valid & CTS_FC_VALID_SPEED)
1283 speed = fc->bitrate;
1284 } else if (ccb->cts.transport == XPORT_SAS) {
1285 struct ccb_trans_settings_sas *sas =
1286 &ccb->cts.xport_specific.sas;
1288 if (sas->valid & CTS_SAS_VALID_SPEED)
1289 speed = sas->bitrate;
1290 } else if (ccb->cts.transport == XPORT_ATA) {
1291 struct ccb_trans_settings_pata *pata =
1292 &ccb->cts.xport_specific.ata;
1294 if (pata->valid & CTS_ATA_VALID_MODE)
1295 speed = ata_mode2speed(pata->mode);
1296 } else if (ccb->cts.transport == XPORT_SATA) {
1297 struct ccb_trans_settings_sata *sata =
1298 &ccb->cts.xport_specific.sata;
1300 if (sata->valid & CTS_SATA_VALID_REVISION)
1301 speed = ata_revision2speed(sata->revision);
1306 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1307 device->device_name, device->dev_unit_num,
1310 fprintf(stdout, "%s%d: %dKB/s transfers",
1311 device->device_name, device->dev_unit_num,
1315 if (ccb->cts.transport == XPORT_SPI) {
1316 struct ccb_trans_settings_spi *spi =
1317 &ccb->cts.xport_specific.spi;
1319 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1320 && (spi->sync_offset != 0))
1321 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1322 freq % 1000, spi->sync_offset);
1324 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1325 && (spi->bus_width > 0)) {
1326 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1327 && (spi->sync_offset != 0)) {
1328 fprintf(stdout, ", ");
1330 fprintf(stdout, " (");
1332 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1333 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1334 && (spi->sync_offset != 0)) {
1335 fprintf(stdout, ")");
1337 } else if (ccb->cts.transport == XPORT_ATA) {
1338 struct ccb_trans_settings_pata *pata =
1339 &ccb->cts.xport_specific.ata;
1342 if (pata->valid & CTS_ATA_VALID_MODE)
1343 printf("%s, ", ata_mode2string(pata->mode));
1344 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1345 printf("ATAPI %dbytes, ", pata->atapi);
1346 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1347 printf("PIO %dbytes", pata->bytecount);
1349 } else if (ccb->cts.transport == XPORT_SATA) {
1350 struct ccb_trans_settings_sata *sata =
1351 &ccb->cts.xport_specific.sata;
1354 if (sata->valid & CTS_SATA_VALID_REVISION)
1355 printf("SATA %d.x, ", sata->revision);
1358 if (sata->valid & CTS_SATA_VALID_MODE)
1359 printf("%s, ", ata_mode2string(sata->mode));
1360 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1361 printf("ATAPI %dbytes, ", sata->atapi);
1362 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1363 printf("PIO %dbytes", sata->bytecount);
1367 if (ccb->cts.protocol == PROTO_SCSI) {
1368 struct ccb_trans_settings_scsi *scsi =
1369 &ccb->cts.proto_specific.scsi;
1370 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1371 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1372 fprintf(stdout, ", Command Queueing Enabled");
1377 fprintf(stdout, "\n");
1387 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1389 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1390 ((u_int32_t)parm->lba_size_2 << 16);
1392 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1393 ((u_int64_t)parm->lba_size48_2 << 16) |
1394 ((u_int64_t)parm->lba_size48_3 << 32) |
1395 ((u_int64_t)parm->lba_size48_4 << 48);
1399 "Support Enabled Value\n");
1402 printf("Host Protected Area (HPA) ");
1403 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1404 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1405 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1408 printf("HPA - Security ");
1409 if (parm->support.command2 & ATA_SUPPORT_MAXSECURITY)
1410 printf("yes %s\n", (parm->enabled.command2 &
1411 ATA_SUPPORT_MAXSECURITY) ? "yes" : "no ");
1420 ataama_print(struct ata_params *parm, u_int64_t nativesize, int header)
1422 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1423 ((u_int32_t)parm->lba_size_2 << 16);
1425 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1426 ((u_int64_t)parm->lba_size48_2 << 16) |
1427 ((u_int64_t)parm->lba_size48_3 << 32) |
1428 ((u_int64_t)parm->lba_size48_4 << 48);
1432 "Support Enabled Value\n");
1435 printf("Accessible Max Address Config ");
1436 if (parm->support2 & ATA_SUPPORT_AMAX_ADDR) {
1437 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1438 printf("yes %s %ju/%ju\n",
1439 (nativesize > lba) ? "yes" : "no ", lba, nativesize);
1446 atasata(struct ata_params *parm)
1450 if (parm->satacapabilities != 0xffff &&
1451 parm->satacapabilities != 0x0000)
1458 atacapprint(struct ata_params *parm)
1461 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1462 ((u_int32_t)parm->lba_size_2 << 16);
1464 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1465 ((u_int64_t)parm->lba_size48_2 << 16) |
1466 ((u_int64_t)parm->lba_size48_3 << 32) |
1467 ((u_int64_t)parm->lba_size48_4 << 48);
1470 printf("protocol ");
1471 proto = (parm->config == ATA_PROTO_CFA) ? "CFA" :
1472 (parm->config & ATA_PROTO_ATAPI) ? "ATAPI" : "ATA";
1473 if (ata_version(parm->version_major) == 0) {
1474 printf("%s", proto);
1475 } else if (ata_version(parm->version_major) <= 7) {
1476 printf("%s-%d", proto,
1477 ata_version(parm->version_major));
1478 } else if (ata_version(parm->version_major) == 8) {
1479 printf("%s8-ACS", proto);
1482 ata_version(parm->version_major) - 7, proto);
1484 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1485 if (parm->satacapabilities & ATA_SATA_GEN3)
1486 printf(" SATA 3.x\n");
1487 else if (parm->satacapabilities & ATA_SATA_GEN2)
1488 printf(" SATA 2.x\n");
1489 else if (parm->satacapabilities & ATA_SATA_GEN1)
1490 printf(" SATA 1.x\n");
1496 printf("device model %.40s\n", parm->model);
1497 printf("firmware revision %.8s\n", parm->revision);
1498 printf("serial number %.20s\n", parm->serial);
1499 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1500 printf("WWN %04x%04x%04x%04x\n",
1501 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1503 printf("additional product id %.8s\n", parm->product_id);
1504 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1505 printf("media serial number %.30s\n",
1506 parm->media_serial);
1509 printf("cylinders %d\n", parm->cylinders);
1510 printf("heads %d\n", parm->heads);
1511 printf("sectors/track %d\n", parm->sectors);
1512 printf("sector size logical %u, physical %lu, offset %lu\n",
1513 ata_logical_sector_size(parm),
1514 (unsigned long)ata_physical_sector_size(parm),
1515 (unsigned long)ata_logical_sector_offset(parm));
1517 if (parm->config == ATA_PROTO_CFA ||
1518 (parm->support.command2 & ATA_SUPPORT_CFA))
1519 printf("CFA supported\n");
1521 printf("LBA%ssupported ",
1522 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1524 printf("%d sectors\n", lbasize);
1528 printf("LBA48%ssupported ",
1529 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1531 printf("%ju sectors\n", (uintmax_t)lbasize48);
1535 printf("PIO supported PIO");
1536 switch (ata_max_pmode(parm)) {
1552 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1553 printf(" w/o IORDY");
1556 printf("DMA%ssupported ",
1557 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1558 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1559 if (parm->mwdmamodes & 0xff) {
1561 if (parm->mwdmamodes & 0x04)
1563 else if (parm->mwdmamodes & 0x02)
1565 else if (parm->mwdmamodes & 0x01)
1569 if ((parm->atavalid & ATA_FLAG_88) &&
1570 (parm->udmamodes & 0xff)) {
1572 if (parm->udmamodes & 0x40)
1574 else if (parm->udmamodes & 0x20)
1576 else if (parm->udmamodes & 0x10)
1578 else if (parm->udmamodes & 0x08)
1580 else if (parm->udmamodes & 0x04)
1582 else if (parm->udmamodes & 0x02)
1584 else if (parm->udmamodes & 0x01)
1591 if (parm->media_rotation_rate == 1) {
1592 printf("media RPM non-rotating\n");
1593 } else if (parm->media_rotation_rate >= 0x0401 &&
1594 parm->media_rotation_rate <= 0xFFFE) {
1595 printf("media RPM %d\n",
1596 parm->media_rotation_rate);
1599 printf("Zoned-Device Commands ");
1600 switch (parm->support3 & ATA_SUPPORT_ZONE_MASK) {
1601 case ATA_SUPPORT_ZONE_DEV_MANAGED:
1602 printf("device managed\n");
1604 case ATA_SUPPORT_ZONE_HOST_AWARE:
1605 printf("host aware\n");
1612 "Support Enabled Value Vendor\n");
1613 printf("read ahead %s %s\n",
1614 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1615 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1616 printf("write cache %s %s\n",
1617 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1618 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1619 printf("flush cache %s %s\n",
1620 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1621 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1622 printf("Native Command Queuing (NCQ) ");
1623 if (atasata(parm) && (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1624 printf("yes %d tags\n",
1625 ATA_QUEUE_LEN(parm->queue) + 1);
1626 printf("NCQ Priority Information %s\n",
1627 parm->satacapabilities & ATA_SUPPORT_NCQ_PRIO ?
1629 printf("NCQ Non-Data Command %s\n",
1630 parm->satacapabilities2 & ATA_SUPPORT_NCQ_NON_DATA ?
1632 printf("NCQ Streaming %s\n",
1633 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1635 printf("Receive & Send FPDMA Queued %s\n",
1636 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1638 printf("NCQ Autosense %s\n",
1639 parm->satasupport & ATA_SUPPORT_NCQ_AUTOSENSE ?
1644 printf("SMART %s %s\n",
1645 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1646 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1647 printf("security %s %s\n",
1648 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1649 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1650 printf("power management %s %s\n",
1651 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1652 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1653 printf("microcode download %s %s\n",
1654 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1655 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1656 printf("advanced power management %s %s",
1657 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1658 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1659 if (parm->support.command2 & ATA_SUPPORT_APM) {
1660 printf(" %d/0x%02X\n",
1661 parm->apm_value & 0xff, parm->apm_value & 0xff);
1664 printf("automatic acoustic management %s %s",
1665 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1666 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1667 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1668 printf(" %d/0x%02X %d/0x%02X\n",
1669 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1670 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1671 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1672 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1675 printf("media status notification %s %s\n",
1676 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1677 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1678 printf("power-up in Standby %s %s\n",
1679 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1680 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1681 printf("write-read-verify %s %s",
1682 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1683 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1684 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1685 printf(" %d/0x%x\n",
1686 parm->wrv_mode, parm->wrv_mode);
1689 printf("unload %s %s\n",
1690 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1691 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1692 printf("general purpose logging %s %s\n",
1693 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1694 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1695 printf("free-fall %s %s\n",
1696 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1697 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1698 printf("sense data reporting %s %s\n",
1699 parm->support2 & ATA_SUPPORT_SENSE_REPORT ? "yes" : "no",
1700 parm->enabled2 & ATA_SUPPORT_SENSE_REPORT ? "yes" : "no");
1701 printf("extended power conditions %s %s\n",
1702 parm->support2 & ATA_SUPPORT_EPC ? "yes" : "no",
1703 parm->enabled2 & ATA_SUPPORT_EPC ? "yes" : "no");
1704 printf("device statistics notification %s %s\n",
1705 parm->support2 & ATA_SUPPORT_DSN ? "yes" : "no",
1706 parm->enabled2 & ATA_SUPPORT_DSN ? "yes" : "no");
1707 printf("Data Set Management (DSM/TRIM) ");
1708 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1710 printf("DSM - max 512byte blocks ");
1711 if (parm->max_dsm_blocks == 0x00)
1712 printf("yes not specified\n");
1715 parm->max_dsm_blocks);
1717 printf("DSM - deterministic read ");
1718 if (parm->support3 & ATA_SUPPORT_DRAT) {
1719 if (parm->support3 & ATA_SUPPORT_RZAT)
1720 printf("yes zeroed\n");
1722 printf("yes any value\n");
1729 printf("Trusted Computing %s\n",
1730 ((parm->tcg & 0xc000) == 0x4000) && (parm->tcg & ATA_SUPPORT_TCG) ?
1732 printf("encrypts all user data %s\n",
1733 parm->support3 & ATA_ENCRYPTS_ALL_USER_DATA ? "yes" : "no");
1734 printf("Sanitize ");
1735 if (parm->multi & ATA_SUPPORT_SANITIZE) {
1736 printf("yes\t\t%s%s%s\n",
1737 parm->multi & ATA_SUPPORT_BLOCK_ERASE_EXT ? "block, " : "",
1738 parm->multi & ATA_SUPPORT_OVERWRITE_EXT ? "overwrite, " : "",
1739 parm->multi & ATA_SUPPORT_CRYPTO_SCRAMBLE_EXT ? "crypto" : "");
1740 printf("Sanitize - commands allowed %s\n",
1741 parm->multi & ATA_SUPPORT_SANITIZE_ALLOWED ? "yes" : "no");
1742 printf("Sanitize - antifreeze lock %s\n",
1743 parm->multi & ATA_SUPPORT_ANTIFREEZE_LOCK_EXT ? "yes" : "no");
1750 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb)
1752 struct ata_pass_16 *ata_pass_16;
1753 struct ata_cmd ata_cmd;
1755 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1756 ata_cmd.command = ata_pass_16->command;
1757 ata_cmd.control = ata_pass_16->control;
1758 ata_cmd.features = ata_pass_16->features;
1760 if (arglist & CAM_ARG_VERBOSE) {
1761 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1762 ata_op_string(&ata_cmd),
1763 ccb->csio.ccb_h.timeout);
1766 /* Disable freezing the device queue */
1767 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1769 if (arglist & CAM_ARG_ERR_RECOVER)
1770 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1772 if (cam_send_ccb(device, ccb) < 0) {
1773 warn("error sending ATA %s via pass_16", ata_op_string(&ata_cmd));
1778 * Consider any non-CAM_REQ_CMP status as error and report it here,
1779 * unless caller set AP_FLAG_CHK_COND, in which case it is reponsible.
1781 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1782 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1783 warnx("ATA %s via pass_16 failed", ata_op_string(&ata_cmd));
1784 if (arglist & CAM_ARG_VERBOSE) {
1785 cam_error_print(device, ccb, CAM_ESF_ALL,
1786 CAM_EPF_ALL, stderr);
1796 ata_cam_send(struct cam_device *device, union ccb *ccb)
1798 if (arglist & CAM_ARG_VERBOSE) {
1799 warnx("sending ATA %s with timeout of %u msecs",
1800 ata_op_string(&(ccb->ataio.cmd)),
1801 ccb->ataio.ccb_h.timeout);
1804 /* Disable freezing the device queue */
1805 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1807 if (arglist & CAM_ARG_ERR_RECOVER)
1808 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1810 if (cam_send_ccb(device, ccb) < 0) {
1811 warn("error sending ATA %s", ata_op_string(&(ccb->ataio.cmd)));
1816 * Consider any non-CAM_REQ_CMP status as error and report it here,
1817 * unless caller set AP_FLAG_CHK_COND, in which case it is reponsible.
1819 if (!(ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT) &&
1820 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1821 warnx("ATA %s failed", ata_op_string(&(ccb->ataio.cmd)));
1822 if (arglist & CAM_ARG_VERBOSE) {
1823 cam_error_print(device, ccb, CAM_ESF_ALL,
1824 CAM_EPF_ALL, stderr);
1833 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1834 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1835 u_int8_t tag_action, u_int8_t command, u_int16_t features,
1836 u_int64_t lba, u_int16_t sector_count, u_int8_t *data_ptr,
1837 u_int16_t dxfer_len, int timeout)
1839 if (data_ptr != NULL) {
1840 if (flags & CAM_DIR_OUT)
1841 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1843 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1845 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1848 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1850 scsi_ata_pass_16(&ccb->csio,
1864 /*sense_len*/SSD_FULL_SIZE,
1867 return scsi_cam_pass_16_send(device, ccb);
1871 ata_try_pass_16(struct cam_device *device)
1873 struct ccb_pathinq cpi;
1875 if (get_cpi(device, &cpi) != 0) {
1876 warnx("couldn't get CPI");
1880 if (cpi.protocol == PROTO_SCSI) {
1881 /* possibly compatible with pass_16 */
1885 /* likely not compatible with pass_16 */
1890 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1891 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1892 u_int8_t tag_action, u_int8_t command, u_int16_t features,
1893 u_int64_t lba, u_int16_t sector_count, u_int8_t *data_ptr,
1894 u_int16_t dxfer_len, int timeout, int force48bit)
1898 retval = ata_try_pass_16(device);
1903 return (ata_do_pass_16(device, ccb, retries, flags, protocol,
1904 ata_flags, tag_action, command, features,
1905 lba, sector_count, data_ptr, dxfer_len,
1909 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1910 cam_fill_ataio(&ccb->ataio,
1919 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1920 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1922 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1924 if (ata_flags & AP_FLAG_CHK_COND)
1925 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1927 return ata_cam_send(device, ccb);
1931 dump_data(uint16_t *ptr, uint32_t len)
1935 for (i = 0; i < len / 2; i++) {
1937 printf(" %3d: ", i);
1938 printf("%04hx ", ptr[i]);
1947 atahpa_proc_resp(struct cam_device *device, union ccb *ccb, u_int64_t *hpasize)
1949 uint8_t error = 0, ata_device = 0, status = 0;
1954 retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
1957 if (arglist & CAM_ARG_VERBOSE) {
1958 cam_error_print(device, ccb, CAM_ESF_ALL,
1959 CAM_EPF_ALL, stderr);
1961 warnx("Can't get ATA command status");
1965 if (status & ATA_STATUS_ERROR) {
1966 if (arglist & CAM_ARG_VERBOSE) {
1967 cam_error_print(device, ccb, CAM_ESF_ALL,
1968 CAM_EPF_ALL, stderr);
1971 if (error & ATA_ERROR_ID_NOT_FOUND) {
1972 warnx("Max address has already been set since "
1973 "last power-on or hardware reset");
1974 } else if (hpasize == NULL)
1975 warnx("Command failed with ATA error");
1980 if (hpasize != NULL) {
1981 if (retval == 2 || retval == 6)
1990 ata_read_native_max(struct cam_device *device, int retry_count,
1991 u_int32_t timeout, union ccb *ccb,
1992 struct ata_params *parm, u_int64_t *hpasize)
1998 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1999 protocol = AP_PROTO_NON_DATA;
2002 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
2003 protocol |= AP_EXTEND;
2005 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
2008 error = ata_do_cmd(device,
2011 /*flags*/CAM_DIR_NONE,
2012 /*protocol*/protocol,
2013 /*ata_flags*/AP_FLAG_CHK_COND,
2014 /*tag_action*/MSG_SIMPLE_Q_TAG,
2021 timeout ? timeout : 5000,
2027 return atahpa_proc_resp(device, ccb, hpasize);
2031 atahpa_set_max(struct cam_device *device, int retry_count,
2032 u_int32_t timeout, union ccb *ccb,
2033 int is48bit, u_int64_t maxsize, int persist)
2039 protocol = AP_PROTO_NON_DATA;
2042 cmd = ATA_SET_MAX_ADDRESS48;
2043 protocol |= AP_EXTEND;
2045 cmd = ATA_SET_MAX_ADDRESS;
2048 /* lba's are zero indexed so the max lba is requested max - 1 */
2052 error = ata_do_cmd(device,
2055 /*flags*/CAM_DIR_NONE,
2056 /*protocol*/protocol,
2057 /*ata_flags*/AP_FLAG_CHK_COND,
2058 /*tag_action*/MSG_SIMPLE_Q_TAG,
2060 /*features*/ATA_HPA_FEAT_MAX_ADDR,
2062 /*sector_count*/persist,
2065 timeout ? timeout : 1000,
2071 return atahpa_proc_resp(device, ccb, NULL);
2075 atahpa_password(struct cam_device *device, int retry_count,
2076 u_int32_t timeout, union ccb *ccb,
2077 int is48bit, struct ata_set_max_pwd *pwd)
2082 protocol = AP_PROTO_PIO_OUT;
2083 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2085 return (ata_do_cmd(device,
2088 /*flags*/CAM_DIR_OUT,
2089 /*protocol*/protocol,
2090 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2091 AP_FLAG_TLEN_SECT_CNT,
2092 /*tag_action*/MSG_SIMPLE_Q_TAG,
2094 /*features*/ATA_HPA_FEAT_SET_PWD,
2096 /*sector_count*/sizeof(*pwd) / 512,
2097 /*data_ptr*/(u_int8_t*)pwd,
2098 /*dxfer_len*/sizeof(*pwd),
2099 timeout ? timeout : 1000,
2104 atahpa_lock(struct cam_device *device, int retry_count,
2105 u_int32_t timeout, union ccb *ccb, int is48bit)
2110 protocol = AP_PROTO_NON_DATA;
2111 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2113 return (ata_do_cmd(device,
2116 /*flags*/CAM_DIR_NONE,
2117 /*protocol*/protocol,
2119 /*tag_action*/MSG_SIMPLE_Q_TAG,
2121 /*features*/ATA_HPA_FEAT_LOCK,
2126 timeout ? timeout : 1000,
2131 atahpa_unlock(struct cam_device *device, int retry_count,
2132 u_int32_t timeout, union ccb *ccb,
2133 int is48bit, struct ata_set_max_pwd *pwd)
2138 protocol = AP_PROTO_PIO_OUT;
2139 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2141 return (ata_do_cmd(device,
2144 /*flags*/CAM_DIR_OUT,
2145 /*protocol*/protocol,
2146 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2147 AP_FLAG_TLEN_SECT_CNT,
2148 /*tag_action*/MSG_SIMPLE_Q_TAG,
2150 /*features*/ATA_HPA_FEAT_UNLOCK,
2152 /*sector_count*/sizeof(*pwd) / 512,
2153 /*data_ptr*/(u_int8_t*)pwd,
2154 /*dxfer_len*/sizeof(*pwd),
2155 timeout ? timeout : 1000,
2160 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2161 u_int32_t timeout, union ccb *ccb, int is48bit)
2166 protocol = AP_PROTO_NON_DATA;
2167 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2169 return (ata_do_cmd(device,
2172 /*flags*/CAM_DIR_NONE,
2173 /*protocol*/protocol,
2175 /*tag_action*/MSG_SIMPLE_Q_TAG,
2177 /*features*/ATA_HPA_FEAT_FREEZE,
2182 timeout ? timeout : 1000,
2187 ata_get_native_max(struct cam_device *device, int retry_count,
2188 u_int32_t timeout, union ccb *ccb,
2189 u_int64_t *nativesize)
2193 error = ata_do_cmd(device,
2196 /*flags*/CAM_DIR_NONE,
2197 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2198 /*ata_flags*/AP_FLAG_CHK_COND,
2199 /*tag_action*/MSG_SIMPLE_Q_TAG,
2200 /*command*/ATA_AMAX_ADDR,
2201 /*features*/ATA_AMAX_ADDR_GET,
2206 timeout ? timeout : 30 * 1000,
2212 return atahpa_proc_resp(device, ccb, nativesize);
2216 ataama_set(struct cam_device *device, int retry_count,
2217 u_int32_t timeout, union ccb *ccb, u_int64_t maxsize)
2221 /* lba's are zero indexed so the max lba is requested max - 1 */
2225 error = ata_do_cmd(device,
2228 /*flags*/CAM_DIR_NONE,
2229 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2230 /*ata_flags*/AP_FLAG_CHK_COND,
2231 /*tag_action*/MSG_SIMPLE_Q_TAG,
2232 /*command*/ATA_AMAX_ADDR,
2233 /*features*/ATA_AMAX_ADDR_SET,
2238 timeout ? timeout : 30 * 1000,
2244 return atahpa_proc_resp(device, ccb, NULL);
2248 ataama_freeze(struct cam_device *device, int retry_count,
2249 u_int32_t timeout, union ccb *ccb)
2252 return (ata_do_cmd(device,
2255 /*flags*/CAM_DIR_NONE,
2256 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2258 /*tag_action*/MSG_SIMPLE_Q_TAG,
2259 /*command*/ATA_AMAX_ADDR,
2260 /*features*/ATA_AMAX_ADDR_FREEZE,
2265 timeout ? timeout : 30 * 1000,
2270 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2271 union ccb *ccb, struct ata_params** ident_bufp)
2273 struct ata_params *ident_buf;
2274 struct ccb_pathinq cpi;
2275 struct ccb_getdev cgd;
2278 u_int8_t command, retry_command;
2280 if (get_cpi(device, &cpi) != 0) {
2281 warnx("couldn't get CPI");
2285 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2286 if (cpi.protocol == PROTO_ATA) {
2287 if (get_cgd(device, &cgd) != 0) {
2288 warnx("couldn't get CGD");
2292 command = (cgd.protocol == PROTO_ATA) ?
2293 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2296 /* We don't know which for sure so try both */
2297 command = ATA_ATA_IDENTIFY;
2298 retry_command = ATA_ATAPI_IDENTIFY;
2301 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2303 warnx("can't calloc memory for identify\n");
2308 error = ata_do_cmd(device,
2310 /*retries*/retry_count,
2311 /*flags*/CAM_DIR_IN,
2312 /*protocol*/AP_PROTO_PIO_IN,
2313 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2314 AP_FLAG_TLEN_SECT_CNT,
2315 /*tag_action*/MSG_SIMPLE_Q_TAG,
2319 /*sector_count*/sizeof(struct ata_params) / 512,
2320 /*data_ptr*/(u_int8_t *)ptr,
2321 /*dxfer_len*/sizeof(struct ata_params),
2322 /*timeout*/timeout ? timeout : 30 * 1000,
2326 if (retry_command != 0) {
2327 command = retry_command;
2335 ident_buf = (struct ata_params *)ptr;
2336 ata_param_fixup(ident_buf);
2339 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2344 /* check for invalid (all zero) response */
2346 warnx("Invalid identify response detected");
2351 *ident_bufp = ident_buf;
2358 ataidentify(struct cam_device *device, int retry_count, int timeout)
2361 struct ata_params *ident_buf;
2362 u_int64_t hpasize = 0, nativesize = 0;
2364 if ((ccb = cam_getccb(device)) == NULL) {
2365 warnx("couldn't allocate CCB");
2369 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2374 if (arglist & CAM_ARG_VERBOSE) {
2375 printf("%s%d: Raw identify data:\n",
2376 device->device_name, device->dev_unit_num);
2377 dump_data((void*)ident_buf, sizeof(struct ata_params));
2380 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2381 ata_read_native_max(device, retry_count, timeout, ccb,
2382 ident_buf, &hpasize);
2384 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR) {
2385 ata_get_native_max(device, retry_count, timeout, ccb,
2389 printf("%s%d: ", device->device_name, device->dev_unit_num);
2390 ata_print_ident(ident_buf);
2391 camxferrate(device);
2392 atacapprint(ident_buf);
2393 atahpa_print(ident_buf, hpasize, 0);
2394 ataama_print(ident_buf, nativesize, 0);
2404 nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused)
2406 struct nvme_controller_data cdata;
2408 if (nvme_get_cdata(device, &cdata))
2410 nvme_print_controller(&cdata);
2417 identify(struct cam_device *device, int retry_count, int timeout)
2420 struct ccb_pathinq cpi;
2422 if (get_cpi(device, &cpi) != 0) {
2423 warnx("couldn't get CPI");
2427 if (cpi.protocol == PROTO_NVME) {
2428 return (nvmeidentify(device, retry_count, timeout));
2431 return (ataidentify(device, retry_count, timeout));
2433 #endif /* MINIMALISTIC */
2436 #ifndef MINIMALISTIC
2438 ATA_SECURITY_ACTION_PRINT,
2439 ATA_SECURITY_ACTION_FREEZE,
2440 ATA_SECURITY_ACTION_UNLOCK,
2441 ATA_SECURITY_ACTION_DISABLE,
2442 ATA_SECURITY_ACTION_ERASE,
2443 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2444 ATA_SECURITY_ACTION_SET_PASSWORD
2448 atasecurity_print_time(u_int16_t tw)
2452 printf("unspecified");
2454 printf("> 508 min");
2456 printf("%i min", 2 * tw);
2460 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2464 return 2 * 3600 * 1000; /* default: two hours */
2465 else if (timeout > 255)
2466 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2468 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2473 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2477 bzero(&cmd, sizeof(cmd));
2478 cmd.command = command;
2479 printf("Issuing %s", ata_op_string(&cmd));
2482 /* pwd->password may not be null terminated */
2483 char pass[sizeof(pwd->password)+1];
2485 strlcpy(pass, pwd->password, sizeof(pass));
2486 printf(" password='%s', user='%s'",
2488 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2491 if (command == ATA_SECURITY_SET_PASSWORD) {
2492 printf(", mode='%s'",
2493 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2494 "maximum" : "high");
2502 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2503 int retry_count, u_int32_t timeout, int quiet)
2507 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2509 return ata_do_cmd(device,
2512 /*flags*/CAM_DIR_NONE,
2513 /*protocol*/AP_PROTO_NON_DATA,
2515 /*tag_action*/MSG_SIMPLE_Q_TAG,
2516 /*command*/ATA_SECURITY_FREEZE_LOCK,
2527 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2528 int retry_count, u_int32_t timeout,
2529 struct ata_security_password *pwd, int quiet)
2533 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2535 return ata_do_cmd(device,
2538 /*flags*/CAM_DIR_OUT,
2539 /*protocol*/AP_PROTO_PIO_OUT,
2540 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2541 AP_FLAG_TLEN_SECT_CNT,
2542 /*tag_action*/MSG_SIMPLE_Q_TAG,
2543 /*command*/ATA_SECURITY_UNLOCK,
2546 /*sector_count*/sizeof(*pwd) / 512,
2547 /*data_ptr*/(u_int8_t *)pwd,
2548 /*dxfer_len*/sizeof(*pwd),
2554 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2555 int retry_count, u_int32_t timeout,
2556 struct ata_security_password *pwd, int quiet)
2560 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2561 return ata_do_cmd(device,
2564 /*flags*/CAM_DIR_OUT,
2565 /*protocol*/AP_PROTO_PIO_OUT,
2566 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2567 AP_FLAG_TLEN_SECT_CNT,
2568 /*tag_action*/MSG_SIMPLE_Q_TAG,
2569 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2572 /*sector_count*/sizeof(*pwd) / 512,
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_cmd(device,
2625 /*flags*/CAM_DIR_NONE,
2626 /*protocol*/AP_PROTO_NON_DATA,
2628 /*tag_action*/MSG_SIMPLE_Q_TAG,
2629 /*command*/ATA_SECURITY_ERASE_PREPARE,
2642 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2644 error = ata_do_cmd(device,
2647 /*flags*/CAM_DIR_OUT,
2648 /*protocol*/AP_PROTO_PIO_OUT,
2649 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2650 AP_FLAG_TLEN_SECT_CNT,
2651 /*tag_action*/MSG_SIMPLE_Q_TAG,
2652 /*command*/ATA_SECURITY_ERASE_UNIT,
2655 /*sector_count*/sizeof(*pwd) / 512,
2656 /*data_ptr*/(u_int8_t *)pwd,
2657 /*dxfer_len*/sizeof(*pwd),
2658 /*timeout*/erase_timeout,
2661 if (error == 0 && quiet == 0)
2662 printf("\nErase Complete\n");
2668 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2669 int retry_count, u_int32_t timeout,
2670 struct ata_security_password *pwd, int quiet)
2674 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2676 return ata_do_cmd(device,
2679 /*flags*/CAM_DIR_OUT,
2680 /*protocol*/AP_PROTO_PIO_OUT,
2681 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2682 AP_FLAG_TLEN_SECT_CNT,
2683 /*tag_action*/MSG_SIMPLE_Q_TAG,
2684 /*command*/ATA_SECURITY_SET_PASSWORD,
2687 /*sector_count*/sizeof(*pwd) / 512,
2688 /*data_ptr*/(u_int8_t *)pwd,
2689 /*dxfer_len*/sizeof(*pwd),
2695 atasecurity_print(struct ata_params *parm)
2698 printf("\nSecurity Option Value\n");
2699 if (arglist & CAM_ARG_VERBOSE) {
2700 printf("status %04x\n",
2701 parm->security_status);
2703 printf("supported %s\n",
2704 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2705 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2707 printf("enabled %s\n",
2708 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2709 printf("drive locked %s\n",
2710 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2711 printf("security config frozen %s\n",
2712 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2713 printf("count expired %s\n",
2714 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2715 printf("security level %s\n",
2716 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2717 printf("enhanced erase supported %s\n",
2718 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2719 printf("erase time ");
2720 atasecurity_print_time(parm->erase_time);
2722 printf("enhanced erase time ");
2723 atasecurity_print_time(parm->enhanced_erase_time);
2725 printf("master password rev %04x%s\n",
2726 parm->master_passwd_revision,
2727 parm->master_passwd_revision == 0x0000 ||
2728 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2732 * Validates and copies the password in optarg to the passed buffer.
2733 * If the password in optarg is the same length as the buffer then
2734 * the data will still be copied but no null termination will occur.
2737 ata_getpwd(u_int8_t *passwd, int max, char opt)
2741 len = strlen(optarg);
2743 warnx("-%c password is too long", opt);
2745 } else if (len == 0) {
2746 warnx("-%c password is missing", opt);
2748 } else if (optarg[0] == '-'){
2749 warnx("-%c password starts with '-' (generic arg?)", opt);
2751 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2752 warnx("-%c password conflicts with existing password from -%c",
2757 /* Callers pass in a buffer which does NOT need to be terminated */
2758 strncpy(passwd, optarg, max);
2765 ATA_HPA_ACTION_PRINT,
2766 ATA_HPA_ACTION_SET_MAX,
2767 ATA_HPA_ACTION_SET_PWD,
2768 ATA_HPA_ACTION_LOCK,
2769 ATA_HPA_ACTION_UNLOCK,
2770 ATA_HPA_ACTION_FREEZE_LOCK
2774 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2775 u_int64_t maxsize, int persist)
2777 printf("\nYou are about to configure HPA to limit the user accessible\n"
2778 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2779 persist ? "persistently" : "temporarily",
2780 device->device_name, device->dev_unit_num,
2781 device->given_dev_name, device->given_unit_number);
2782 ata_print_ident(ident_buf);
2786 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2788 if (NULL != fgets(str, sizeof(str), stdin)) {
2789 if (0 == strncasecmp(str, "yes", 3)) {
2791 } else if (0 == strncasecmp(str, "no", 2)) {
2794 printf("Please answer \"yes\" or "
2805 atahpa(struct cam_device *device, int retry_count, int timeout,
2806 int argc, char **argv, char *combinedopt)
2809 struct ata_params *ident_buf;
2810 struct ccb_getdev cgd;
2811 struct ata_set_max_pwd pwd;
2812 int error, confirm, quiet, c, action, actions, persist;
2813 int security, is48bit, pwdsize;
2814 u_int64_t hpasize, maxsize;
2823 memset(&pwd, 0, sizeof(pwd));
2825 /* default action is to print hpa information */
2826 action = ATA_HPA_ACTION_PRINT;
2827 pwdsize = sizeof(pwd.password);
2829 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2832 action = ATA_HPA_ACTION_SET_MAX;
2833 maxsize = strtoumax(optarg, NULL, 0);
2838 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2840 action = ATA_HPA_ACTION_SET_PWD;
2846 action = ATA_HPA_ACTION_LOCK;
2852 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2854 action = ATA_HPA_ACTION_UNLOCK;
2860 action = ATA_HPA_ACTION_FREEZE_LOCK;
2880 warnx("too many hpa actions specified");
2884 if (get_cgd(device, &cgd) != 0) {
2885 warnx("couldn't get CGD");
2889 ccb = cam_getccb(device);
2891 warnx("couldn't allocate CCB");
2895 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2902 printf("%s%d: ", device->device_name, device->dev_unit_num);
2903 ata_print_ident(ident_buf);
2904 camxferrate(device);
2907 if (action == ATA_HPA_ACTION_PRINT) {
2909 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)
2910 ata_read_native_max(device, retry_count, timeout, ccb,
2911 ident_buf, &hpasize);
2912 atahpa_print(ident_buf, hpasize, 1);
2919 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2920 warnx("HPA is not supported by this device");
2926 if (security && !(ident_buf->support.command2 & ATA_SUPPORT_MAXSECURITY)) {
2927 warnx("HPA Security is not supported by this device");
2933 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2936 * The ATA spec requires:
2937 * 1. Read native max addr is called directly before set max addr
2938 * 2. Read native max addr is NOT called before any other set max call
2941 case ATA_HPA_ACTION_SET_MAX:
2943 atahpa_set_confirm(device, ident_buf, maxsize,
2950 error = ata_read_native_max(device, retry_count, timeout,
2951 ccb, ident_buf, &hpasize);
2953 error = atahpa_set_max(device, retry_count, timeout,
2954 ccb, is48bit, maxsize, persist);
2957 /* redo identify to get new values */
2958 error = ata_do_identify(device,
2959 retry_count, timeout, ccb,
2961 atahpa_print(ident_buf, hpasize, 1);
2963 /* Hint CAM to reprobe the device. */
2969 case ATA_HPA_ACTION_SET_PWD:
2970 error = atahpa_password(device, retry_count, timeout,
2971 ccb, is48bit, &pwd);
2972 if (error == 0 && quiet == 0)
2973 printf("HPA password has been set\n");
2976 case ATA_HPA_ACTION_LOCK:
2977 error = atahpa_lock(device, retry_count, timeout,
2979 if (error == 0 && quiet == 0)
2980 printf("HPA has been locked\n");
2983 case ATA_HPA_ACTION_UNLOCK:
2984 error = atahpa_unlock(device, retry_count, timeout,
2985 ccb, is48bit, &pwd);
2986 if (error == 0 && quiet == 0)
2987 printf("HPA has been unlocked\n");
2990 case ATA_HPA_ACTION_FREEZE_LOCK:
2991 error = atahpa_freeze_lock(device, retry_count, timeout,
2993 if (error == 0 && quiet == 0)
2994 printf("HPA has been frozen\n");
2998 errx(1, "Option currently not supported");
3008 ATA_AMA_ACTION_PRINT,
3009 ATA_AMA_ACTION_SET_MAX,
3010 ATA_AMA_ACTION_FREEZE_LOCK
3014 ataama(struct cam_device *device, int retry_count, int timeout,
3015 int argc, char **argv, char *combinedopt)
3018 struct ata_params *ident_buf;
3019 struct ccb_getdev cgd;
3020 int error, quiet, c, action, actions;
3021 u_int64_t nativesize, maxsize;
3027 /* default action is to print AMA information */
3028 action = ATA_AMA_ACTION_PRINT;
3030 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3033 action = ATA_AMA_ACTION_SET_MAX;
3034 maxsize = strtoumax(optarg, NULL, 0);
3039 action = ATA_AMA_ACTION_FREEZE_LOCK;
3050 warnx("too many AMA actions specified");
3054 if (get_cgd(device, &cgd) != 0) {
3055 warnx("couldn't get CGD");
3059 ccb = cam_getccb(device);
3061 warnx("couldn't allocate CCB");
3065 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3072 printf("%s%d: ", device->device_name, device->dev_unit_num);
3073 ata_print_ident(ident_buf);
3074 camxferrate(device);
3077 if (action == ATA_AMA_ACTION_PRINT) {
3079 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)
3080 ata_get_native_max(device, retry_count, timeout, ccb,
3082 ataama_print(ident_buf, nativesize, 1);
3089 if (!(ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)) {
3090 warnx("Accessible Max Address is not supported by this device");
3097 case ATA_AMA_ACTION_SET_MAX:
3098 error = ata_get_native_max(device, retry_count, timeout, ccb,
3101 error = ataama_set(device, retry_count, timeout,
3105 /* redo identify to get new values */
3106 error = ata_do_identify(device,
3107 retry_count, timeout, ccb,
3109 ataama_print(ident_buf, nativesize, 1);
3111 /* Hint CAM to reprobe the device. */
3117 case ATA_AMA_ACTION_FREEZE_LOCK:
3118 error = ataama_freeze(device, retry_count, timeout,
3120 if (error == 0 && quiet == 0)
3121 printf("Accessible Max Address has been frozen\n");
3125 errx(1, "Option currently not supported");
3135 atasecurity(struct cam_device *device, int retry_count, int timeout,
3136 int argc, char **argv, char *combinedopt)
3139 struct ata_params *ident_buf;
3140 int error, confirm, quiet, c, action, actions, setpwd;
3141 int security_enabled, erase_timeout, pwdsize;
3142 struct ata_security_password pwd;
3150 memset(&pwd, 0, sizeof(pwd));
3152 /* default action is to print security information */
3153 action = ATA_SECURITY_ACTION_PRINT;
3155 /* user is master by default as its safer that way */
3156 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3157 pwdsize = sizeof(pwd.password);
3159 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3162 action = ATA_SECURITY_ACTION_FREEZE;
3167 if (strcasecmp(optarg, "user") == 0) {
3168 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
3169 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
3170 } else if (strcasecmp(optarg, "master") == 0) {
3171 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3172 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
3174 warnx("-U argument '%s' is invalid (must be "
3175 "'user' or 'master')", optarg);
3181 if (strcasecmp(optarg, "high") == 0) {
3182 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3183 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3184 } else if (strcasecmp(optarg, "maximum") == 0) {
3185 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3186 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3188 warnx("-l argument '%s' is unknown (must be "
3189 "'high' or 'maximum')", optarg);
3195 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3197 action = ATA_SECURITY_ACTION_UNLOCK;
3202 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3204 action = ATA_SECURITY_ACTION_DISABLE;
3209 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3211 action = ATA_SECURITY_ACTION_ERASE;
3216 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3218 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3219 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3224 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3227 if (action == ATA_SECURITY_ACTION_PRINT)
3228 action = ATA_SECURITY_ACTION_SET_PASSWORD;
3230 * Don't increment action as this can be combined
3231 * with other actions.
3244 erase_timeout = atoi(optarg) * 1000;
3250 warnx("too many security actions specified");
3254 if ((ccb = cam_getccb(device)) == NULL) {
3255 warnx("couldn't allocate CCB");
3259 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3266 printf("%s%d: ", device->device_name, device->dev_unit_num);
3267 ata_print_ident(ident_buf);
3268 camxferrate(device);
3271 if (action == ATA_SECURITY_ACTION_PRINT) {
3272 atasecurity_print(ident_buf);
3278 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3279 warnx("Security not supported");
3285 /* default timeout 15 seconds the same as linux hdparm */
3286 timeout = timeout ? timeout : 15 * 1000;
3288 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3290 /* first set the password if requested */
3292 /* confirm we can erase before setting the password if erasing */
3294 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3295 action == ATA_SECURITY_ACTION_ERASE) &&
3296 atasecurity_erase_confirm(device, ident_buf) == 0) {
3302 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3303 pwd.revision = ident_buf->master_passwd_revision;
3304 if (pwd.revision != 0 && pwd.revision != 0xfff &&
3305 --pwd.revision == 0) {
3306 pwd.revision = 0xfffe;
3309 error = atasecurity_set_password(device, ccb, retry_count,
3310 timeout, &pwd, quiet);
3316 security_enabled = 1;
3320 case ATA_SECURITY_ACTION_FREEZE:
3321 error = atasecurity_freeze(device, ccb, retry_count,
3325 case ATA_SECURITY_ACTION_UNLOCK:
3326 if (security_enabled) {
3327 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3328 error = atasecurity_unlock(device, ccb,
3329 retry_count, timeout, &pwd, quiet);
3331 warnx("Can't unlock, drive is not locked");
3335 warnx("Can't unlock, security is disabled");
3340 case ATA_SECURITY_ACTION_DISABLE:
3341 if (security_enabled) {
3342 /* First unlock the drive if its locked */
3343 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3344 error = atasecurity_unlock(device, ccb,
3352 error = atasecurity_disable(device,
3360 warnx("Can't disable security (already disabled)");
3365 case ATA_SECURITY_ACTION_ERASE:
3366 if (security_enabled) {
3367 if (erase_timeout == 0) {
3368 erase_timeout = atasecurity_erase_timeout_msecs(
3369 ident_buf->erase_time);
3372 error = atasecurity_erase(device, ccb, retry_count,
3373 timeout, erase_timeout, &pwd, quiet);
3375 warnx("Can't secure erase (security is disabled)");
3380 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3381 if (security_enabled) {
3382 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3383 if (erase_timeout == 0) {
3385 atasecurity_erase_timeout_msecs(
3386 ident_buf->enhanced_erase_time);
3389 error = atasecurity_erase(device, ccb,
3390 retry_count, timeout,
3391 erase_timeout, &pwd,
3394 warnx("Enhanced erase is not supported");
3398 warnx("Can't secure erase (enhanced), "
3399 "(security is disabled)");
3410 #endif /* MINIMALISTIC */
3413 * Convert periph name into a bus, target and lun.
3415 * Returns the number of parsed components, or 0.
3418 parse_btl_name(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3419 cam_argmask *arglst)
3424 bzero(&ccb, sizeof(ccb));
3425 ccb.ccb_h.func_code = XPT_GDEVLIST;
3426 if (cam_get_device(tstr, ccb.cgdl.periph_name,
3427 sizeof(ccb.cgdl.periph_name), &ccb.cgdl.unit_number) == -1) {
3428 warnx("%s", cam_errbuf);
3433 * Attempt to get the passthrough device. This ioctl will
3434 * fail if the device name is null, if the device doesn't
3435 * exist, or if the passthrough driver isn't in the kernel.
3437 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3438 warn("Unable to open %s", XPT_DEVICE);
3441 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3442 warn("Unable to find bus:target:lun for device %s%d",
3443 ccb.cgdl.periph_name, ccb.cgdl.unit_number);
3448 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3449 const struct cam_status_entry *entry;
3451 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3452 warnx("Unable to find bus:target_lun for device %s%d, "
3453 "CAM status: %s (%#x)",
3454 ccb.cgdl.periph_name, ccb.cgdl.unit_number,
3455 entry ? entry->status_text : "Unknown",
3461 * The kernel fills in the bus/target/lun. We don't
3462 * need the passthrough device name and unit number since
3463 * we aren't going to open it.
3465 *bus = ccb.ccb_h.path_id;
3466 *target = ccb.ccb_h.target_id;
3467 *lun = ccb.ccb_h.target_lun;
3468 *arglst |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3473 * Parse out a bus, or a bus, target and lun in the following
3479 * Returns the number of parsed components, or 0.
3482 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3483 cam_argmask *arglst)
3488 *bus = CAM_BUS_WILDCARD;
3489 *target = CAM_TARGET_WILDCARD;
3490 *lun = CAM_LUN_WILDCARD;
3492 while (isspace(*tstr) && (*tstr != '\0'))
3495 if (strncasecmp(tstr, "all", strlen("all")) == 0) {
3496 arglist |= CAM_ARG_BUS;
3500 if (!isdigit(*tstr))
3501 return (parse_btl_name(tstr, bus, target, lun, arglst));
3503 tmpstr = strsep(&tstr, ":");
3504 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3505 *bus = strtol(tmpstr, &end, 0);
3508 *arglst |= CAM_ARG_BUS;
3510 tmpstr = strsep(&tstr, ":");
3511 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3512 *target = strtol(tmpstr, &end, 0);
3515 *arglst |= CAM_ARG_TARGET;
3517 tmpstr = strsep(&tstr, ":");
3518 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3519 *lun = strtoll(tmpstr, &end, 0);
3522 *arglst |= CAM_ARG_LUN;
3532 dorescan_or_reset(int argc, char **argv, int rescan)
3534 static const char must[] =
3535 "you must specify \"all\", a bus, a bus:target:lun or periph to %s";
3537 path_id_t bus = CAM_BUS_WILDCARD;
3538 target_id_t target = CAM_TARGET_WILDCARD;
3539 lun_id_t lun = CAM_LUN_WILDCARD;
3543 warnx(must, rescan? "rescan" : "reset");
3547 tstr = argv[optind];
3548 while (isspace(*tstr) && (*tstr != '\0'))
3550 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3551 arglist |= CAM_ARG_BUS;
3553 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3554 if (rv != 1 && rv != 3) {
3555 warnx(must, rescan ? "rescan" : "reset");
3560 if (arglist & CAM_ARG_LUN)
3561 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3563 error = rescan_or_reset_bus(bus, rescan);
3569 rescan_or_reset_bus(path_id_t bus, int rescan)
3571 union ccb *ccb = NULL, *matchccb = NULL;
3572 int fd = -1, retval;
3577 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3578 warnx("error opening transport layer device %s", XPT_DEVICE);
3579 warn("%s", XPT_DEVICE);
3583 ccb = malloc(sizeof(*ccb));
3585 warn("failed to allocate CCB");
3589 bzero(ccb, sizeof(*ccb));
3591 if (bus != CAM_BUS_WILDCARD) {
3592 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3593 ccb->ccb_h.path_id = bus;
3594 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3595 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3596 ccb->crcn.flags = CAM_FLAG_NONE;
3598 /* run this at a low priority */
3599 ccb->ccb_h.pinfo.priority = 5;
3601 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3602 warn("CAMIOCOMMAND ioctl failed");
3607 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3608 fprintf(stdout, "%s of bus %d was successful\n",
3609 rescan ? "Re-scan" : "Reset", bus);
3611 fprintf(stdout, "%s of bus %d returned error %#x\n",
3612 rescan ? "Re-scan" : "Reset", bus,
3613 ccb->ccb_h.status & CAM_STATUS_MASK);
3622 * The right way to handle this is to modify the xpt so that it can
3623 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3624 * that isn't implemented, so instead we enumerate the buses and
3625 * send the rescan or reset to those buses in the case where the
3626 * given bus is -1 (wildcard). We don't send a rescan or reset
3627 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3628 * no-op, sending a rescan to the xpt bus would result in a status of
3631 matchccb = malloc(sizeof(*matchccb));
3632 if (matchccb == NULL) {
3633 warn("failed to allocate CCB");
3637 bzero(matchccb, sizeof(*matchccb));
3638 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3639 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3640 bufsize = sizeof(struct dev_match_result) * 20;
3641 matchccb->cdm.match_buf_len = bufsize;
3642 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3643 if (matchccb->cdm.matches == NULL) {
3644 warnx("can't malloc memory for matches");
3648 matchccb->cdm.num_matches = 0;
3650 matchccb->cdm.num_patterns = 1;
3651 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3653 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3654 matchccb->cdm.pattern_buf_len);
3655 if (matchccb->cdm.patterns == NULL) {
3656 warnx("can't malloc memory for patterns");
3660 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3661 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3666 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3667 warn("CAMIOCOMMAND ioctl failed");
3672 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3673 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3674 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3675 warnx("got CAM error %#x, CDM error %d\n",
3676 matchccb->ccb_h.status, matchccb->cdm.status);
3681 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3682 struct bus_match_result *bus_result;
3684 /* This shouldn't happen. */
3685 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3688 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3691 * We don't want to rescan or reset the xpt bus.
3694 if (bus_result->path_id == CAM_XPT_PATH_ID)
3697 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3699 ccb->ccb_h.path_id = bus_result->path_id;
3700 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3701 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3702 ccb->crcn.flags = CAM_FLAG_NONE;
3704 /* run this at a low priority */
3705 ccb->ccb_h.pinfo.priority = 5;
3707 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3708 warn("CAMIOCOMMAND ioctl failed");
3713 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3714 fprintf(stdout, "%s of bus %d was successful\n",
3715 rescan? "Re-scan" : "Reset",
3716 bus_result->path_id);
3719 * Don't bail out just yet, maybe the other
3720 * rescan or reset commands will complete
3723 fprintf(stderr, "%s of bus %d returned error "
3724 "%#x\n", rescan? "Re-scan" : "Reset",
3725 bus_result->path_id,
3726 ccb->ccb_h.status & CAM_STATUS_MASK);
3730 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3731 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3738 if (matchccb != NULL) {
3739 free(matchccb->cdm.patterns);
3740 free(matchccb->cdm.matches);
3749 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3752 struct cam_device *device;
3757 if (bus == CAM_BUS_WILDCARD) {
3758 warnx("invalid bus number %d", bus);
3762 if (target == CAM_TARGET_WILDCARD) {
3763 warnx("invalid target number %d", target);
3767 if (lun == CAM_LUN_WILDCARD) {
3768 warnx("invalid lun number %jx", (uintmax_t)lun);
3774 bzero(&ccb, sizeof(union ccb));
3777 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3778 warnx("error opening transport layer device %s\n",
3780 warn("%s", XPT_DEVICE);
3784 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3785 if (device == NULL) {
3786 warnx("%s", cam_errbuf);
3791 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3792 ccb.ccb_h.path_id = bus;
3793 ccb.ccb_h.target_id = target;
3794 ccb.ccb_h.target_lun = lun;
3795 ccb.ccb_h.timeout = 5000;
3796 ccb.crcn.flags = CAM_FLAG_NONE;
3798 /* run this at a low priority */
3799 ccb.ccb_h.pinfo.priority = 5;
3802 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3803 warn("CAMIOCOMMAND ioctl failed");
3808 if (cam_send_ccb(device, &ccb) < 0) {
3809 warn("error sending XPT_RESET_DEV CCB");
3810 cam_close_device(device);
3818 cam_close_device(device);
3821 * An error code of CAM_BDR_SENT is normal for a BDR request.
3823 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3825 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3826 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3827 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3830 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3831 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3832 ccb.ccb_h.status & CAM_STATUS_MASK);
3837 #ifndef MINIMALISTIC
3839 static struct scsi_nv defect_list_type_map[] = {
3840 { "block", SRDD10_BLOCK_FORMAT },
3841 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3842 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3843 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3844 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3845 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3849 readdefects(struct cam_device *device, int argc, char **argv,
3850 char *combinedopt, int task_attr, int retry_count, int timeout)
3852 union ccb *ccb = NULL;
3853 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3854 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3855 size_t hdr_size = 0, entry_size = 0;
3858 u_int8_t *defect_list = NULL;
3859 u_int8_t list_format = 0;
3860 int list_type_set = 0;
3861 u_int32_t dlist_length = 0;
3862 u_int32_t returned_length = 0, valid_len = 0;
3863 u_int32_t num_returned = 0, num_valid = 0;
3864 u_int32_t max_possible_size = 0, hdr_max = 0;
3865 u_int32_t starting_offset = 0;
3866 u_int8_t returned_format, returned_type;
3868 int summary = 0, quiet = 0;
3870 int lists_specified = 0;
3871 int get_length = 1, first_pass = 1;
3874 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3878 scsi_nv_status status;
3881 status = scsi_get_nv(defect_list_type_map,
3882 sizeof(defect_list_type_map) /
3883 sizeof(defect_list_type_map[0]), optarg,
3884 &entry_num, SCSI_NV_FLAG_IG_CASE);
3886 if (status == SCSI_NV_FOUND) {
3887 list_format = defect_list_type_map[
3891 warnx("%s: %s %s option %s", __func__,
3892 (status == SCSI_NV_AMBIGUOUS) ?
3893 "ambiguous" : "invalid", "defect list type",
3896 goto defect_bailout;
3901 arglist |= CAM_ARG_GLIST;
3904 arglist |= CAM_ARG_PLIST;
3915 starting_offset = strtoul(optarg, &endptr, 0);
3916 if (*endptr != '\0') {
3918 warnx("invalid starting offset %s", optarg);
3919 goto defect_bailout;
3931 if (list_type_set == 0) {
3933 warnx("no defect list format specified");
3934 goto defect_bailout;
3937 if (arglist & CAM_ARG_PLIST) {
3938 list_format |= SRDD10_PLIST;
3942 if (arglist & CAM_ARG_GLIST) {
3943 list_format |= SRDD10_GLIST;
3948 * This implies a summary, and was the previous behavior.
3950 if (lists_specified == 0)
3953 ccb = cam_getccb(device);
3958 * We start off asking for just the header to determine how much
3959 * defect data is available. Some Hitachi drives return an error
3960 * if you ask for more data than the drive has. Once we know the
3961 * length, we retry the command with the returned length.
3963 if (use_12byte == 0)
3964 dlist_length = sizeof(*hdr10);
3966 dlist_length = sizeof(*hdr12);
3969 if (defect_list != NULL) {
3973 defect_list = malloc(dlist_length);
3974 if (defect_list == NULL) {
3975 warnx("can't malloc memory for defect list");
3977 goto defect_bailout;
3981 bzero(defect_list, dlist_length);
3984 * cam_getccb() zeros the CCB header only. So we need to zero the
3985 * payload portion of the ccb.
3987 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3989 scsi_read_defects(&ccb->csio,
3990 /*retries*/ retry_count,
3992 /*tag_action*/ task_attr,
3993 /*list_format*/ list_format,
3994 /*addr_desc_index*/ starting_offset,
3995 /*data_ptr*/ defect_list,
3996 /*dxfer_len*/ dlist_length,
3997 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3998 /*sense_len*/ SSD_FULL_SIZE,
3999 /*timeout*/ timeout ? timeout : 5000);
4001 /* Disable freezing the device queue */
4002 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4004 if (cam_send_ccb(device, ccb) < 0) {
4005 warn("error sending READ DEFECT DATA command");
4007 goto defect_bailout;
4010 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
4012 if (use_12byte == 0) {
4013 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
4014 hdr_size = sizeof(*hdr10);
4015 hdr_max = SRDDH10_MAX_LENGTH;
4017 if (valid_len >= hdr_size) {
4018 returned_length = scsi_2btoul(hdr10->length);
4019 returned_format = hdr10->format;
4021 returned_length = 0;
4022 returned_format = 0;
4025 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
4026 hdr_size = sizeof(*hdr12);
4027 hdr_max = SRDDH12_MAX_LENGTH;
4029 if (valid_len >= hdr_size) {
4030 returned_length = scsi_4btoul(hdr12->length);
4031 returned_format = hdr12->format;
4033 returned_length = 0;
4034 returned_format = 0;
4038 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
4039 switch (returned_type) {
4040 case SRDD10_BLOCK_FORMAT:
4041 entry_size = sizeof(struct scsi_defect_desc_block);
4043 case SRDD10_LONG_BLOCK_FORMAT:
4044 entry_size = sizeof(struct scsi_defect_desc_long_block);
4046 case SRDD10_EXT_PHYS_FORMAT:
4047 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4048 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
4050 case SRDD10_EXT_BFI_FORMAT:
4051 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4052 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
4055 warnx("Unknown defect format 0x%x\n", returned_type);
4057 goto defect_bailout;
4061 max_possible_size = (hdr_max / entry_size) * entry_size;
4062 num_returned = returned_length / entry_size;
4063 num_valid = min(returned_length, valid_len - hdr_size);
4064 num_valid /= entry_size;
4066 if (get_length != 0) {
4069 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
4070 CAM_SCSI_STATUS_ERROR) {
4071 struct scsi_sense_data *sense;
4072 int error_code, sense_key, asc, ascq;
4074 sense = &ccb->csio.sense_data;
4075 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4076 ccb->csio.sense_resid, &error_code, &sense_key,
4077 &asc, &ascq, /*show_errors*/ 1);
4080 * If the drive is reporting that it just doesn't
4081 * support the defect list format, go ahead and use
4082 * the length it reported. Otherwise, the length
4083 * may not be valid, so use the maximum.
4085 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4086 && (asc == 0x1c) && (ascq == 0x00)
4087 && (returned_length > 0)) {
4088 if ((use_12byte == 0)
4089 && (returned_length >= max_possible_size)) {
4094 dlist_length = returned_length + hdr_size;
4095 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4096 && (asc == 0x1f) && (ascq == 0x00)
4097 && (returned_length > 0)) {
4098 /* Partial defect list transfer */
4100 * Hitachi drives return this error
4101 * along with a partial defect list if they
4102 * have more defects than the 10 byte
4103 * command can support. Retry with the 12
4106 if (use_12byte == 0) {
4111 dlist_length = returned_length + hdr_size;
4112 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
4113 && (asc == 0x24) && (ascq == 0x00)) {
4114 /* Invalid field in CDB */
4116 * SBC-3 says that if the drive has more
4117 * defects than can be reported with the
4118 * 10 byte command, it should return this
4119 * error and no data. Retry with the 12
4122 if (use_12byte == 0) {
4127 dlist_length = returned_length + hdr_size;
4130 * If we got a SCSI error and no valid length,
4131 * just use the 10 byte maximum. The 12
4132 * byte maximum is too large.
4134 if (returned_length == 0)
4135 dlist_length = SRDD10_MAX_LENGTH;
4137 if ((use_12byte == 0)
4138 && (returned_length >=
4139 max_possible_size)) {
4144 dlist_length = returned_length +
4148 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4151 warnx("Error reading defect header");
4152 if (arglist & CAM_ARG_VERBOSE)
4153 cam_error_print(device, ccb, CAM_ESF_ALL,
4154 CAM_EPF_ALL, stderr);
4155 goto defect_bailout;
4157 if ((use_12byte == 0)
4158 && (returned_length >= max_possible_size)) {
4163 dlist_length = returned_length + hdr_size;
4166 fprintf(stdout, "%u", num_returned);
4168 fprintf(stdout, " defect%s",
4169 (num_returned != 1) ? "s" : "");
4171 fprintf(stdout, "\n");
4173 goto defect_bailout;
4177 * We always limit the list length to the 10-byte maximum
4178 * length (0xffff). The reason is that some controllers
4179 * can't handle larger I/Os, and we can transfer the entire
4180 * 10 byte list in one shot. For drives that support the 12
4181 * byte read defects command, we'll step through the list
4182 * by specifying a starting offset. For drives that don't
4183 * support the 12 byte command's starting offset, we'll
4184 * just display the first 64K.
4186 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4192 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4193 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4194 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4195 struct scsi_sense_data *sense;
4196 int error_code, sense_key, asc, ascq;
4198 sense = &ccb->csio.sense_data;
4199 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4200 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4201 &ascq, /*show_errors*/ 1);
4204 * According to the SCSI spec, if the disk doesn't support
4205 * the requested format, it will generally return a sense
4206 * key of RECOVERED ERROR, and an additional sense code
4207 * of "DEFECT LIST NOT FOUND". HGST drives also return
4208 * Primary/Grown defect list not found errors. So just
4209 * check for an ASC of 0x1c.
4211 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4213 const char *format_str;
4215 format_str = scsi_nv_to_str(defect_list_type_map,
4216 sizeof(defect_list_type_map) /
4217 sizeof(defect_list_type_map[0]),
4218 list_format & SRDD10_DLIST_FORMAT_MASK);
4219 warnx("requested defect format %s not available",
4220 format_str ? format_str : "unknown");
4222 format_str = scsi_nv_to_str(defect_list_type_map,
4223 sizeof(defect_list_type_map) /
4224 sizeof(defect_list_type_map[0]), returned_type);
4225 if (format_str != NULL) {
4226 warnx("Device returned %s format",
4230 warnx("Device returned unknown defect"
4231 " data format %#x", returned_type);
4232 goto defect_bailout;
4236 warnx("Error returned from read defect data command");
4237 if (arglist & CAM_ARG_VERBOSE)
4238 cam_error_print(device, ccb, CAM_ESF_ALL,
4239 CAM_EPF_ALL, stderr);
4240 goto defect_bailout;
4242 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4244 warnx("Error returned from read defect data command");
4245 if (arglist & CAM_ARG_VERBOSE)
4246 cam_error_print(device, ccb, CAM_ESF_ALL,
4247 CAM_EPF_ALL, stderr);
4248 goto defect_bailout;
4251 if (first_pass != 0) {
4252 fprintf(stderr, "Got %d defect", num_returned);
4254 if ((lists_specified == 0) || (num_returned == 0)) {
4255 fprintf(stderr, "s.\n");
4256 goto defect_bailout;
4257 } else if (num_returned == 1)
4258 fprintf(stderr, ":\n");
4260 fprintf(stderr, "s:\n");
4266 * XXX KDM I should probably clean up the printout format for the
4269 switch (returned_type) {
4270 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4271 case SRDD10_EXT_PHYS_FORMAT:
4273 struct scsi_defect_desc_phys_sector *dlist;
4275 dlist = (struct scsi_defect_desc_phys_sector *)
4276 (defect_list + hdr_size);
4278 for (i = 0; i < num_valid; i++) {
4281 sector = scsi_4btoul(dlist[i].sector);
4282 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4283 mads = (sector & SDD_EXT_PHYS_MADS) ?
4285 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4287 if (hex_format == 0)
4288 fprintf(stdout, "%d:%d:%d%s",
4289 scsi_3btoul(dlist[i].cylinder),
4291 scsi_4btoul(dlist[i].sector),
4292 mads ? " - " : "\n");
4294 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4295 scsi_3btoul(dlist[i].cylinder),
4297 scsi_4btoul(dlist[i].sector),
4298 mads ? " - " : "\n");
4301 if (num_valid < num_returned) {
4302 starting_offset += num_valid;
4307 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4308 case SRDD10_EXT_BFI_FORMAT:
4310 struct scsi_defect_desc_bytes_from_index *dlist;
4312 dlist = (struct scsi_defect_desc_bytes_from_index *)
4313 (defect_list + hdr_size);
4315 for (i = 0; i < num_valid; i++) {
4318 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4319 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4320 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4321 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4323 if (hex_format == 0)
4324 fprintf(stdout, "%d:%d:%d%s",
4325 scsi_3btoul(dlist[i].cylinder),
4327 scsi_4btoul(dlist[i].bytes_from_index),
4328 mads ? " - " : "\n");
4330 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4331 scsi_3btoul(dlist[i].cylinder),
4333 scsi_4btoul(dlist[i].bytes_from_index),
4334 mads ? " - " : "\n");
4338 if (num_valid < num_returned) {
4339 starting_offset += num_valid;
4344 case SRDDH10_BLOCK_FORMAT:
4346 struct scsi_defect_desc_block *dlist;
4348 dlist = (struct scsi_defect_desc_block *)
4349 (defect_list + hdr_size);
4351 for (i = 0; i < num_valid; i++) {
4352 if (hex_format == 0)
4353 fprintf(stdout, "%u\n",
4354 scsi_4btoul(dlist[i].address));
4356 fprintf(stdout, "0x%x\n",
4357 scsi_4btoul(dlist[i].address));
4360 if (num_valid < num_returned) {
4361 starting_offset += num_valid;
4367 case SRDD10_LONG_BLOCK_FORMAT:
4369 struct scsi_defect_desc_long_block *dlist;
4371 dlist = (struct scsi_defect_desc_long_block *)
4372 (defect_list + hdr_size);
4374 for (i = 0; i < num_valid; i++) {
4375 if (hex_format == 0)
4376 fprintf(stdout, "%ju\n",
4377 (uintmax_t)scsi_8btou64(
4380 fprintf(stdout, "0x%jx\n",
4381 (uintmax_t)scsi_8btou64(
4385 if (num_valid < num_returned) {
4386 starting_offset += num_valid;
4392 fprintf(stderr, "Unknown defect format 0x%x\n",
4399 if (defect_list != NULL)
4407 #endif /* MINIMALISTIC */
4411 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4415 ccb = cam_getccb(device);
4421 #ifndef MINIMALISTIC
4423 mode_sense(struct cam_device *device, int *cdb_len, int dbd, int llbaa, int pc,
4424 int page, int subpage, int task_attr, int retry_count, int timeout,
4425 u_int8_t *data, int datalen)
4428 int error_code, sense_key, asc, ascq;
4430 ccb = cam_getccb(device);
4432 errx(1, "mode_sense: couldn't allocate CCB");
4436 * MODE SENSE(6) can't handle more then 255 bytes. If there are more,
4437 * device must return error, so we should not get trucated data.
4439 if (*cdb_len == 6 && datalen > 255)
4442 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4444 scsi_mode_sense_subpage(&ccb->csio,
4445 /* retries */ retry_count,
4447 /* tag_action */ task_attr,
4451 /* subpage */ subpage,
4452 /* param_buf */ data,
4453 /* param_len */ datalen,
4454 /* minimum_cmd_size */ *cdb_len,
4455 /* sense_len */ SSD_FULL_SIZE,
4456 /* timeout */ timeout ? timeout : 5000);
4457 if (llbaa && ccb->csio.cdb_len == 10) {
4458 struct scsi_mode_sense_10 *cdb =
4459 (struct scsi_mode_sense_10 *)ccb->csio.cdb_io.cdb_bytes;
4460 cdb->byte2 |= SMS10_LLBAA;
4463 /* Record what CDB size the above function really set. */
4464 *cdb_len = ccb->csio.cdb_len;
4466 if (arglist & CAM_ARG_ERR_RECOVER)
4467 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4469 /* Disable freezing the device queue */
4470 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4472 if (cam_send_ccb(device, ccb) < 0)
4473 err(1, "error sending mode sense command");
4475 /* In case of ILLEGEL REQUEST try to fall back to 6-byte command. */
4476 if (*cdb_len != 6 &&
4477 ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID ||
4478 (scsi_extract_sense_ccb(ccb, &error_code, &sense_key, &asc, &ascq)
4479 && sense_key == SSD_KEY_ILLEGAL_REQUEST))) {
4484 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4485 if (arglist & CAM_ARG_VERBOSE) {
4486 cam_error_print(device, ccb, CAM_ESF_ALL,
4487 CAM_EPF_ALL, stderr);
4490 cam_close_device(device);
4491 errx(1, "mode sense command returned error");
4498 mode_select(struct cam_device *device, int cdb_len, int save_pages,
4499 int task_attr, int retry_count, int timeout, u_int8_t *data, int datalen)
4504 ccb = cam_getccb(device);
4507 errx(1, "mode_select: couldn't allocate CCB");
4509 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4511 scsi_mode_select_len(&ccb->csio,
4512 /* retries */ retry_count,
4514 /* tag_action */ task_attr,
4515 /* scsi_page_fmt */ 1,
4516 /* save_pages */ save_pages,
4517 /* param_buf */ data,
4518 /* param_len */ datalen,
4519 /* minimum_cmd_size */ cdb_len,
4520 /* sense_len */ SSD_FULL_SIZE,
4521 /* timeout */ timeout ? timeout : 5000);
4523 if (arglist & CAM_ARG_ERR_RECOVER)
4524 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4526 /* Disable freezing the device queue */
4527 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4529 if (((retval = cam_send_ccb(device, ccb)) < 0)
4530 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4531 if (arglist & CAM_ARG_VERBOSE) {
4532 cam_error_print(device, ccb, CAM_ESF_ALL,
4533 CAM_EPF_ALL, stderr);
4536 cam_close_device(device);
4539 err(1, "error sending mode select command");
4541 errx(1, "error sending mode select command");
4549 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4550 int task_attr, int retry_count, int timeout)
4553 int c, page = -1, subpage = 0, pc = 0, llbaa = 0;
4554 int binary = 0, cdb_len = 10, dbd = 0, desc = 0, edit = 0, list = 0;
4556 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4574 str_subpage = optarg;
4575 strsep(&str_subpage, ",");
4576 page = strtol(optarg, NULL, 0);
4578 subpage = strtol(str_subpage, NULL, 0);
4579 if (page < 0 || page > 0x3f)
4580 errx(1, "invalid mode page %d", page);
4581 if (subpage < 0 || subpage > 0xff)
4582 errx(1, "invalid mode subpage %d", subpage);
4591 pc = strtol(optarg, NULL, 0);
4592 if ((pc < 0) || (pc > 3))
4593 errx(1, "invalid page control field %d", pc);
4600 if (desc && page == -1)
4601 page = SMS_ALL_PAGES_PAGE;
4603 if (page == -1 && list == 0)
4604 errx(1, "you must specify a mode page!");
4607 errx(1, "-d and -D are incompatible!");
4609 if (llbaa && cdb_len != 10)
4610 errx(1, "LLBAA bit is not present in MODE SENSE(6)!");
4613 mode_list(device, cdb_len, dbd, pc, list > 1, task_attr,
4614 retry_count, timeout);
4616 mode_edit(device, cdb_len, desc, dbd, llbaa, pc, page, subpage,
4617 edit, binary, task_attr, retry_count, timeout);
4622 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4623 int task_attr, int retry_count, int timeout)
4626 u_int32_t flags = CAM_DIR_NONE;
4627 u_int8_t *data_ptr = NULL;
4629 u_int8_t atacmd[12];
4630 struct get_hook hook;
4631 int c, data_bytes = 0, valid_bytes;
4637 char *datastr = NULL, *tstr, *resstr = NULL;
4639 int fd_data = 0, fd_res = 0;
4642 ccb = cam_getccb(device);
4645 warnx("scsicmd: error allocating ccb");
4649 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4651 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4655 while (isspace(*tstr) && (*tstr != '\0'))
4657 hook.argc = argc - optind;
4658 hook.argv = argv + optind;
4660 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4663 * Increment optind by the number of arguments the
4664 * encoding routine processed. After each call to
4665 * getopt(3), optind points to the argument that
4666 * getopt should process _next_. In this case,
4667 * that means it points to the first command string
4668 * argument, if there is one. Once we increment
4669 * this, it should point to either the next command
4670 * line argument, or it should be past the end of
4677 while (isspace(*tstr) && (*tstr != '\0'))
4679 hook.argc = argc - optind;
4680 hook.argv = argv + optind;
4682 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4685 * Increment optind by the number of arguments the
4686 * encoding routine processed. After each call to
4687 * getopt(3), optind points to the argument that
4688 * getopt should process _next_. In this case,
4689 * that means it points to the first command string
4690 * argument, if there is one. Once we increment
4691 * this, it should point to either the next command
4692 * line argument, or it should be past the end of
4704 if (arglist & CAM_ARG_CMD_OUT) {
4705 warnx("command must either be "
4706 "read or write, not both");
4708 goto scsicmd_bailout;
4710 arglist |= CAM_ARG_CMD_IN;
4712 data_bytes = strtol(optarg, NULL, 0);
4713 if (data_bytes <= 0) {
4714 warnx("invalid number of input bytes %d",
4717 goto scsicmd_bailout;
4719 hook.argc = argc - optind;
4720 hook.argv = argv + optind;
4723 datastr = cget(&hook, NULL);
4725 * If the user supplied "-" instead of a format, he
4726 * wants the data to be written to stdout.
4728 if ((datastr != NULL)
4729 && (datastr[0] == '-'))
4732 data_ptr = (u_int8_t *)malloc(data_bytes);
4733 if (data_ptr == NULL) {
4734 warnx("can't malloc memory for data_ptr");
4736 goto scsicmd_bailout;
4740 if (arglist & CAM_ARG_CMD_IN) {
4741 warnx("command must either be "
4742 "read or write, not both");
4744 goto scsicmd_bailout;
4746 arglist |= CAM_ARG_CMD_OUT;
4747 flags = CAM_DIR_OUT;
4748 data_bytes = strtol(optarg, NULL, 0);
4749 if (data_bytes <= 0) {
4750 warnx("invalid number of output bytes %d",
4753 goto scsicmd_bailout;
4755 hook.argc = argc - optind;
4756 hook.argv = argv + optind;
4758 datastr = cget(&hook, NULL);
4759 data_ptr = (u_int8_t *)malloc(data_bytes);
4760 if (data_ptr == NULL) {
4761 warnx("can't malloc memory for data_ptr");
4763 goto scsicmd_bailout;
4765 bzero(data_ptr, data_bytes);
4767 * If the user supplied "-" instead of a format, he
4768 * wants the data to be read from stdin.
4770 if ((datastr != NULL)
4771 && (datastr[0] == '-'))
4774 buff_encode_visit(data_ptr, data_bytes, datastr,
4780 hook.argc = argc - optind;
4781 hook.argv = argv + optind;
4783 resstr = cget(&hook, NULL);
4784 if ((resstr != NULL) && (resstr[0] == '-'))
4794 * If fd_data is set, and we're writing to the device, we need to
4795 * read the data the user wants written from stdin.
4797 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4799 int amt_to_read = data_bytes;
4800 u_int8_t *buf_ptr = data_ptr;
4802 for (amt_read = 0; amt_to_read > 0;
4803 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4804 if (amt_read == -1) {
4805 warn("error reading data from stdin");
4807 goto scsicmd_bailout;
4809 amt_to_read -= amt_read;
4810 buf_ptr += amt_read;
4814 if (arglist & CAM_ARG_ERR_RECOVER)
4815 flags |= CAM_PASS_ERR_RECOVER;
4817 /* Disable freezing the device queue */
4818 flags |= CAM_DEV_QFRZDIS;
4822 * This is taken from the SCSI-3 draft spec.
4823 * (T10/1157D revision 0.3)
4824 * The top 3 bits of an opcode are the group code.
4825 * The next 5 bits are the command code.
4826 * Group 0: six byte commands
4827 * Group 1: ten byte commands
4828 * Group 2: ten byte commands
4830 * Group 4: sixteen byte commands
4831 * Group 5: twelve byte commands
4832 * Group 6: vendor specific
4833 * Group 7: vendor specific
4835 switch((cdb[0] >> 5) & 0x7) {
4846 /* computed by buff_encode_visit */
4857 * We should probably use csio_build_visit or something like that
4858 * here, but it's easier to encode arguments as you go. The
4859 * alternative would be skipping the CDB argument and then encoding
4860 * it here, since we've got the data buffer argument by now.
4862 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4864 cam_fill_csio(&ccb->csio,
4865 /*retries*/ retry_count,
4868 /*tag_action*/ task_attr,
4869 /*data_ptr*/ data_ptr,
4870 /*dxfer_len*/ data_bytes,
4871 /*sense_len*/ SSD_FULL_SIZE,
4872 /*cdb_len*/ cdb_len,
4873 /*timeout*/ timeout ? timeout : 5000);
4876 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4878 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4880 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4882 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4884 cam_fill_ataio(&ccb->ataio,
4885 /*retries*/ retry_count,
4889 /*data_ptr*/ data_ptr,
4890 /*dxfer_len*/ data_bytes,
4891 /*timeout*/ timeout ? timeout : 5000);
4894 if (((retval = cam_send_ccb(device, ccb)) < 0)
4895 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4896 const char warnstr[] = "error sending command";
4903 if (arglist & CAM_ARG_VERBOSE) {
4904 cam_error_print(device, ccb, CAM_ESF_ALL,
4905 CAM_EPF_ALL, stderr);
4909 goto scsicmd_bailout;
4912 if (atacmd_len && need_res) {
4914 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4916 fprintf(stdout, "\n");
4919 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4920 ccb->ataio.res.status,
4921 ccb->ataio.res.error,
4922 ccb->ataio.res.lba_low,
4923 ccb->ataio.res.lba_mid,
4924 ccb->ataio.res.lba_high,
4925 ccb->ataio.res.device,
4926 ccb->ataio.res.lba_low_exp,
4927 ccb->ataio.res.lba_mid_exp,
4928 ccb->ataio.res.lba_high_exp,
4929 ccb->ataio.res.sector_count,
4930 ccb->ataio.res.sector_count_exp);
4936 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4938 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4939 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4940 && (arglist & CAM_ARG_CMD_IN)
4941 && (valid_bytes > 0)) {
4943 buff_decode_visit(data_ptr, valid_bytes, datastr,
4945 fprintf(stdout, "\n");
4947 ssize_t amt_written;
4948 int amt_to_write = valid_bytes;
4949 u_int8_t *buf_ptr = data_ptr;
4951 for (amt_written = 0; (amt_to_write > 0) &&
4952 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4953 amt_to_write -= amt_written;
4954 buf_ptr += amt_written;
4956 if (amt_written == -1) {
4957 warn("error writing data to stdout");
4959 goto scsicmd_bailout;
4960 } else if ((amt_written == 0)
4961 && (amt_to_write > 0)) {
4962 warnx("only wrote %u bytes out of %u",
4963 valid_bytes - amt_to_write, valid_bytes);
4970 if ((data_bytes > 0) && (data_ptr != NULL))
4979 camdebug(int argc, char **argv, char *combinedopt)
4982 path_id_t bus = CAM_BUS_WILDCARD;
4983 target_id_t target = CAM_TARGET_WILDCARD;
4984 lun_id_t lun = CAM_LUN_WILDCARD;
4989 bzero(&ccb, sizeof(union ccb));
4991 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4994 arglist |= CAM_ARG_DEBUG_INFO;
4995 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4998 arglist |= CAM_ARG_DEBUG_PERIPH;
4999 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
5002 arglist |= CAM_ARG_DEBUG_SUBTRACE;
5003 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
5006 arglist |= CAM_ARG_DEBUG_TRACE;
5007 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
5010 arglist |= CAM_ARG_DEBUG_XPT;
5011 ccb.cdbg.flags |= CAM_DEBUG_XPT;
5014 arglist |= CAM_ARG_DEBUG_CDB;
5015 ccb.cdbg.flags |= CAM_DEBUG_CDB;
5018 arglist |= CAM_ARG_DEBUG_PROBE;
5019 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
5030 warnx("you must specify \"off\", \"all\" or a bus,");
5031 warnx("bus:target, bus:target:lun or periph");
5036 while (isspace(*tstr) && (*tstr != '\0'))
5039 if (strncmp(tstr, "off", 3) == 0) {
5040 ccb.cdbg.flags = CAM_DEBUG_NONE;
5041 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
5042 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
5043 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
5045 rv = parse_btl(tstr, &bus, &target, &lun, &arglist);
5047 warnx("you must specify \"all\", \"off\", or a bus,");
5048 warnx("bus:target, bus:target:lun or periph to debug");
5053 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
5054 warnx("error opening transport layer device %s", XPT_DEVICE);
5055 warn("%s", XPT_DEVICE);
5059 ccb.ccb_h.func_code = XPT_DEBUG;
5060 ccb.ccb_h.path_id = bus;
5061 ccb.ccb_h.target_id = target;
5062 ccb.ccb_h.target_lun = lun;
5064 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
5065 warn("CAMIOCOMMAND ioctl failed");
5068 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
5069 CAM_FUNC_NOTAVAIL) {
5070 warnx("CAM debugging not available");
5071 warnx("you need to put options CAMDEBUG in"
5072 " your kernel config file!");
5074 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
5076 warnx("XPT_DEBUG CCB failed with status %#x",
5080 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
5082 "Debugging turned off\n");
5085 "Debugging enabled for "
5087 bus, target, (uintmax_t)lun);
5097 tagcontrol(struct cam_device *device, int argc, char **argv,
5107 ccb = cam_getccb(device);
5110 warnx("tagcontrol: error allocating ccb");
5114 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5117 numtags = strtol(optarg, NULL, 0);
5119 warnx("tag count %d is < 0", numtags);
5121 goto tagcontrol_bailout;
5132 cam_path_string(device, pathstr, sizeof(pathstr));
5135 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
5136 ccb->ccb_h.func_code = XPT_REL_SIMQ;
5137 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5138 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5139 ccb->crs.openings = numtags;
5142 if (cam_send_ccb(device, ccb) < 0) {
5143 warn("error sending XPT_REL_SIMQ CCB");
5145 goto tagcontrol_bailout;
5148 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5149 warnx("XPT_REL_SIMQ CCB failed");
5150 cam_error_print(device, ccb, CAM_ESF_ALL,
5151 CAM_EPF_ALL, stderr);
5153 goto tagcontrol_bailout;
5158 fprintf(stdout, "%stagged openings now %d\n",
5159 pathstr, ccb->crs.openings);
5162 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5164 ccb->ccb_h.func_code = XPT_GDEV_STATS;
5166 if (cam_send_ccb(device, ccb) < 0) {
5167 warn("error sending XPT_GDEV_STATS CCB");
5169 goto tagcontrol_bailout;
5172 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5173 warnx("XPT_GDEV_STATS CCB failed");
5174 cam_error_print(device, ccb, CAM_ESF_ALL,
5175 CAM_EPF_ALL, stderr);
5177 goto tagcontrol_bailout;
5180 if (arglist & CAM_ARG_VERBOSE) {
5181 fprintf(stdout, "%s", pathstr);
5182 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5183 fprintf(stdout, "%s", pathstr);
5184 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5185 fprintf(stdout, "%s", pathstr);
5186 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5187 fprintf(stdout, "%s", pathstr);
5188 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5189 fprintf(stdout, "%s", pathstr);
5190 fprintf(stdout, "held %d\n", ccb->cgds.held);
5191 fprintf(stdout, "%s", pathstr);
5192 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5193 fprintf(stdout, "%s", pathstr);
5194 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5197 fprintf(stdout, "%s", pathstr);
5198 fprintf(stdout, "device openings: ");
5200 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5201 ccb->cgds.dev_active);
5211 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5215 cam_path_string(device, pathstr, sizeof(pathstr));
5217 if (cts->transport == XPORT_SPI) {
5218 struct ccb_trans_settings_spi *spi =
5219 &cts->xport_specific.spi;
5221 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5223 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5226 if (spi->sync_offset != 0) {
5229 freq = scsi_calc_syncsrate(spi->sync_period);
5230 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5231 pathstr, freq / 1000, freq % 1000);
5235 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5236 fprintf(stdout, "%soffset: %d\n", pathstr,
5240 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5241 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5242 (0x01 << spi->bus_width) * 8);
5245 if (spi->valid & CTS_SPI_VALID_DISC) {
5246 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5247 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5248 "enabled" : "disabled");
5251 if (cts->transport == XPORT_FC) {
5252 struct ccb_trans_settings_fc *fc =
5253 &cts->xport_specific.fc;
5255 if (fc->valid & CTS_FC_VALID_WWNN)
5256 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5257 (long long) fc->wwnn);
5258 if (fc->valid & CTS_FC_VALID_WWPN)
5259 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5260 (long long) fc->wwpn);
5261 if (fc->valid & CTS_FC_VALID_PORT)
5262 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5263 if (fc->valid & CTS_FC_VALID_SPEED)
5264 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5265 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5267 if (cts->transport == XPORT_SAS) {
5268 struct ccb_trans_settings_sas *sas =
5269 &cts->xport_specific.sas;
5271 if (sas->valid & CTS_SAS_VALID_SPEED)
5272 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5273 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5275 if (cts->transport == XPORT_ATA) {
5276 struct ccb_trans_settings_pata *pata =
5277 &cts->xport_specific.ata;
5279 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5280 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5281 ata_mode2string(pata->mode));
5283 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5284 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5287 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5288 fprintf(stdout, "%sPIO transaction length: %d\n",
5289 pathstr, pata->bytecount);
5292 if (cts->transport == XPORT_SATA) {
5293 struct ccb_trans_settings_sata *sata =
5294 &cts->xport_specific.sata;
5296 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5297 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5300 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5301 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5302 ata_mode2string(sata->mode));
5304 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5305 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5308 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5309 fprintf(stdout, "%sPIO transaction length: %d\n",
5310 pathstr, sata->bytecount);
5312 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5313 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5316 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5317 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5320 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5321 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5325 if (cts->protocol == PROTO_ATA) {
5326 struct ccb_trans_settings_ata *ata=
5327 &cts->proto_specific.ata;
5329 if (ata->valid & CTS_ATA_VALID_TQ) {
5330 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5331 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5332 "enabled" : "disabled");
5335 if (cts->protocol == PROTO_SCSI) {
5336 struct ccb_trans_settings_scsi *scsi=
5337 &cts->proto_specific.scsi;
5339 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5340 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5341 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5342 "enabled" : "disabled");
5346 if (cts->protocol == PROTO_NVME) {
5347 struct ccb_trans_settings_nvme *nvmex =
5348 &cts->xport_specific.nvme;
5350 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5351 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5352 NVME_MAJOR(nvmex->spec),
5353 NVME_MINOR(nvmex->spec));
5355 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5356 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5357 nvmex->lanes, nvmex->max_lanes);
5358 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5359 nvmex->speed, nvmex->max_speed);
5366 * Get a path inquiry CCB for the specified device.
5369 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5374 ccb = cam_getccb(device);
5376 warnx("get_cpi: couldn't allocate CCB");
5379 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5380 ccb->ccb_h.func_code = XPT_PATH_INQ;
5381 if (cam_send_ccb(device, ccb) < 0) {
5382 warn("get_cpi: error sending Path Inquiry CCB");
5384 goto get_cpi_bailout;
5386 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5387 if (arglist & CAM_ARG_VERBOSE)
5388 cam_error_print(device, ccb, CAM_ESF_ALL,
5389 CAM_EPF_ALL, stderr);
5391 goto get_cpi_bailout;
5393 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5401 * Get a get device CCB for the specified device.
5404 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5409 ccb = cam_getccb(device);
5411 warnx("get_cgd: couldn't allocate CCB");
5414 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5415 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5416 if (cam_send_ccb(device, ccb) < 0) {
5417 warn("get_cgd: error sending Get type information CCB");
5419 goto get_cgd_bailout;
5421 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5422 if (arglist & CAM_ARG_VERBOSE)
5423 cam_error_print(device, ccb, CAM_ESF_ALL,
5424 CAM_EPF_ALL, stderr);
5426 goto get_cgd_bailout;
5428 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5436 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5440 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5441 int timeout, int verbosemode)
5443 union ccb *ccb = NULL;
5444 struct scsi_vpd_supported_page_list sup_pages;
5448 ccb = cam_getccb(dev);
5450 warn("Unable to allocate CCB");
5455 /* cam_getccb cleans up the header, caller has to zero the payload */
5456 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5458 bzero(&sup_pages, sizeof(sup_pages));
5460 scsi_inquiry(&ccb->csio,
5461 /*retries*/ retry_count,
5463 /* tag_action */ MSG_SIMPLE_Q_TAG,
5464 /* inq_buf */ (u_int8_t *)&sup_pages,
5465 /* inq_len */ sizeof(sup_pages),
5467 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5468 /* sense_len */ SSD_FULL_SIZE,
5469 /* timeout */ timeout ? timeout : 5000);
5471 /* Disable freezing the device queue */
5472 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5474 if (retry_count != 0)
5475 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5477 if (cam_send_ccb(dev, ccb) < 0) {
5484 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5485 if (verbosemode != 0)
5486 cam_error_print(dev, ccb, CAM_ESF_ALL,
5487 CAM_EPF_ALL, stderr);
5492 for (i = 0; i < sup_pages.length; i++) {
5493 if (sup_pages.list[i] == page_id) {
5506 * devtype is filled in with the type of device.
5507 * Returns 0 for success, non-zero for failure.
5510 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5511 int verbosemode, camcontrol_devtype *devtype)
5513 struct ccb_getdev cgd;
5516 retval = get_cgd(dev, &cgd);
5520 switch (cgd.protocol) {
5526 *devtype = CC_DT_ATA;
5528 break; /*NOTREACHED*/
5530 *devtype = CC_DT_NVME;
5532 break; /*NOTREACHED*/
5534 *devtype = CC_DT_MMCSD;
5536 break; /*NOTREACHED*/
5538 *devtype = CC_DT_UNKNOWN;
5540 break; /*NOTREACHED*/
5543 if (retry_count == -1) {
5545 * For a retry count of -1, used only the cached data to avoid
5546 * I/O to the drive. Sending the identify command to the drive
5547 * can cause issues for SATL attachaed drives since identify is
5548 * not an NCQ command.
5550 if (cgd.ident_data.config != 0)
5551 *devtype = CC_DT_SATL;
5553 *devtype = CC_DT_SCSI;
5556 * Check for the ATA Information VPD page (0x89). If this is an
5557 * ATA device behind a SCSI to ATA translation layer (SATL),
5558 * this VPD page should be present.
5560 * If that VPD page isn't present, or we get an error back from
5561 * the INQUIRY command, we'll just treat it as a normal SCSI
5564 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5565 timeout, verbosemode);
5567 *devtype = CC_DT_SATL;
5569 *devtype = CC_DT_SCSI;
5578 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5579 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5580 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5581 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5582 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5583 int is48bit, camcontrol_devtype devtype)
5587 if (devtype == CC_DT_ATA) {
5588 cam_fill_ataio(&ccb->ataio,
5589 /*retries*/ retry_count,
5592 /*tag_action*/ tag_action,
5593 /*data_ptr*/ data_ptr,
5594 /*dxfer_len*/ dxfer_len,
5595 /*timeout*/ timeout);
5596 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5597 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5600 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5603 if (auxiliary != 0) {
5604 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5605 ccb->ataio.aux = auxiliary;
5608 if (ata_flags & AP_FLAG_CHK_COND)
5609 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5611 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5612 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5613 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5614 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5616 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5617 protocol |= AP_EXTEND;
5619 retval = scsi_ata_pass(&ccb->csio,
5620 /*retries*/ retry_count,
5623 /*tag_action*/ tag_action,
5624 /*protocol*/ protocol,
5625 /*ata_flags*/ ata_flags,
5626 /*features*/ features,
5627 /*sector_count*/ sector_count,
5629 /*command*/ command,
5632 /*auxiliary*/ auxiliary,
5634 /*data_ptr*/ data_ptr,
5635 /*dxfer_len*/ dxfer_len,
5636 /*cdb_storage*/ cdb_storage,
5637 /*cdb_storage_len*/ cdb_storage_len,
5638 /*minimum_cmd_size*/ 0,
5639 /*sense_len*/ sense_len,
5640 /*timeout*/ timeout);
5647 * Returns: 0 -- success, 1 -- error, 2 -- lba truncated,
5648 * 4 -- count truncated, 6 -- lba and count truncated.
5651 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5652 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5656 switch (ccb->ccb_h.func_code) {
5659 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5663 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5664 * or 16 byte, and need to see what
5666 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5667 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5669 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5670 if ((opcode != ATA_PASS_12)
5671 && (opcode != ATA_PASS_16)) {
5672 warnx("%s: unsupported opcode %02x", __func__, opcode);
5676 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5678 /* Note: the _ccb() variant returns 0 for an error */
5682 sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
5683 switch (error_code) {
5684 case SSD_DESC_CURRENT_ERROR:
5685 case SSD_DESC_DEFERRED_ERROR: {
5686 struct scsi_sense_data_desc *sense;
5687 struct scsi_sense_ata_ret_desc *desc;
5690 sense = (struct scsi_sense_data_desc *)
5691 &ccb->csio.sense_data;
5693 desc_ptr = scsi_find_desc(sense, sense_len,
5695 if (desc_ptr == NULL) {
5696 cam_error_print(dev, ccb, CAM_ESF_ALL,
5697 CAM_EPF_ALL, stderr);
5700 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5702 *error = desc->error;
5703 *count = (desc->count_15_8 << 8) |
5705 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5706 ((uint64_t)desc->lba_39_32 << 32) |
5707 ((uint64_t)desc->lba_31_24 << 24) |
5708 (desc->lba_23_16 << 16) |
5709 (desc->lba_15_8 << 8) |
5711 *device = desc->device;
5712 *status = desc->status;
5715 * If the extend bit isn't set, the result is for a
5716 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5717 * command without the extend bit set. This means
5718 * that the device is supposed to return 28-bit
5719 * status. The count field is only 8 bits, and the
5720 * LBA field is only 8 bits.
5722 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5728 case SSD_CURRENT_ERROR:
5729 case SSD_DEFERRED_ERROR: {
5733 * In my understanding of SAT-5 specification, saying:
5734 * "without interpreting the contents of the STATUS",
5735 * this should not happen if CK_COND was set, but it
5736 * does at least for some devices, so try to revert.
5738 if ((sense_key == SSD_KEY_ABORTED_COMMAND) &&
5739 (asc == 0) && (ascq == 0)) {
5740 *status = ATA_STATUS_ERROR;
5741 *error = ATA_ERROR_ABORT;
5748 if ((sense_key != SSD_KEY_RECOVERED_ERROR) ||
5749 (asc != 0x00) || (ascq != 0x1d))
5753 scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5754 SSD_DESC_INFO, &val, NULL);
5755 *error = (val >> 24) & 0xff;
5756 *status = (val >> 16) & 0xff;
5757 *device = (val >> 8) & 0xff;
5758 *count = val & 0xff;
5761 scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5762 SSD_DESC_COMMAND, &val, NULL);
5763 *lba = ((val >> 16) & 0xff) | (val & 0xff00) |
5764 ((val & 0xff) << 16);
5766 /* Report UPPER NONZERO bits as errors 2, 4 and 6. */
5767 return ((val >> 28) & 0x06);
5776 struct ata_res *res;
5778 /* Only some statuses return ATA result register set. */
5779 if (cam_ccb_status(ccb) != CAM_REQ_CMP &&
5780 cam_ccb_status(ccb) != CAM_ATA_STATUS_ERROR)
5783 res = &ccb->ataio.res;
5784 *error = res->error;
5785 *status = res->status;
5786 *device = res->device;
5787 *count = res->sector_count;
5788 *lba = (res->lba_high << 16) |
5789 (res->lba_mid << 8) |
5791 if (ccb->ataio.cmd.flags & CAM_ATAIO_48BIT) {
5792 *count |= (res->sector_count_exp << 8);
5793 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5794 ((uint64_t)res->lba_mid_exp << 32) |
5795 ((uint64_t)res->lba_high_exp << 40);
5797 *lba |= (res->device & 0xf) << 24;
5808 cpi_print(struct ccb_pathinq *cpi)
5810 char adapter_str[1024];
5813 snprintf(adapter_str, sizeof(adapter_str),
5814 "%s%d:", cpi->dev_name, cpi->unit_number);
5816 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5819 for (i = 1; i < UINT8_MAX; i = i << 1) {
5822 if ((i & cpi->hba_inquiry) == 0)
5825 fprintf(stdout, "%s supports ", adapter_str);
5829 str = "MDP message";
5832 str = "32 bit wide SCSI";
5835 str = "16 bit wide SCSI";
5838 str = "SDTR message";
5841 str = "linked CDBs";
5844 str = "tag queue messages";
5847 str = "soft reset alternative";
5850 str = "SATA Port Multiplier";
5853 str = "unknown PI bit set";
5856 fprintf(stdout, "%s\n", str);
5859 for (i = 1; i < UINT32_MAX; i = i << 1) {
5862 if ((i & cpi->hba_misc) == 0)
5865 fprintf(stdout, "%s ", adapter_str);
5869 str = "can understand ata_ext requests";
5872 str = "64bit extended LUNs supported";
5875 str = "bus scans from high ID to low ID";
5878 str = "removable devices not included in scan";
5880 case PIM_NOINITIATOR:
5881 str = "initiator role not supported";
5883 case PIM_NOBUSRESET:
5884 str = "user has disabled initial BUS RESET or"
5885 " controller is in target/mixed mode";
5888 str = "do not send 6-byte commands";
5891 str = "scan bus sequentially";
5894 str = "unmapped I/O supported";
5897 str = "does its own scanning";
5900 str = "unknown PIM bit set";
5903 fprintf(stdout, "%s\n", str);
5906 for (i = 1; i < UINT16_MAX; i = i << 1) {
5909 if ((i & cpi->target_sprt) == 0)
5912 fprintf(stdout, "%s supports ", adapter_str);
5915 str = "target mode processor mode";
5918 str = "target mode phase cog. mode";
5920 case PIT_DISCONNECT:
5921 str = "disconnects in target mode";
5924 str = "terminate I/O message in target mode";
5927 str = "group 6 commands in target mode";
5930 str = "group 7 commands in target mode";
5933 str = "unknown PIT bit set";
5937 fprintf(stdout, "%s\n", str);
5939 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5941 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5943 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5945 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5946 adapter_str, cpi->hpath_id);
5947 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5949 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5950 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5951 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5952 adapter_str, cpi->hba_vendor);
5953 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5954 adapter_str, cpi->hba_device);
5955 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5956 adapter_str, cpi->hba_subvendor);
5957 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5958 adapter_str, cpi->hba_subdevice);
5959 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5960 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5961 if (cpi->base_transfer_speed > 1000)
5962 fprintf(stdout, "%d.%03dMB/sec\n",
5963 cpi->base_transfer_speed / 1000,
5964 cpi->base_transfer_speed % 1000);
5966 fprintf(stdout, "%dKB/sec\n",
5967 (cpi->base_transfer_speed % 1000) * 1000);
5968 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5969 adapter_str, cpi->maxio);
5973 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5974 struct ccb_trans_settings *cts)
5980 ccb = cam_getccb(device);
5983 warnx("get_print_cts: error allocating ccb");
5987 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5989 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5991 if (user_settings == 0)
5992 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5994 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5996 if (cam_send_ccb(device, ccb) < 0) {
5997 warn("error sending XPT_GET_TRAN_SETTINGS CCB");
5999 goto get_print_cts_bailout;
6002 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6003 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
6004 if (arglist & CAM_ARG_VERBOSE)
6005 cam_error_print(device, ccb, CAM_ESF_ALL,
6006 CAM_EPF_ALL, stderr);
6008 goto get_print_cts_bailout;
6012 cts_print(device, &ccb->cts);
6015 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
6017 get_print_cts_bailout:
6025 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
6026 int timeout, int argc, char **argv, char *combinedopt)
6030 int user_settings = 0;
6032 int disc_enable = -1, tag_enable = -1;
6035 double syncrate = -1;
6038 int change_settings = 0, send_tur = 0;
6039 struct ccb_pathinq cpi;
6041 ccb = cam_getccb(device);
6043 warnx("ratecontrol: error allocating ccb");
6046 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6055 if (strncasecmp(optarg, "enable", 6) == 0)
6057 else if (strncasecmp(optarg, "disable", 7) == 0)
6060 warnx("-D argument \"%s\" is unknown", optarg);
6062 goto ratecontrol_bailout;
6064 change_settings = 1;
6067 mode = ata_string2mode(optarg);
6069 warnx("unknown mode '%s'", optarg);
6071 goto ratecontrol_bailout;
6073 change_settings = 1;
6076 offset = strtol(optarg, NULL, 0);
6078 warnx("offset value %d is < 0", offset);
6080 goto ratecontrol_bailout;
6082 change_settings = 1;
6088 syncrate = atof(optarg);
6090 warnx("sync rate %f is < 0", syncrate);
6092 goto ratecontrol_bailout;
6094 change_settings = 1;
6097 if (strncasecmp(optarg, "enable", 6) == 0)
6099 else if (strncasecmp(optarg, "disable", 7) == 0)
6102 warnx("-T argument \"%s\" is unknown", optarg);
6104 goto ratecontrol_bailout;
6106 change_settings = 1;
6112 bus_width = strtol(optarg, NULL, 0);
6113 if (bus_width < 0) {
6114 warnx("bus width %d is < 0", bus_width);
6116 goto ratecontrol_bailout;
6118 change_settings = 1;
6125 * Grab path inquiry information, so we can determine whether
6126 * or not the initiator is capable of the things that the user
6129 if ((retval = get_cpi(device, &cpi)) != 0)
6130 goto ratecontrol_bailout;
6131 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
6133 fprintf(stdout, "%s parameters:\n",
6134 user_settings ? "User" : "Current");
6136 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
6138 goto ratecontrol_bailout;
6140 if (arglist & CAM_ARG_VERBOSE)
6143 if (change_settings) {
6144 int didsettings = 0;
6145 struct ccb_trans_settings_spi *spi = NULL;
6146 struct ccb_trans_settings_pata *pata = NULL;
6147 struct ccb_trans_settings_sata *sata = NULL;
6148 struct ccb_trans_settings_ata *ata = NULL;
6149 struct ccb_trans_settings_scsi *scsi = NULL;
6151 if (ccb->cts.transport == XPORT_SPI)
6152 spi = &ccb->cts.xport_specific.spi;
6153 if (ccb->cts.transport == XPORT_ATA)
6154 pata = &ccb->cts.xport_specific.ata;
6155 if (ccb->cts.transport == XPORT_SATA)
6156 sata = &ccb->cts.xport_specific.sata;
6157 if (ccb->cts.protocol == PROTO_ATA)
6158 ata = &ccb->cts.proto_specific.ata;
6159 if (ccb->cts.protocol == PROTO_SCSI)
6160 scsi = &ccb->cts.proto_specific.scsi;
6161 ccb->cts.xport_specific.valid = 0;
6162 ccb->cts.proto_specific.valid = 0;
6163 if (spi && disc_enable != -1) {
6164 spi->valid |= CTS_SPI_VALID_DISC;
6165 if (disc_enable == 0)
6166 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6168 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6171 if (tag_enable != -1) {
6172 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6173 warnx("HBA does not support tagged queueing, "
6174 "so you cannot modify tag settings");
6176 goto ratecontrol_bailout;
6179 ata->valid |= CTS_SCSI_VALID_TQ;
6180 if (tag_enable == 0)
6181 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6183 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6186 scsi->valid |= CTS_SCSI_VALID_TQ;
6187 if (tag_enable == 0)
6188 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6190 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6194 if (spi && offset != -1) {
6195 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6196 warnx("HBA is not capable of changing offset");
6198 goto ratecontrol_bailout;
6200 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6201 spi->sync_offset = offset;
6204 if (spi && syncrate != -1) {
6205 int prelim_sync_period;
6207 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6208 warnx("HBA is not capable of changing "
6211 goto ratecontrol_bailout;
6213 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6215 * The sync rate the user gives us is in MHz.
6216 * We need to translate it into KHz for this
6221 * Next, we calculate a "preliminary" sync period
6222 * in tenths of a nanosecond.
6225 prelim_sync_period = 0;
6227 prelim_sync_period = 10000000 / syncrate;
6229 scsi_calc_syncparam(prelim_sync_period);
6232 if (sata && syncrate != -1) {
6233 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6234 warnx("HBA is not capable of changing "
6237 goto ratecontrol_bailout;
6239 if (!user_settings) {
6240 warnx("You can modify only user rate "
6241 "settings for SATA");
6243 goto ratecontrol_bailout;
6245 sata->revision = ata_speed2revision(syncrate * 100);
6246 if (sata->revision < 0) {
6247 warnx("Invalid rate %f", syncrate);
6249 goto ratecontrol_bailout;
6251 sata->valid |= CTS_SATA_VALID_REVISION;
6254 if ((pata || sata) && mode != -1) {
6255 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6256 warnx("HBA is not capable of changing "
6259 goto ratecontrol_bailout;
6261 if (!user_settings) {
6262 warnx("You can modify only user mode "
6263 "settings for ATA/SATA");
6265 goto ratecontrol_bailout;
6269 pata->valid |= CTS_ATA_VALID_MODE;
6272 sata->valid |= CTS_SATA_VALID_MODE;
6277 * The bus_width argument goes like this:
6281 * Therefore, if you shift the number of bits given on the
6282 * command line right by 4, you should get the correct
6285 if (spi && bus_width != -1) {
6287 * We might as well validate things here with a
6288 * decipherable error message, rather than what
6289 * will probably be an indecipherable error message
6290 * by the time it gets back to us.
6292 if ((bus_width == 16)
6293 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6294 warnx("HBA does not support 16 bit bus width");
6296 goto ratecontrol_bailout;
6297 } else if ((bus_width == 32)
6298 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6299 warnx("HBA does not support 32 bit bus width");
6301 goto ratecontrol_bailout;
6302 } else if ((bus_width != 8)
6303 && (bus_width != 16)
6304 && (bus_width != 32)) {
6305 warnx("Invalid bus width %d", bus_width);
6307 goto ratecontrol_bailout;
6309 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6310 spi->bus_width = bus_width >> 4;
6313 if (didsettings == 0) {
6314 goto ratecontrol_bailout;
6316 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6317 if (cam_send_ccb(device, ccb) < 0) {
6318 warn("error sending XPT_SET_TRAN_SETTINGS CCB");
6320 goto ratecontrol_bailout;
6322 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6323 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6324 if (arglist & CAM_ARG_VERBOSE) {
6325 cam_error_print(device, ccb, CAM_ESF_ALL,
6326 CAM_EPF_ALL, stderr);
6329 goto ratecontrol_bailout;
6333 retval = testunitready(device, task_attr, retry_count, timeout,
6334 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6336 * If the TUR didn't succeed, just bail.
6340 fprintf(stderr, "Test Unit Ready failed\n");
6341 goto ratecontrol_bailout;
6344 if ((change_settings || send_tur) && !quiet &&
6345 (ccb->cts.transport == XPORT_ATA ||
6346 ccb->cts.transport == XPORT_SATA || send_tur)) {
6347 fprintf(stdout, "New parameters:\n");
6348 retval = get_print_cts(device, user_settings, 0, NULL);
6351 ratecontrol_bailout:
6357 scsiformat(struct cam_device *device, int argc, char **argv,
6358 char *combinedopt, int task_attr, int retry_count, int timeout)
6362 int ycount = 0, quiet = 0;
6363 int error = 0, retval = 0;
6364 int use_timeout = 10800 * 1000;
6366 struct format_defect_list_header fh;
6367 u_int8_t *data_ptr = NULL;
6368 u_int32_t dxfer_len = 0;
6370 int num_warnings = 0;
6373 ccb = cam_getccb(device);
6376 warnx("scsiformat: error allocating ccb");
6380 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6382 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6402 if (quiet == 0 && ycount == 0) {
6403 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6404 "following device:\n");
6406 error = scsidoinquiry(device, argc, argv, combinedopt,
6407 task_attr, retry_count, timeout);
6410 warnx("scsiformat: error sending inquiry");
6411 goto scsiformat_bailout;
6416 if (!get_confirmation()) {
6418 goto scsiformat_bailout;
6423 use_timeout = timeout;
6426 fprintf(stdout, "Current format timeout is %d seconds\n",
6427 use_timeout / 1000);
6431 * If the user hasn't disabled questions and didn't specify a
6432 * timeout on the command line, ask them if they want the current
6436 && (timeout == 0)) {
6438 int new_timeout = 0;
6440 fprintf(stdout, "Enter new timeout in seconds or press\n"
6441 "return to keep the current timeout [%d] ",
6442 use_timeout / 1000);
6444 if (fgets(str, sizeof(str), stdin) != NULL) {
6446 new_timeout = atoi(str);
6449 if (new_timeout != 0) {
6450 use_timeout = new_timeout * 1000;
6451 fprintf(stdout, "Using new timeout value %d\n",
6452 use_timeout / 1000);
6457 * Keep this outside the if block below to silence any unused
6458 * variable warnings.
6460 bzero(&fh, sizeof(fh));
6463 * If we're in immediate mode, we've got to include the format
6466 if (immediate != 0) {
6467 fh.byte2 = FU_DLH_IMMED;
6468 data_ptr = (u_int8_t *)&fh;
6469 dxfer_len = sizeof(fh);
6470 byte2 = FU_FMT_DATA;
6471 } else if (quiet == 0) {
6472 fprintf(stdout, "Formatting...");
6476 scsi_format_unit(&ccb->csio,
6477 /* retries */ retry_count,
6479 /* tag_action */ task_attr,
6482 /* data_ptr */ data_ptr,
6483 /* dxfer_len */ dxfer_len,
6484 /* sense_len */ SSD_FULL_SIZE,
6485 /* timeout */ use_timeout);
6487 /* Disable freezing the device queue */
6488 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6490 if (arglist & CAM_ARG_ERR_RECOVER)
6491 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6493 if (((retval = cam_send_ccb(device, ccb)) < 0)
6494 || ((immediate == 0)
6495 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6496 const char errstr[] = "error sending format command";
6503 if (arglist & CAM_ARG_VERBOSE) {
6504 cam_error_print(device, ccb, CAM_ESF_ALL,
6505 CAM_EPF_ALL, stderr);
6508 goto scsiformat_bailout;
6512 * If we ran in non-immediate mode, we already checked for errors
6513 * above and printed out any necessary information. If we're in
6514 * immediate mode, we need to loop through and get status
6515 * information periodically.
6517 if (immediate == 0) {
6519 fprintf(stdout, "Format Complete\n");
6521 goto scsiformat_bailout;
6528 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6531 * There's really no need to do error recovery or
6532 * retries here, since we're just going to sit in a
6533 * loop and wait for the device to finish formatting.
6535 scsi_test_unit_ready(&ccb->csio,
6538 /* tag_action */ task_attr,
6539 /* sense_len */ SSD_FULL_SIZE,
6540 /* timeout */ 5000);
6542 /* Disable freezing the device queue */
6543 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6545 retval = cam_send_ccb(device, ccb);
6548 * If we get an error from the ioctl, bail out. SCSI
6549 * errors are expected.
6552 warn("error sending TEST UNIT READY command");
6554 goto scsiformat_bailout;
6557 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6559 if ((status != CAM_REQ_CMP)
6560 && (status == CAM_SCSI_STATUS_ERROR)
6561 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6562 struct scsi_sense_data *sense;
6563 int error_code, sense_key, asc, ascq;
6565 sense = &ccb->csio.sense_data;
6566 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6567 ccb->csio.sense_resid, &error_code, &sense_key,
6568 &asc, &ascq, /*show_errors*/ 1);
6571 * According to the SCSI-2 and SCSI-3 specs, a
6572 * drive that is in the middle of a format should
6573 * return NOT READY with an ASC of "logical unit
6574 * not ready, format in progress". The sense key
6575 * specific bytes will then be a progress indicator.
6577 if ((sense_key == SSD_KEY_NOT_READY)
6578 && (asc == 0x04) && (ascq == 0x04)) {
6581 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6582 ccb->csio.sense_resid, sks) == 0)
6585 u_int64_t percentage;
6587 val = scsi_2btoul(&sks[1]);
6588 percentage = 10000ull * val;
6591 "\rFormatting: %ju.%02u %% "
6593 (uintmax_t)(percentage /
6595 (unsigned)((percentage /
6599 } else if ((quiet == 0)
6600 && (++num_warnings <= 1)) {
6601 warnx("Unexpected SCSI Sense Key "
6602 "Specific value returned "
6604 scsi_sense_print(device, &ccb->csio,
6606 warnx("Unable to print status "
6607 "information, but format will "
6609 warnx("will exit when format is "
6614 warnx("Unexpected SCSI error during format");
6615 cam_error_print(device, ccb, CAM_ESF_ALL,
6616 CAM_EPF_ALL, stderr);
6618 goto scsiformat_bailout;
6621 } else if (status != CAM_REQ_CMP) {
6622 warnx("Unexpected CAM status %#x", status);
6623 if (arglist & CAM_ARG_VERBOSE)
6624 cam_error_print(device, ccb, CAM_ESF_ALL,
6625 CAM_EPF_ALL, stderr);
6627 goto scsiformat_bailout;
6630 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6633 fprintf(stdout, "\nFormat Complete\n");
6643 sanitize_wait_ata(struct cam_device *device, union ccb *ccb, int quiet,
6644 camcontrol_devtype devtype)
6647 uint8_t error = 0, ata_device = 0, status = 0;
6653 retval = build_ata_cmd(ccb,
6655 /*flags*/ CAM_DIR_NONE,
6656 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6657 /*protocol*/ AP_PROTO_NON_DATA,
6658 /*ata_flags*/ AP_FLAG_CHK_COND,
6659 /*features*/ 0x00, /* SANITIZE STATUS EXT */
6662 /*command*/ ATA_SANITIZE,
6666 /*cdb_storage*/ NULL,
6667 /*cdb_storage_len*/ 0,
6668 /*sense_len*/ SSD_FULL_SIZE,
6671 /*devtype*/ devtype);
6673 warnx("%s: build_ata_cmd() failed, likely "
6674 "programmer error", __func__);
6678 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6679 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6680 retval = cam_send_ccb(device, ccb);
6682 warn("error sending SANITIZE STATUS EXT command");
6686 retval = get_ata_status(device, ccb, &error, &count, &lba,
6687 &ata_device, &status);
6689 warnx("Can't get SANITIZE STATUS EXT status, "
6690 "sanitize may still run.");
6693 if (status & ATA_STATUS_ERROR) {
6694 if (error & ATA_ERROR_ABORT) {
6695 switch (lba & 0xff) {
6697 warnx("Reason not reported or sanitize failed.");
6700 warnx("Sanitize command unsuccessful. ");
6703 warnx("Unsupported sanitize device command. ");
6706 warnx("Device is in sanitize frozen state. ");
6709 warnx("Sanitize antifreeze lock is enabled. ");
6713 warnx("SANITIZE STATUS EXT failed, "
6714 "sanitize may still run.");
6717 if (count & 0x4000) {
6722 "Sanitizing: %u.%02u%% (%d/%d)\r",
6723 (perc / (0x10000 * 100)),
6724 ((perc / 0x10000) % 100),
6736 sanitize_wait_scsi(struct cam_device *device, union ccb *ccb, int task_attr, int quiet)
6738 int warnings = 0, retval;
6743 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6746 * There's really no need to do error recovery or
6747 * retries here, since we're just going to sit in a
6748 * loop and wait for the device to finish sanitizing.
6750 scsi_test_unit_ready(&ccb->csio,
6753 /* tag_action */ task_attr,
6754 /* sense_len */ SSD_FULL_SIZE,
6755 /* timeout */ 5000);
6757 /* Disable freezing the device queue */
6758 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6760 retval = cam_send_ccb(device, ccb);
6763 * If we get an error from the ioctl, bail out. SCSI
6764 * errors are expected.
6767 warn("error sending TEST UNIT READY command");
6771 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6772 if ((status == CAM_SCSI_STATUS_ERROR) &&
6773 ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6774 struct scsi_sense_data *sense;
6775 int error_code, sense_key, asc, ascq;
6777 sense = &ccb->csio.sense_data;
6778 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6779 ccb->csio.sense_resid, &error_code, &sense_key,
6780 &asc, &ascq, /*show_errors*/ 1);
6783 * According to the SCSI-3 spec, a drive that is in the
6784 * middle of a sanitize should return NOT READY with an
6785 * ASC of "logical unit not ready, sanitize in
6786 * progress". The sense key specific bytes will then
6787 * be a progress indicator.
6789 if ((sense_key == SSD_KEY_NOT_READY)
6790 && (asc == 0x04) && (ascq == 0x1b)) {
6793 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6794 ccb->csio.sense_resid, sks) == 0)
6796 val = scsi_2btoul(&sks[1]);
6799 "Sanitizing: %u.%02u%% (%d/%d)\r",
6800 (perc / (0x10000 * 100)),
6801 ((perc / 0x10000) % 100),
6804 } else if ((quiet == 0) && (++warnings <= 1)) {
6805 warnx("Unexpected SCSI Sense Key "
6806 "Specific value returned "
6807 "during sanitize:");
6808 scsi_sense_print(device, &ccb->csio,
6810 warnx("Unable to print status "
6811 "information, but sanitze will "
6813 warnx("will exit when sanitize is "
6818 warnx("Unexpected SCSI error during sanitize");
6819 cam_error_print(device, ccb, CAM_ESF_ALL,
6820 CAM_EPF_ALL, stderr);
6824 } else if (status != CAM_REQ_CMP && status != CAM_REQUEUE_REQ) {
6825 warnx("Unexpected CAM status %#x", status);
6826 if (arglist & CAM_ARG_VERBOSE)
6827 cam_error_print(device, ccb, CAM_ESF_ALL,
6828 CAM_EPF_ALL, stderr);
6831 } while ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6836 sanitize(struct cam_device *device, int argc, char **argv,
6837 char *combinedopt, int task_attr, int retry_count, int timeout)
6840 u_int8_t action = 0;
6842 int ycount = 0, quiet = 0;
6850 const char *pattern = NULL;
6851 u_int8_t *data_ptr = NULL;
6852 u_int32_t dxfer_len = 0;
6854 uint16_t feature, count;
6857 camcontrol_devtype dt;
6860 * Get the device type, request no I/O be done to do this.
6862 error = get_device_type(device, -1, 0, 0, &dt);
6863 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
6864 warnx("sanitize: can't get device type");
6868 ccb = cam_getccb(device);
6871 warnx("sanitize: error allocating ccb");
6875 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6877 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6880 if (strcasecmp(optarg, "overwrite") == 0)
6881 action = SSZ_SERVICE_ACTION_OVERWRITE;
6882 else if (strcasecmp(optarg, "block") == 0)
6883 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6884 else if (strcasecmp(optarg, "crypto") == 0)
6885 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6886 else if (strcasecmp(optarg, "exitfailure") == 0)
6887 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6889 warnx("invalid service operation \"%s\"",
6892 goto sanitize_bailout;
6896 passes = strtol(optarg, NULL, 0);
6897 if (passes < 1 || passes > 31) {
6898 warnx("invalid passes value %d", passes);
6900 goto sanitize_bailout;
6919 /* ATA supports only immediate commands. */
6920 if (dt == CC_DT_SCSI)
6933 warnx("an action is required");
6935 goto sanitize_bailout;
6936 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6937 struct scsi_sanitize_parameter_list *pl;
6941 if (pattern == NULL) {
6942 warnx("overwrite action requires -P argument");
6944 goto sanitize_bailout;
6946 fd = open(pattern, O_RDONLY);
6948 warn("cannot open pattern file %s", pattern);
6950 goto sanitize_bailout;
6952 if (fstat(fd, &sb) < 0) {
6953 warn("cannot stat pattern file %s", pattern);
6955 goto sanitize_bailout;
6958 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6959 warnx("pattern file size exceeds maximum value %d",
6960 SSZPL_MAX_PATTERN_LENGTH);
6962 goto sanitize_bailout;
6964 dxfer_len = sizeof(*pl) + sz;
6965 data_ptr = calloc(1, dxfer_len);
6966 if (data_ptr == NULL) {
6967 warnx("cannot allocate parameter list buffer");
6969 goto sanitize_bailout;
6972 amt = read(fd, data_ptr + sizeof(*pl), sz);
6974 warn("cannot read pattern file");
6976 goto sanitize_bailout;
6977 } else if (amt != sz) {
6978 warnx("short pattern file read");
6980 goto sanitize_bailout;
6983 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6989 pl->byte1 |= SSZPL_INVERT;
6990 scsi_ulto2b(sz, pl->length);
6996 else if (invert != 0)
6998 else if (pattern != NULL)
7003 warnx("%s argument only valid with overwrite "
7006 goto sanitize_bailout;
7010 if (quiet == 0 && ycount == 0) {
7011 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
7012 "following device:\n");
7014 if (dt == CC_DT_SCSI) {
7015 error = scsidoinquiry(device, argc, argv, combinedopt,
7016 task_attr, retry_count, timeout);
7017 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7018 struct ata_params *ident_buf;
7019 error = ata_do_identify(device, retry_count, timeout,
7022 printf("%s%d: ", device->device_name,
7023 device->dev_unit_num);
7024 ata_print_ident(ident_buf);
7031 warnx("sanitize: error sending inquiry");
7032 goto sanitize_bailout;
7037 if (!get_confirmation()) {
7039 goto sanitize_bailout;
7044 use_timeout = timeout;
7046 use_timeout = (immediate ? 10 : 10800) * 1000;
7048 if (immediate == 0 && quiet == 0) {
7049 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
7050 use_timeout / 1000);
7054 * If the user hasn't disabled questions and didn't specify a
7055 * timeout on the command line, ask them if they want the current
7058 if (immediate == 0 && ycount == 0 && timeout == 0) {
7060 int new_timeout = 0;
7062 fprintf(stdout, "Enter new timeout in seconds or press\n"
7063 "return to keep the current timeout [%d] ",
7064 use_timeout / 1000);
7066 if (fgets(str, sizeof(str), stdin) != NULL) {
7068 new_timeout = atoi(str);
7071 if (new_timeout != 0) {
7072 use_timeout = new_timeout * 1000;
7073 fprintf(stdout, "Using new timeout value %d\n",
7074 use_timeout / 1000);
7078 if (dt == CC_DT_SCSI) {
7081 byte2 |= SSZ_UNRESTRICTED_EXIT;
7084 scsi_sanitize(&ccb->csio,
7085 /* retries */ retry_count,
7087 /* tag_action */ task_attr,
7090 /* data_ptr */ data_ptr,
7091 /* dxfer_len */ dxfer_len,
7092 /* sense_len */ SSD_FULL_SIZE,
7093 /* timeout */ use_timeout);
7095 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7096 if (arglist & CAM_ARG_ERR_RECOVER)
7097 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7098 if (cam_send_ccb(device, ccb) < 0) {
7099 warn("error sending sanitize command");
7101 goto sanitize_bailout;
7103 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7104 if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
7105 feature = 0x14; /* OVERWRITE EXT */
7106 lba = 0x4F5700000000 | scsi_4btoul(data_ptr + 4);
7107 count = (passes == 0) ? 1 : (passes >= 16) ? 0 : passes;
7109 count |= 0x80; /* INVERT PATTERN */
7111 count |= 0x10; /* FAILURE MODE */
7112 } else if (action == SSZ_SERVICE_ACTION_BLOCK_ERASE) {
7113 feature = 0x12; /* BLOCK ERASE EXT */
7114 lba = 0x0000426B4572;
7117 count |= 0x10; /* FAILURE MODE */
7118 } else if (action == SSZ_SERVICE_ACTION_CRYPTO_ERASE) {
7119 feature = 0x11; /* CRYPTO SCRAMBLE EXT */
7120 lba = 0x000043727970;
7123 count |= 0x10; /* FAILURE MODE */
7124 } else if (action == SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE) {
7125 feature = 0x00; /* SANITIZE STATUS EXT */
7127 count = 1; /* CLEAR SANITIZE OPERATION FAILED */
7130 goto sanitize_bailout;
7133 error = ata_do_cmd(device,
7136 /*flags*/CAM_DIR_NONE,
7137 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
7139 /*tag_action*/MSG_SIMPLE_Q_TAG,
7140 /*command*/ATA_SANITIZE,
7141 /*features*/feature,
7143 /*sector_count*/count,
7146 /*timeout*/ use_timeout,
7150 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7151 struct scsi_sense_data *sense;
7152 int error_code, sense_key, asc, ascq;
7154 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
7155 CAM_SCSI_STATUS_ERROR) {
7156 sense = &ccb->csio.sense_data;
7157 scsi_extract_sense_len(sense, ccb->csio.sense_len -
7158 ccb->csio.sense_resid, &error_code, &sense_key,
7159 &asc, &ascq, /*show_errors*/ 1);
7161 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
7162 asc == 0x20 && ascq == 0x00)
7163 warnx("sanitize is not supported by "
7166 warnx("error sanitizing this device");
7168 warnx("error sanitizing this device");
7170 if (arglist & CAM_ARG_VERBOSE) {
7171 cam_error_print(device, ccb, CAM_ESF_ALL,
7172 CAM_EPF_ALL, stderr);
7175 goto sanitize_bailout;
7179 * If we ran in non-immediate mode, we already checked for errors
7180 * above and printed out any necessary information. If we're in
7181 * immediate mode, we need to loop through and get status
7182 * information periodically.
7184 if (immediate == 0) {
7186 fprintf(stdout, "Sanitize Complete\n");
7188 goto sanitize_bailout;
7192 if (dt == CC_DT_SCSI) {
7193 error = sanitize_wait_scsi(device, ccb, task_attr, quiet);
7194 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7195 error = sanitize_wait_ata(device, ccb, quiet, dt);
7198 if (error == 0 && quiet == 0)
7199 fprintf(stdout, "Sanitize Complete \n");
7204 if (data_ptr != NULL)
7212 scsireportluns(struct cam_device *device, int argc, char **argv,
7213 char *combinedopt, int task_attr, int retry_count, int timeout)
7216 int c, countonly, lunsonly;
7217 struct scsi_report_luns_data *lundata;
7219 uint8_t report_type;
7220 uint32_t list_len, i, j;
7225 report_type = RPL_REPORT_DEFAULT;
7226 ccb = cam_getccb(device);
7229 warnx("%s: error allocating ccb", __func__);
7233 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7238 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7247 if (strcasecmp(optarg, "default") == 0)
7248 report_type = RPL_REPORT_DEFAULT;
7249 else if (strcasecmp(optarg, "wellknown") == 0)
7250 report_type = RPL_REPORT_WELLKNOWN;
7251 else if (strcasecmp(optarg, "all") == 0)
7252 report_type = RPL_REPORT_ALL;
7254 warnx("%s: invalid report type \"%s\"",
7265 if ((countonly != 0)
7266 && (lunsonly != 0)) {
7267 warnx("%s: you can only specify one of -c or -l", __func__);
7272 * According to SPC-4, the allocation length must be at least 16
7273 * bytes -- enough for the header and one LUN.
7275 alloc_len = sizeof(*lundata) + 8;
7279 lundata = malloc(alloc_len);
7281 if (lundata == NULL) {
7282 warn("%s: error mallocing %d bytes", __func__, alloc_len);
7287 scsi_report_luns(&ccb->csio,
7288 /*retries*/ retry_count,
7290 /*tag_action*/ task_attr,
7291 /*select_report*/ report_type,
7292 /*rpl_buf*/ lundata,
7293 /*alloc_len*/ alloc_len,
7294 /*sense_len*/ SSD_FULL_SIZE,
7295 /*timeout*/ timeout ? timeout : 5000);
7297 /* Disable freezing the device queue */
7298 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7300 if (arglist & CAM_ARG_ERR_RECOVER)
7301 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7303 if (cam_send_ccb(device, ccb) < 0) {
7304 warn("error sending REPORT LUNS command");
7309 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7310 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7316 list_len = scsi_4btoul(lundata->length);
7319 * If we need to list the LUNs, and our allocation
7320 * length was too short, reallocate and retry.
7322 if ((countonly == 0)
7323 && (list_len > (alloc_len - sizeof(*lundata)))) {
7324 alloc_len = list_len + sizeof(*lundata);
7330 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7331 ((list_len / 8) > 1) ? "s" : "");
7336 for (i = 0; i < (list_len / 8); i++) {
7340 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7342 fprintf(stdout, ",");
7343 switch (lundata->luns[i].lundata[j] &
7344 RPL_LUNDATA_ATYP_MASK) {
7345 case RPL_LUNDATA_ATYP_PERIPH:
7346 if ((lundata->luns[i].lundata[j] &
7347 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7348 fprintf(stdout, "%d:",
7349 lundata->luns[i].lundata[j] &
7350 RPL_LUNDATA_PERIPH_BUS_MASK);
7352 && ((lundata->luns[i].lundata[j+2] &
7353 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7356 fprintf(stdout, "%d",
7357 lundata->luns[i].lundata[j+1]);
7359 case RPL_LUNDATA_ATYP_FLAT: {
7361 tmplun[0] = lundata->luns[i].lundata[j] &
7362 RPL_LUNDATA_FLAT_LUN_MASK;
7363 tmplun[1] = lundata->luns[i].lundata[j+1];
7365 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7369 case RPL_LUNDATA_ATYP_LUN:
7370 fprintf(stdout, "%d:%d:%d",
7371 (lundata->luns[i].lundata[j+1] &
7372 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7373 lundata->luns[i].lundata[j] &
7374 RPL_LUNDATA_LUN_TARG_MASK,
7375 lundata->luns[i].lundata[j+1] &
7376 RPL_LUNDATA_LUN_LUN_MASK);
7378 case RPL_LUNDATA_ATYP_EXTLUN: {
7379 int field_len_code, eam_code;
7381 eam_code = lundata->luns[i].lundata[j] &
7382 RPL_LUNDATA_EXT_EAM_MASK;
7383 field_len_code = (lundata->luns[i].lundata[j] &
7384 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7386 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7387 && (field_len_code == 0x00)) {
7388 fprintf(stdout, "%d",
7389 lundata->luns[i].lundata[j+1]);
7390 } else if ((eam_code ==
7391 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7392 && (field_len_code == 0x03)) {
7396 * This format takes up all 8 bytes.
7397 * If we aren't starting at offset 0,
7401 fprintf(stdout, "Invalid "
7404 "specified format", j);
7408 bzero(tmp_lun, sizeof(tmp_lun));
7409 bcopy(&lundata->luns[i].lundata[j+1],
7410 &tmp_lun[1], sizeof(tmp_lun) - 1);
7411 fprintf(stdout, "%#jx",
7412 (intmax_t)scsi_8btou64(tmp_lun));
7415 fprintf(stderr, "Unknown Extended LUN"
7416 "Address method %#x, length "
7417 "code %#x", eam_code,
7424 fprintf(stderr, "Unknown LUN address method "
7425 "%#x\n", lundata->luns[i].lundata[0] &
7426 RPL_LUNDATA_ATYP_MASK);
7430 * For the flat addressing method, there are no
7431 * other levels after it.
7436 fprintf(stdout, "\n");
7449 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7450 char *combinedopt, int task_attr, int retry_count, int timeout)
7453 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7454 struct scsi_read_capacity_data rcap;
7455 struct scsi_read_capacity_data_long rcaplong;
7470 ccb = cam_getccb(device);
7473 warnx("%s: error allocating ccb", __func__);
7477 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7479 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7509 if ((blocksizeonly != 0)
7510 && (numblocks != 0)) {
7511 warnx("%s: you can only specify one of -b or -N", __func__);
7516 if ((blocksizeonly != 0)
7517 && (sizeonly != 0)) {
7518 warnx("%s: you can only specify one of -b or -s", __func__);
7525 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7531 && (blocksizeonly != 0)) {
7532 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7540 scsi_read_capacity(&ccb->csio,
7541 /*retries*/ retry_count,
7543 /*tag_action*/ task_attr,
7546 /*timeout*/ timeout ? timeout : 5000);
7548 /* Disable freezing the device queue */
7549 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7551 if (arglist & CAM_ARG_ERR_RECOVER)
7552 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7554 if (cam_send_ccb(device, ccb) < 0) {
7555 warn("error sending READ CAPACITY command");
7560 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7561 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7566 maxsector = scsi_4btoul(rcap.addr);
7567 block_len = scsi_4btoul(rcap.length);
7570 * A last block of 2^32-1 means that the true capacity is over 2TB,
7571 * and we need to issue the long READ CAPACITY to get the real
7572 * capacity. Otherwise, we're all set.
7574 if (maxsector != 0xffffffff)
7578 scsi_read_capacity_16(&ccb->csio,
7579 /*retries*/ retry_count,
7581 /*tag_action*/ task_attr,
7585 /*rcap_buf*/ (uint8_t *)&rcaplong,
7586 /*rcap_buf_len*/ sizeof(rcaplong),
7587 /*sense_len*/ SSD_FULL_SIZE,
7588 /*timeout*/ timeout ? timeout : 5000);
7590 /* Disable freezing the device queue */
7591 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7593 if (arglist & CAM_ARG_ERR_RECOVER)
7594 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7596 if (cam_send_ccb(device, ccb) < 0) {
7597 warn("error sending READ CAPACITY (16) command");
7602 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7603 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7608 maxsector = scsi_8btou64(rcaplong.addr);
7609 block_len = scsi_4btoul(rcaplong.length);
7612 if (blocksizeonly == 0) {
7614 * Humanize implies !quiet, and also implies numblocks.
7616 if (humanize != 0) {
7621 tmpbytes = (maxsector + 1) * block_len;
7622 ret = humanize_number(tmpstr, sizeof(tmpstr),
7623 tmpbytes, "", HN_AUTOSCALE,
7626 HN_DIVISOR_1000 : 0));
7628 warnx("%s: humanize_number failed!", __func__);
7632 fprintf(stdout, "Device Size: %s%s", tmpstr,
7633 (sizeonly == 0) ? ", " : "\n");
7634 } else if (numblocks != 0) {
7635 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7636 "Blocks: " : "", (uintmax_t)maxsector + 1,
7637 (sizeonly == 0) ? ", " : "\n");
7639 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7640 "Last Block: " : "", (uintmax_t)maxsector,
7641 (sizeonly == 0) ? ", " : "\n");
7645 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7646 "Block Length: " : "", block_len, (quiet == 0) ?
7655 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7656 int retry_count, int timeout)
7660 uint8_t *smp_request = NULL, *smp_response = NULL;
7661 int request_size = 0, response_size = 0;
7662 int fd_request = 0, fd_response = 0;
7663 char *datastr = NULL;
7664 struct get_hook hook;
7669 * Note that at the moment we don't support sending SMP CCBs to
7670 * devices that aren't probed by CAM.
7672 ccb = cam_getccb(device);
7674 warnx("%s: error allocating CCB", __func__);
7678 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7680 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7683 arglist |= CAM_ARG_CMD_IN;
7684 response_size = strtol(optarg, NULL, 0);
7685 if (response_size <= 0) {
7686 warnx("invalid number of response bytes %d",
7689 goto smpcmd_bailout;
7691 hook.argc = argc - optind;
7692 hook.argv = argv + optind;
7695 datastr = cget(&hook, NULL);
7697 * If the user supplied "-" instead of a format, he
7698 * wants the data to be written to stdout.
7700 if ((datastr != NULL)
7701 && (datastr[0] == '-'))
7704 smp_response = (u_int8_t *)malloc(response_size);
7705 if (smp_response == NULL) {
7706 warn("can't malloc memory for SMP response");
7708 goto smpcmd_bailout;
7712 arglist |= CAM_ARG_CMD_OUT;
7713 request_size = strtol(optarg, NULL, 0);
7714 if (request_size <= 0) {
7715 warnx("invalid number of request bytes %d",
7718 goto smpcmd_bailout;
7720 hook.argc = argc - optind;
7721 hook.argv = argv + optind;
7723 datastr = cget(&hook, NULL);
7724 smp_request = (u_int8_t *)malloc(request_size);
7725 if (smp_request == NULL) {
7726 warn("can't malloc memory for SMP request");
7728 goto smpcmd_bailout;
7730 bzero(smp_request, request_size);
7732 * If the user supplied "-" instead of a format, he
7733 * wants the data to be read from stdin.
7735 if ((datastr != NULL)
7736 && (datastr[0] == '-'))
7739 buff_encode_visit(smp_request, request_size,
7750 * If fd_data is set, and we're writing to the device, we need to
7751 * read the data the user wants written from stdin.
7753 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7755 int amt_to_read = request_size;
7756 u_int8_t *buf_ptr = smp_request;
7758 for (amt_read = 0; amt_to_read > 0;
7759 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7760 if (amt_read == -1) {
7761 warn("error reading data from stdin");
7763 goto smpcmd_bailout;
7765 amt_to_read -= amt_read;
7766 buf_ptr += amt_read;
7770 if (((arglist & CAM_ARG_CMD_IN) == 0)
7771 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7772 warnx("%s: need both the request (-r) and response (-R) "
7773 "arguments", __func__);
7775 goto smpcmd_bailout;
7778 flags |= CAM_DEV_QFRZDIS;
7780 cam_fill_smpio(&ccb->smpio,
7781 /*retries*/ retry_count,
7784 /*smp_request*/ smp_request,
7785 /*smp_request_len*/ request_size,
7786 /*smp_response*/ smp_response,
7787 /*smp_response_len*/ response_size,
7788 /*timeout*/ timeout ? timeout : 5000);
7790 ccb->smpio.flags = SMP_FLAG_NONE;
7792 if (((retval = cam_send_ccb(device, ccb)) < 0)
7793 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7794 const char warnstr[] = "error sending command";
7801 if (arglist & CAM_ARG_VERBOSE) {
7802 cam_error_print(device, ccb, CAM_ESF_ALL,
7803 CAM_EPF_ALL, stderr);
7807 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7808 && (response_size > 0)) {
7809 if (fd_response == 0) {
7810 buff_decode_visit(smp_response, response_size,
7811 datastr, arg_put, NULL);
7812 fprintf(stdout, "\n");
7814 ssize_t amt_written;
7815 int amt_to_write = response_size;
7816 u_int8_t *buf_ptr = smp_response;
7818 for (amt_written = 0; (amt_to_write > 0) &&
7819 (amt_written = write(STDOUT_FILENO, buf_ptr,
7820 amt_to_write)) > 0;){
7821 amt_to_write -= amt_written;
7822 buf_ptr += amt_written;
7824 if (amt_written == -1) {
7825 warn("error writing data to stdout");
7827 goto smpcmd_bailout;
7828 } else if ((amt_written == 0)
7829 && (amt_to_write > 0)) {
7830 warnx("only wrote %u bytes out of %u",
7831 response_size - amt_to_write,
7840 if (smp_request != NULL)
7843 if (smp_response != NULL)
7850 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7851 int retry_count, int timeout)
7855 int32_t mmc_opcode = 0, mmc_arg = 0;
7856 int32_t mmc_flags = -1;
7859 int is_bw_4 = 0, is_bw_1 = 0;
7860 int is_highspeed = 0, is_stdspeed = 0;
7861 int is_info_request = 0;
7863 uint8_t mmc_data_byte = 0;
7865 /* For IO_RW_EXTENDED command */
7866 uint8_t *mmc_data = NULL;
7867 struct mmc_data mmc_d;
7868 int mmc_data_len = 0;
7871 * Note that at the moment we don't support sending SMP CCBs to
7872 * devices that aren't probed by CAM.
7874 ccb = cam_getccb(device);
7876 warnx("%s: error allocating CCB", __func__);
7880 bzero(&(&ccb->ccb_h)[1],
7881 sizeof(union ccb) - sizeof(struct ccb_hdr));
7883 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7892 if (!strcmp(optarg, "high"))
7898 is_info_request = 1;
7901 mmc_opcode = strtol(optarg, NULL, 0);
7902 if (mmc_opcode < 0) {
7903 warnx("invalid MMC opcode %d",
7906 goto mmccmd_bailout;
7910 mmc_arg = strtol(optarg, NULL, 0);
7912 warnx("invalid MMC arg %d",
7915 goto mmccmd_bailout;
7919 mmc_flags = strtol(optarg, NULL, 0);
7920 if (mmc_flags < 0) {
7921 warnx("invalid MMC flags %d",
7924 goto mmccmd_bailout;
7928 mmc_data_len = strtol(optarg, NULL, 0);
7929 if (mmc_data_len <= 0) {
7930 warnx("invalid MMC data len %d",
7933 goto mmccmd_bailout;
7940 mmc_data_byte = strtol(optarg, NULL, 0);
7946 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7948 /* If flags are left default, supply the right flags */
7950 switch (mmc_opcode) {
7951 case MMC_GO_IDLE_STATE:
7952 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7954 case IO_SEND_OP_COND:
7955 mmc_flags = MMC_RSP_R4;
7957 case SD_SEND_RELATIVE_ADDR:
7958 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7960 case MMC_SELECT_CARD:
7961 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7962 mmc_arg = mmc_arg << 16;
7964 case SD_IO_RW_DIRECT:
7965 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7966 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7968 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7970 case SD_IO_RW_EXTENDED:
7971 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7972 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7973 int len_arg = mmc_data_len;
7974 if (mmc_data_len == 512)
7978 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7980 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7983 mmc_flags = MMC_RSP_R1;
7987 // Switch bus width instead of sending IO command
7988 if (is_bw_4 || is_bw_1) {
7989 struct ccb_trans_settings_mmc *cts;
7990 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7991 ccb->ccb_h.flags = 0;
7992 cts = &ccb->cts.proto_specific.mmc;
7993 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7994 cts->ios_valid = MMC_BW;
7995 if (((retval = cam_send_ccb(device, ccb)) < 0)
7996 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7997 warn("Error sending command");
7999 printf("Parameters set OK\n");
8005 // Switch bus speed instead of sending IO command
8006 if (is_stdspeed || is_highspeed) {
8007 struct ccb_trans_settings_mmc *cts;
8008 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
8009 ccb->ccb_h.flags = 0;
8010 cts = &ccb->cts.proto_specific.mmc;
8011 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
8012 cts->ios_valid = MMC_BT;
8013 if (((retval = cam_send_ccb(device, ccb)) < 0)
8014 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8015 warn("Error sending command");
8017 printf("Speed set OK (HS: %d)\n", is_highspeed);
8023 // Get information about controller and its settings
8024 if (is_info_request) {
8025 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
8026 ccb->ccb_h.flags = 0;
8027 struct ccb_trans_settings_mmc *cts;
8028 cts = &ccb->cts.proto_specific.mmc;
8029 if (((retval = cam_send_ccb(device, ccb)) < 0)
8030 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8031 warn("Error sending command");
8034 printf("Host controller information\n");
8035 printf("Host OCR: 0x%x\n", cts->host_ocr);
8036 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
8037 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
8038 printf("Supported bus width: ");
8039 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
8041 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
8043 printf("\nCurrent settings:\n");
8044 printf("Bus width: ");
8045 switch (cts->ios.bus_width) {
8056 printf("Freq: %d.%03d MHz%s\n",
8057 cts->ios.clock / 1000000,
8058 (cts->ios.clock / 1000) % 1000,
8059 cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : "");
8063 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
8065 if (mmc_data_len > 0) {
8066 flags |= CAM_DIR_IN;
8067 mmc_data = malloc(mmc_data_len);
8068 memset(mmc_data, 0, mmc_data_len);
8069 mmc_d.len = mmc_data_len;
8070 mmc_d.data = mmc_data;
8071 mmc_d.flags = MMC_DATA_READ;
8072 } else flags |= CAM_DIR_NONE;
8074 cam_fill_mmcio(&ccb->mmcio,
8075 /*retries*/ retry_count,
8078 /*mmc_opcode*/ mmc_opcode,
8079 /*mmc_arg*/ mmc_arg,
8080 /*mmc_flags*/ mmc_flags,
8081 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
8082 /*timeout*/ timeout ? timeout : 5000);
8084 if (((retval = cam_send_ccb(device, ccb)) < 0)
8085 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8086 const char warnstr[] = "error sending command";
8093 if (arglist & CAM_ARG_VERBOSE) {
8094 cam_error_print(device, ccb, CAM_ESF_ALL,
8095 CAM_EPF_ALL, stderr);
8099 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
8100 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
8101 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
8102 ccb->mmcio.cmd.resp[1],
8103 ccb->mmcio.cmd.resp[2],
8104 ccb->mmcio.cmd.resp[3]);
8106 switch (mmc_opcode) {
8107 case SD_IO_RW_DIRECT:
8108 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
8109 SD_R5_DATA(ccb->mmcio.cmd.resp),
8110 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
8112 case SD_IO_RW_EXTENDED:
8113 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
8114 hexdump(mmc_data, mmc_data_len, NULL, 0);
8116 case SD_SEND_RELATIVE_ADDR:
8117 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
8120 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
8127 if (mmc_data_len > 0 && mmc_data != NULL)
8134 smpreportgeneral(struct cam_device *device, int argc, char **argv,
8135 char *combinedopt, int retry_count, int timeout)
8138 struct smp_report_general_request *request = NULL;
8139 struct smp_report_general_response *response = NULL;
8140 struct sbuf *sb = NULL;
8142 int c, long_response = 0;
8146 * Note that at the moment we don't support sending SMP CCBs to
8147 * devices that aren't probed by CAM.
8149 ccb = cam_getccb(device);
8151 warnx("%s: error allocating CCB", __func__);
8155 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8157 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8166 request = malloc(sizeof(*request));
8167 if (request == NULL) {
8168 warn("%s: unable to allocate %zd bytes", __func__,
8174 response = malloc(sizeof(*response));
8175 if (response == NULL) {
8176 warn("%s: unable to allocate %zd bytes", __func__,
8183 smp_report_general(&ccb->smpio,
8187 /*request_len*/ sizeof(*request),
8188 (uint8_t *)response,
8189 /*response_len*/ sizeof(*response),
8190 /*long_response*/ long_response,
8193 if (((retval = cam_send_ccb(device, ccb)) < 0)
8194 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8195 const char warnstr[] = "error sending command";
8202 if (arglist & CAM_ARG_VERBOSE) {
8203 cam_error_print(device, ccb, CAM_ESF_ALL,
8204 CAM_EPF_ALL, stderr);
8211 * If the device supports the long response bit, try again and see
8212 * if we can get all of the data.
8214 if ((response->long_response & SMP_RG_LONG_RESPONSE)
8215 && (long_response == 0)) {
8216 ccb->ccb_h.status = CAM_REQ_INPROG;
8217 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8223 * XXX KDM detect and decode SMP errors here.
8225 sb = sbuf_new_auto();
8227 warnx("%s: error allocating sbuf", __func__);
8231 smp_report_general_sbuf(response, sizeof(*response), sb);
8233 if (sbuf_finish(sb) != 0) {
8234 warnx("%s: sbuf_finish", __func__);
8238 printf("%s", sbuf_data(sb));
8244 if (request != NULL)
8247 if (response != NULL)
8256 static struct camcontrol_opts phy_ops[] = {
8257 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
8258 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
8259 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
8260 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
8261 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
8262 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
8263 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
8264 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
8265 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
8270 smpphycontrol(struct cam_device *device, int argc, char **argv,
8271 char *combinedopt, int retry_count, int timeout)
8274 struct smp_phy_control_request *request = NULL;
8275 struct smp_phy_control_response *response = NULL;
8276 int long_response = 0;
8279 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
8281 uint64_t attached_dev_name = 0;
8282 int dev_name_set = 0;
8283 uint32_t min_plr = 0, max_plr = 0;
8284 uint32_t pp_timeout_val = 0;
8285 int slumber_partial = 0;
8286 int set_pp_timeout_val = 0;
8290 * Note that at the moment we don't support sending SMP CCBs to
8291 * devices that aren't probed by CAM.
8293 ccb = cam_getccb(device);
8295 warnx("%s: error allocating CCB", __func__);
8299 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8301 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8309 if (strcasecmp(optarg, "enable") == 0)
8311 else if (strcasecmp(optarg, "disable") == 0)
8314 warnx("%s: Invalid argument %s", __func__,
8321 slumber_partial |= enable <<
8322 SMP_PC_SAS_SLUMBER_SHIFT;
8325 slumber_partial |= enable <<
8326 SMP_PC_SAS_PARTIAL_SHIFT;
8329 slumber_partial |= enable <<
8330 SMP_PC_SATA_SLUMBER_SHIFT;
8333 slumber_partial |= enable <<
8334 SMP_PC_SATA_PARTIAL_SHIFT;
8337 warnx("%s: programmer error", __func__);
8340 break; /*NOTREACHED*/
8345 attached_dev_name = (uintmax_t)strtoumax(optarg,
8354 * We don't do extensive checking here, so this
8355 * will continue to work when new speeds come out.
8357 min_plr = strtoul(optarg, NULL, 0);
8359 || (min_plr > 0xf)) {
8360 warnx("%s: invalid link rate %x",
8368 * We don't do extensive checking here, so this
8369 * will continue to work when new speeds come out.
8371 max_plr = strtoul(optarg, NULL, 0);
8373 || (max_plr > 0xf)) {
8374 warnx("%s: invalid link rate %x",
8381 camcontrol_optret optreturn;
8382 cam_argmask argnums;
8385 if (phy_op_set != 0) {
8386 warnx("%s: only one phy operation argument "
8387 "(-o) allowed", __func__);
8395 * Allow the user to specify the phy operation
8396 * numerically, as well as with a name. This will
8397 * future-proof it a bit, so options that are added
8398 * in future specs can be used.
8400 if (isdigit(optarg[0])) {
8401 phy_operation = strtoul(optarg, NULL, 0);
8402 if ((phy_operation == 0)
8403 || (phy_operation > 0xff)) {
8404 warnx("%s: invalid phy operation %#x",
8405 __func__, phy_operation);
8411 optreturn = getoption(phy_ops, optarg, &phy_operation,
8414 if (optreturn == CC_OR_AMBIGUOUS) {
8415 warnx("%s: ambiguous option %s", __func__,
8420 } else if (optreturn == CC_OR_NOT_FOUND) {
8421 warnx("%s: option %s not found", __func__,
8433 pp_timeout_val = strtoul(optarg, NULL, 0);
8434 if (pp_timeout_val > 15) {
8435 warnx("%s: invalid partial pathway timeout "
8436 "value %u, need a value less than 16",
8437 __func__, pp_timeout_val);
8441 set_pp_timeout_val = 1;
8449 warnx("%s: a PHY (-p phy) argument is required",__func__);
8454 if (((dev_name_set != 0)
8455 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8456 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8457 && (dev_name_set == 0))) {
8458 warnx("%s: -d name and -o setdevname arguments both "
8459 "required to set device name", __func__);
8464 request = malloc(sizeof(*request));
8465 if (request == NULL) {
8466 warn("%s: unable to allocate %zd bytes", __func__,
8472 response = malloc(sizeof(*response));
8473 if (response == NULL) {
8474 warn("%s: unable to allocate %zd bytes", __func__,
8480 smp_phy_control(&ccb->smpio,
8485 (uint8_t *)response,
8488 /*expected_exp_change_count*/ 0,
8491 (set_pp_timeout_val != 0) ? 1 : 0,
8499 if (((retval = cam_send_ccb(device, ccb)) < 0)
8500 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8501 const char warnstr[] = "error sending command";
8508 if (arglist & CAM_ARG_VERBOSE) {
8510 * Use CAM_EPF_NORMAL so we only get one line of
8511 * SMP command decoding.
8513 cam_error_print(device, ccb, CAM_ESF_ALL,
8514 CAM_EPF_NORMAL, stderr);
8520 /* XXX KDM print out something here for success? */
8525 if (request != NULL)
8528 if (response != NULL)
8535 smpmaninfo(struct cam_device *device, int argc, char **argv,
8536 char *combinedopt, int retry_count, int timeout)
8539 struct smp_report_manuf_info_request request;
8540 struct smp_report_manuf_info_response response;
8541 struct sbuf *sb = NULL;
8542 int long_response = 0;
8547 * Note that at the moment we don't support sending SMP CCBs to
8548 * devices that aren't probed by CAM.
8550 ccb = cam_getccb(device);
8552 warnx("%s: error allocating CCB", __func__);
8556 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8558 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8567 bzero(&request, sizeof(request));
8568 bzero(&response, sizeof(response));
8570 smp_report_manuf_info(&ccb->smpio,
8575 (uint8_t *)&response,
8580 if (((retval = cam_send_ccb(device, ccb)) < 0)
8581 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8582 const char warnstr[] = "error sending command";
8589 if (arglist & CAM_ARG_VERBOSE) {
8590 cam_error_print(device, ccb, CAM_ESF_ALL,
8591 CAM_EPF_ALL, stderr);
8597 sb = sbuf_new_auto();
8599 warnx("%s: error allocating sbuf", __func__);
8603 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8605 if (sbuf_finish(sb) != 0) {
8606 warnx("%s: sbuf_finish", __func__);
8610 printf("%s", sbuf_data(sb));
8624 getdevid(struct cam_devitem *item)
8627 union ccb *ccb = NULL;
8629 struct cam_device *dev;
8631 dev = cam_open_btl(item->dev_match.path_id,
8632 item->dev_match.target_id,
8633 item->dev_match.target_lun, O_RDWR, NULL);
8636 warnx("%s", cam_errbuf);
8641 item->device_id_len = 0;
8643 ccb = cam_getccb(dev);
8645 warnx("%s: error allocating CCB", __func__);
8650 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8653 * On the first try, we just probe for the size of the data, and
8654 * then allocate that much memory and try again.
8657 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8658 ccb->ccb_h.flags = CAM_DIR_IN;
8659 ccb->cdai.flags = CDAI_FLAG_NONE;
8660 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8661 ccb->cdai.bufsiz = item->device_id_len;
8662 if (item->device_id_len != 0)
8663 ccb->cdai.buf = (uint8_t *)item->device_id;
8665 if (cam_send_ccb(dev, ccb) < 0) {
8666 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8671 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8672 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8677 if (item->device_id_len == 0) {
8679 * This is our first time through. Allocate the buffer,
8680 * and then go back to get the data.
8682 if (ccb->cdai.provsiz == 0) {
8683 warnx("%s: invalid .provsiz field returned with "
8684 "XPT_GDEV_ADVINFO CCB", __func__);
8688 item->device_id_len = ccb->cdai.provsiz;
8689 item->device_id = malloc(item->device_id_len);
8690 if (item->device_id == NULL) {
8691 warn("%s: unable to allocate %d bytes", __func__,
8692 item->device_id_len);
8696 ccb->ccb_h.status = CAM_REQ_INPROG;
8702 cam_close_device(dev);
8711 * XXX KDM merge this code with getdevtree()?
8714 buildbusdevlist(struct cam_devlist *devlist)
8717 int bufsize, fd = -1;
8718 struct dev_match_pattern *patterns;
8719 struct cam_devitem *item = NULL;
8720 int skip_device = 0;
8723 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8724 warn("couldn't open %s", XPT_DEVICE);
8728 bzero(&ccb, sizeof(union ccb));
8730 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8731 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8732 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8734 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8735 bufsize = sizeof(struct dev_match_result) * 100;
8736 ccb.cdm.match_buf_len = bufsize;
8737 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8738 if (ccb.cdm.matches == NULL) {
8739 warnx("can't malloc memory for matches");
8743 ccb.cdm.num_matches = 0;
8744 ccb.cdm.num_patterns = 2;
8745 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8746 ccb.cdm.num_patterns;
8748 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8749 if (patterns == NULL) {
8750 warnx("can't malloc memory for patterns");
8755 ccb.cdm.patterns = patterns;
8756 bzero(patterns, ccb.cdm.pattern_buf_len);
8758 patterns[0].type = DEV_MATCH_DEVICE;
8759 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8760 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8761 patterns[1].type = DEV_MATCH_PERIPH;
8762 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8763 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8766 * We do the ioctl multiple times if necessary, in case there are
8767 * more than 100 nodes in the EDT.
8772 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8773 warn("error sending CAMIOCOMMAND ioctl");
8778 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8779 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8780 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8781 warnx("got CAM error %#x, CDM error %d\n",
8782 ccb.ccb_h.status, ccb.cdm.status);
8787 for (i = 0; i < ccb.cdm.num_matches; i++) {
8788 switch (ccb.cdm.matches[i].type) {
8789 case DEV_MATCH_DEVICE: {
8790 struct device_match_result *dev_result;
8793 &ccb.cdm.matches[i].result.device_result;
8795 if (dev_result->flags &
8796 DEV_RESULT_UNCONFIGURED) {
8802 item = malloc(sizeof(*item));
8804 warn("%s: unable to allocate %zd bytes",
8805 __func__, sizeof(*item));
8809 bzero(item, sizeof(*item));
8810 bcopy(dev_result, &item->dev_match,
8811 sizeof(*dev_result));
8812 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8815 if (getdevid(item) != 0) {
8821 case DEV_MATCH_PERIPH: {
8822 struct periph_match_result *periph_result;
8825 &ccb.cdm.matches[i].result.periph_result;
8827 if (skip_device != 0)
8829 item->num_periphs++;
8830 item->periph_matches = realloc(
8831 item->periph_matches,
8833 sizeof(struct periph_match_result));
8834 if (item->periph_matches == NULL) {
8835 warn("%s: error allocating periph "
8840 bcopy(periph_result, &item->periph_matches[
8841 item->num_periphs - 1],
8842 sizeof(*periph_result));
8846 fprintf(stderr, "%s: unexpected match "
8847 "type %d\n", __func__,
8848 ccb.cdm.matches[i].type);
8851 break; /*NOTREACHED*/
8854 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8855 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8863 free(ccb.cdm.matches);
8866 freebusdevlist(devlist);
8872 freebusdevlist(struct cam_devlist *devlist)
8874 struct cam_devitem *item, *item2;
8876 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8877 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8879 free(item->device_id);
8880 free(item->periph_matches);
8885 static struct cam_devitem *
8886 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8888 struct cam_devitem *item;
8890 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8891 struct scsi_vpd_id_descriptor *idd;
8894 * XXX KDM look for LUN IDs as well?
8896 idd = scsi_get_devid(item->device_id,
8897 item->device_id_len,
8898 scsi_devid_is_sas_target);
8902 if (scsi_8btou64(idd->identifier) == sasaddr)
8910 smpphylist(struct cam_device *device, int argc, char **argv,
8911 char *combinedopt, int retry_count, int timeout)
8913 struct smp_report_general_request *rgrequest = NULL;
8914 struct smp_report_general_response *rgresponse = NULL;
8915 struct smp_discover_request *disrequest = NULL;
8916 struct smp_discover_response *disresponse = NULL;
8917 struct cam_devlist devlist;
8919 int long_response = 0;
8926 * Note that at the moment we don't support sending SMP CCBs to
8927 * devices that aren't probed by CAM.
8929 ccb = cam_getccb(device);
8931 warnx("%s: error allocating CCB", __func__);
8935 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8936 STAILQ_INIT(&devlist.dev_queue);
8938 rgrequest = malloc(sizeof(*rgrequest));
8939 if (rgrequest == NULL) {
8940 warn("%s: unable to allocate %zd bytes", __func__,
8941 sizeof(*rgrequest));
8946 rgresponse = malloc(sizeof(*rgresponse));
8947 if (rgresponse == NULL) {
8948 warn("%s: unable to allocate %zd bytes", __func__,
8949 sizeof(*rgresponse));
8954 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8967 smp_report_general(&ccb->smpio,
8971 /*request_len*/ sizeof(*rgrequest),
8972 (uint8_t *)rgresponse,
8973 /*response_len*/ sizeof(*rgresponse),
8974 /*long_response*/ long_response,
8977 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8979 if (((retval = cam_send_ccb(device, ccb)) < 0)
8980 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8981 const char warnstr[] = "error sending command";
8988 if (arglist & CAM_ARG_VERBOSE) {
8989 cam_error_print(device, ccb, CAM_ESF_ALL,
8990 CAM_EPF_ALL, stderr);
8996 num_phys = rgresponse->num_phys;
8998 if (num_phys == 0) {
9000 fprintf(stdout, "%s: No Phys reported\n", __func__);
9005 devlist.path_id = device->path_id;
9007 retval = buildbusdevlist(&devlist);
9012 fprintf(stdout, "%d PHYs:\n", num_phys);
9013 fprintf(stdout, "PHY Attached SAS Address\n");
9016 disrequest = malloc(sizeof(*disrequest));
9017 if (disrequest == NULL) {
9018 warn("%s: unable to allocate %zd bytes", __func__,
9019 sizeof(*disrequest));
9024 disresponse = malloc(sizeof(*disresponse));
9025 if (disresponse == NULL) {
9026 warn("%s: unable to allocate %zd bytes", __func__,
9027 sizeof(*disresponse));
9032 for (i = 0; i < num_phys; i++) {
9033 struct cam_devitem *item;
9034 struct device_match_result *dev_match;
9035 char vendor[16], product[48], revision[16];
9039 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
9041 ccb->ccb_h.status = CAM_REQ_INPROG;
9042 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9044 smp_discover(&ccb->smpio,
9048 sizeof(*disrequest),
9049 (uint8_t *)disresponse,
9050 sizeof(*disresponse),
9052 /*ignore_zone_group*/ 0,
9056 if (((retval = cam_send_ccb(device, ccb)) < 0)
9057 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
9058 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
9059 const char warnstr[] = "error sending command";
9066 if (arglist & CAM_ARG_VERBOSE) {
9067 cam_error_print(device, ccb, CAM_ESF_ALL,
9068 CAM_EPF_ALL, stderr);
9074 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
9076 fprintf(stdout, "%3d <vacant>\n", i);
9080 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
9083 item = findsasdevice(&devlist,
9084 scsi_8btou64(disresponse->attached_sas_address));
9088 || (item != NULL)) {
9089 fprintf(stdout, "%3d 0x%016jx", i,
9090 (uintmax_t)scsi_8btou64(
9091 disresponse->attached_sas_address));
9093 fprintf(stdout, "\n");
9096 } else if (quiet != 0)
9099 dev_match = &item->dev_match;
9101 if (dev_match->protocol == PROTO_SCSI) {
9102 cam_strvis(vendor, dev_match->inq_data.vendor,
9103 sizeof(dev_match->inq_data.vendor),
9105 cam_strvis(product, dev_match->inq_data.product,
9106 sizeof(dev_match->inq_data.product),
9108 cam_strvis(revision, dev_match->inq_data.revision,
9109 sizeof(dev_match->inq_data.revision),
9111 sprintf(tmpstr, "<%s %s %s>", vendor, product,
9113 } else if ((dev_match->protocol == PROTO_ATA)
9114 || (dev_match->protocol == PROTO_SATAPM)) {
9115 cam_strvis(product, dev_match->ident_data.model,
9116 sizeof(dev_match->ident_data.model),
9118 cam_strvis(revision, dev_match->ident_data.revision,
9119 sizeof(dev_match->ident_data.revision),
9121 sprintf(tmpstr, "<%s %s>", product, revision);
9123 sprintf(tmpstr, "<>");
9125 fprintf(stdout, " %-33s ", tmpstr);
9128 * If we have 0 periphs, that's a bug...
9130 if (item->num_periphs == 0) {
9131 fprintf(stdout, "\n");
9135 fprintf(stdout, "(");
9136 for (j = 0; j < item->num_periphs; j++) {
9138 fprintf(stdout, ",");
9140 fprintf(stdout, "%s%d",
9141 item->periph_matches[j].periph_name,
9142 item->periph_matches[j].unit_number);
9145 fprintf(stdout, ")\n");
9159 freebusdevlist(&devlist);
9165 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
9167 uint8_t error = 0, ata_device = 0, status = 0;
9172 retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
9175 if (arglist & CAM_ARG_VERBOSE) {
9176 cam_error_print(device, ccb, CAM_ESF_ALL,
9177 CAM_EPF_ALL, stderr);
9179 warnx("Can't get ATA command status");
9183 if (status & ATA_STATUS_ERROR) {
9184 cam_error_print(device, ccb, CAM_ESF_ALL,
9185 CAM_EPF_ALL, stderr);
9189 printf("%s%d: ", device->device_name, device->dev_unit_num);
9192 printf("Standby mode\n");
9195 printf("Standby_y mode\n");
9198 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
9201 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
9204 printf("Idle mode\n");
9207 printf("Idle_a mode\n");
9210 printf("Idle_b mode\n");
9213 printf("Idle_c mode\n");
9216 printf("Active or Idle mode\n");
9219 printf("Unknown mode 0x%02x\n", count);
9227 atapm(struct cam_device *device, int argc, char **argv,
9228 char *combinedopt, int retry_count, int timeout)
9234 u_int8_t ata_flags = 0;
9237 ccb = cam_getccb(device);
9240 warnx("%s: error allocating ccb", __func__);
9244 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9253 if (strcmp(argv[1], "idle") == 0) {
9255 cmd = ATA_IDLE_IMMEDIATE;
9258 } else if (strcmp(argv[1], "standby") == 0) {
9260 cmd = ATA_STANDBY_IMMEDIATE;
9262 cmd = ATA_STANDBY_CMD;
9263 } else if (strcmp(argv[1], "powermode") == 0) {
9264 cmd = ATA_CHECK_POWER_MODE;
9265 ata_flags = AP_FLAG_CHK_COND;
9274 else if (t <= (240 * 5))
9276 else if (t <= (252 * 5))
9277 /* special encoding for 21 minutes */
9279 else if (t <= (11 * 30 * 60))
9280 sc = (t - 1) / (30 * 60) + 241;
9284 retval = ata_do_cmd(device,
9286 /*retries*/retry_count,
9287 /*flags*/CAM_DIR_NONE,
9288 /*protocol*/AP_PROTO_NON_DATA,
9289 /*ata_flags*/ata_flags,
9290 /*tag_action*/MSG_SIMPLE_Q_TAG,
9297 /*timeout*/timeout ? timeout : 30 * 1000,
9302 if (retval || cmd != ATA_CHECK_POWER_MODE)
9305 return (atapm_proc_resp(device, ccb));
9309 ataaxm(struct cam_device *device, int argc, char **argv,
9310 char *combinedopt, int retry_count, int timeout)
9318 ccb = cam_getccb(device);
9321 warnx("%s: error allocating ccb", __func__);
9325 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9335 if (strcmp(argv[1], "apm") == 0) {
9351 retval = ata_do_cmd(device,
9353 /*retries*/retry_count,
9354 /*flags*/CAM_DIR_NONE,
9355 /*protocol*/AP_PROTO_NON_DATA,
9357 /*tag_action*/MSG_SIMPLE_Q_TAG,
9358 /*command*/ATA_SETFEATURES,
9364 /*timeout*/timeout ? timeout : 30 * 1000,
9372 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9373 int show_sa_errors, int sa_set, int service_action,
9374 int timeout_desc, int task_attr, int retry_count, int timeout,
9375 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9377 union ccb *ccb = NULL;
9378 uint8_t *buf = NULL;
9379 uint32_t alloc_len = 0, num_opcodes;
9380 uint32_t valid_len = 0;
9381 uint32_t avail_len = 0;
9382 struct scsi_report_supported_opcodes_all *all_hdr;
9383 struct scsi_report_supported_opcodes_one *one;
9388 * Make it clear that we haven't yet allocated or filled anything.
9393 ccb = cam_getccb(device);
9395 warnx("couldn't allocate CCB");
9400 /* cam_getccb cleans up the header, caller has to zero the payload */
9401 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9403 if (opcode_set != 0) {
9404 options |= RSO_OPTIONS_OC;
9406 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9409 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9410 sizeof(struct scsi_report_supported_opcodes_descr));
9413 if (timeout_desc != 0) {
9414 options |= RSO_RCTD;
9415 alloc_len += num_opcodes *
9416 sizeof(struct scsi_report_supported_opcodes_timeout);
9420 options |= RSO_OPTIONS_OC_SA;
9421 if (show_sa_errors != 0)
9422 options &= ~RSO_OPTIONS_OC;
9431 buf = malloc(alloc_len);
9433 warn("Unable to allocate %u bytes", alloc_len);
9437 bzero(buf, alloc_len);
9439 scsi_report_supported_opcodes(&ccb->csio,
9440 /*retries*/ retry_count,
9442 /*tag_action*/ task_attr,
9443 /*options*/ options,
9444 /*req_opcode*/ opcode,
9445 /*req_service_action*/ service_action,
9447 /*dxfer_len*/ alloc_len,
9448 /*sense_len*/ SSD_FULL_SIZE,
9449 /*timeout*/ timeout ? timeout : 10000);
9451 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9453 if (retry_count != 0)
9454 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9456 if (cam_send_ccb(device, ccb) < 0) {
9457 warn("error sending REPORT SUPPORTED OPERATION CODES command");
9462 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9463 if (verbosemode != 0)
9464 cam_error_print(device, ccb, CAM_ESF_ALL,
9465 CAM_EPF_ALL, stderr);
9470 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9472 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9473 && (valid_len >= sizeof(*all_hdr))) {
9474 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9475 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9476 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9477 && (valid_len >= sizeof(*one))) {
9478 uint32_t cdb_length;
9480 one = (struct scsi_report_supported_opcodes_one *)buf;
9481 cdb_length = scsi_2btoul(one->cdb_length);
9482 avail_len = sizeof(*one) + cdb_length;
9483 if (one->support & RSO_ONE_CTDP) {
9484 struct scsi_report_supported_opcodes_timeout *td;
9486 td = (struct scsi_report_supported_opcodes_timeout *)
9488 if (valid_len >= (avail_len + sizeof(td->length))) {
9489 avail_len += scsi_2btoul(td->length) +
9492 avail_len += sizeof(*td);
9498 * avail_len could be zero if we didn't get enough data back from
9499 * thet target to determine
9501 if ((avail_len != 0)
9502 && (avail_len > valid_len)) {
9503 alloc_len = avail_len;
9507 *fill_len = valid_len;
9519 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9520 int req_sa, uint8_t *buf, uint32_t valid_len)
9522 struct scsi_report_supported_opcodes_one *one;
9523 struct scsi_report_supported_opcodes_timeout *td;
9524 uint32_t cdb_len = 0, td_len = 0;
9525 const char *op_desc = NULL;
9529 one = (struct scsi_report_supported_opcodes_one *)buf;
9532 * If we don't have the full single opcode descriptor, no point in
9535 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9537 warnx("Only %u bytes returned, not enough to verify support",
9543 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9545 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9548 printf(", SA 0x%x", req_sa);
9551 switch (one->support & RSO_ONE_SUP_MASK) {
9552 case RSO_ONE_SUP_UNAVAIL:
9553 printf("No command support information currently available\n");
9555 case RSO_ONE_SUP_NOT_SUP:
9556 printf("Command not supported\n");
9559 break; /*NOTREACHED*/
9560 case RSO_ONE_SUP_AVAIL:
9561 printf("Command is supported, complies with a SCSI standard\n");
9563 case RSO_ONE_SUP_VENDOR:
9564 printf("Command is supported, vendor-specific "
9565 "implementation\n");
9568 printf("Unknown command support flags 0x%#x\n",
9569 one->support & RSO_ONE_SUP_MASK);
9574 * If we don't have the CDB length, it isn't exactly an error, the
9575 * command probably isn't supported.
9577 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9581 cdb_len = scsi_2btoul(one->cdb_length);
9584 * If our valid data doesn't include the full reported length,
9585 * return. The caller should have detected this and adjusted his
9586 * allocation length to get all of the available data.
9588 if (valid_len < sizeof(*one) + cdb_len) {
9594 * If all we have is the opcode, there is no point in printing out
9602 printf("CDB usage bitmap:");
9603 for (i = 0; i < cdb_len; i++) {
9604 printf(" %02x", one->cdb_usage[i]);
9609 * If we don't have a timeout descriptor, we're done.
9611 if ((one->support & RSO_ONE_CTDP) == 0)
9615 * If we don't have enough valid length to include the timeout
9616 * descriptor length, we're done.
9618 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9621 td = (struct scsi_report_supported_opcodes_timeout *)
9622 &buf[sizeof(*one) + cdb_len];
9623 td_len = scsi_2btoul(td->length);
9624 td_len += sizeof(td->length);
9627 * If we don't have the full timeout descriptor, we're done.
9629 if (td_len < sizeof(*td))
9633 * If we don't have enough valid length to contain the full timeout
9634 * descriptor, we're done.
9636 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9639 printf("Timeout information:\n");
9640 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9641 printf("Nominal timeout: %u seconds\n",
9642 scsi_4btoul(td->nominal_time));
9643 printf("Recommended timeout: %u seconds\n",
9644 scsi_4btoul(td->recommended_time));
9651 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9654 struct scsi_report_supported_opcodes_all *hdr;
9655 struct scsi_report_supported_opcodes_descr *desc;
9656 uint32_t avail_len = 0, used_len = 0;
9660 if (valid_len < sizeof(*hdr)) {
9661 warnx("%s: not enough returned data (%u bytes) opcode list",
9662 __func__, valid_len);
9666 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9667 avail_len = scsi_4btoul(hdr->length);
9668 avail_len += sizeof(hdr->length);
9670 * Take the lesser of the amount of data the drive claims is
9671 * available, and the amount of data the HBA says was returned.
9673 avail_len = MIN(avail_len, valid_len);
9675 used_len = sizeof(hdr->length);
9677 printf("%-6s %4s %8s ",
9678 "Opcode", "SA", "CDB len" );
9681 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9682 printf(" Description\n");
9684 while ((avail_len - used_len) > sizeof(*desc)) {
9685 struct scsi_report_supported_opcodes_timeout *td;
9687 const char *op_desc = NULL;
9689 cur_ptr = &buf[used_len];
9690 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9692 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9693 if (op_desc == NULL)
9694 op_desc = "UNKNOWN";
9696 printf("0x%02x %#4x %8u ", desc->opcode,
9697 scsi_2btoul(desc->service_action),
9698 scsi_2btoul(desc->cdb_length));
9700 used_len += sizeof(*desc);
9702 if ((desc->flags & RSO_CTDP) == 0) {
9703 printf(" %s\n", op_desc);
9708 * If we don't have enough space to fit a timeout
9709 * descriptor, then we're done.
9711 if (avail_len - used_len < sizeof(*td)) {
9712 used_len = avail_len;
9713 printf(" %s\n", op_desc);
9716 cur_ptr = &buf[used_len];
9717 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9718 td_len = scsi_2btoul(td->length);
9719 td_len += sizeof(td->length);
9723 * If the given timeout descriptor length is less than what
9724 * we understand, skip it.
9726 if (td_len < sizeof(*td)) {
9727 printf(" %s\n", op_desc);
9731 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9732 scsi_4btoul(td->nominal_time),
9733 scsi_4btoul(td->recommended_time), op_desc);
9740 scsiopcodes(struct cam_device *device, int argc, char **argv,
9741 char *combinedopt, int task_attr, int retry_count, int timeout,
9745 uint32_t opcode = 0, service_action = 0;
9746 int td_set = 0, opcode_set = 0, sa_set = 0;
9747 int show_sa_errors = 1;
9748 uint32_t valid_len = 0;
9749 uint8_t *buf = NULL;
9753 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9759 opcode = strtoul(optarg, &endptr, 0);
9760 if (*endptr != '\0') {
9761 warnx("Invalid opcode \"%s\", must be a number",
9766 if (opcode > 0xff) {
9767 warnx("Invalid opcode 0x%#x, must be between"
9768 "0 and 0xff inclusive", opcode);
9775 service_action = strtoul(optarg, &endptr, 0);
9776 if (*endptr != '\0') {
9777 warnx("Invalid service action \"%s\", must "
9778 "be a number", optarg);
9782 if (service_action > 0xffff) {
9783 warnx("Invalid service action 0x%#x, must "
9784 "be between 0 and 0xffff inclusive",
9799 && (opcode_set == 0)) {
9800 warnx("You must specify an opcode with -o if a service "
9805 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9806 sa_set, service_action, td_set, task_attr,
9807 retry_count, timeout, verbosemode, &valid_len,
9812 if ((opcode_set != 0)
9814 retval = scsiprintoneopcode(device, opcode, sa_set,
9815 service_action, buf, valid_len);
9817 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9826 #endif /* MINIMALISTIC */
9829 reprobe(struct cam_device *device)
9834 ccb = cam_getccb(device);
9837 warnx("%s: error allocating ccb", __func__);
9841 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
9843 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9845 if (cam_send_ccb(device, ccb) < 0) {
9846 warn("error sending XPT_REPROBE_LUN CCB");
9851 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9852 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9864 usage(int printlong)
9867 fprintf(printlong ? stdout : stderr,
9868 "usage: camcontrol <command> [device id][generic args][command args]\n"
9869 " camcontrol devlist [-b] [-v]\n"
9870 #ifndef MINIMALISTIC
9871 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9872 " camcontrol tur [dev_id][generic args]\n"
9873 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9874 " camcontrol identify [dev_id][generic args] [-v]\n"
9875 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9876 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9878 " camcontrol start [dev_id][generic args]\n"
9879 " camcontrol stop [dev_id][generic args]\n"
9880 " camcontrol load [dev_id][generic args]\n"
9881 " camcontrol eject [dev_id][generic args]\n"
9882 " camcontrol reprobe [dev_id][generic args]\n"
9883 #endif /* MINIMALISTIC */
9884 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9885 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9886 #ifndef MINIMALISTIC
9887 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9888 " [-q][-s][-S offset][-X]\n"
9889 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9890 " [-P pagectl][-e | -b][-d]\n"
9891 " camcontrol cmd [dev_id][generic args]\n"
9892 " <-a cmd [args] | -c cmd [args]>\n"
9893 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9894 " camcontrol smpcmd [dev_id][generic args]\n"
9895 " <-r len fmt [args]> <-R len fmt [args]>\n"
9896 " camcontrol smprg [dev_id][generic args][-l]\n"
9897 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9898 " [-o operation][-d name][-m rate][-M rate]\n"
9899 " [-T pp_timeout][-a enable|disable]\n"
9900 " [-A enable|disable][-s enable|disable]\n"
9901 " [-S enable|disable]\n"
9902 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9903 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9904 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9905 " <all|dev_id|bus[:target[:lun]]|off>\n"
9906 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9907 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9908 " [-D <enable|disable>][-M mode][-O offset]\n"
9909 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9910 " [-U][-W bus_width]\n"
9911 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9912 " camcontrol sanitize [dev_id][generic args]\n"
9913 " [-a overwrite|block|crypto|exitfailure]\n"
9914 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9916 " camcontrol idle [dev_id][generic args][-t time]\n"
9917 " camcontrol standby [dev_id][generic args][-t time]\n"
9918 " camcontrol sleep [dev_id][generic args]\n"
9919 " camcontrol powermode [dev_id][generic args]\n"
9920 " camcontrol apm [dev_id][generic args][-l level]\n"
9921 " camcontrol aam [dev_id][generic args][-l level]\n"
9922 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9924 " camcontrol security [dev_id][generic args]\n"
9925 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9926 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9927 " [-U <user|master>] [-y]\n"
9928 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9929 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9930 " camcontrol ama [dev_id][generic args] [-f] [-q] [-s max_sectors]\n"
9931 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9932 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9933 " [-s scope][-S][-T type][-U]\n"
9934 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9935 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9936 " [-p part][-s start][-T type][-V vol]\n"
9937 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9939 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9940 " [-o rep_opts] [-P print_opts]\n"
9941 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9942 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9943 " [-S power_src] [-T timer]\n"
9944 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9945 " <-s <-f format -T time | -U >>\n"
9946 " camcontrol devtype [dev_id]\n"
9948 #endif /* MINIMALISTIC */
9949 " camcontrol help\n");
9952 #ifndef MINIMALISTIC
9954 "Specify one of the following options:\n"
9955 "devlist list all CAM devices\n"
9956 "periphlist list all CAM peripheral drivers attached to a device\n"
9957 "tur send a test unit ready to the named device\n"
9958 "inquiry send a SCSI inquiry command to the named device\n"
9959 "identify send a ATA identify command to the named device\n"
9960 "reportluns send a SCSI report luns command to the device\n"
9961 "readcap send a SCSI read capacity command to the device\n"
9962 "start send a Start Unit command to the device\n"
9963 "stop send a Stop Unit command to the device\n"
9964 "load send a Start Unit command to the device with the load bit set\n"
9965 "eject send a Stop Unit command to the device with the eject bit set\n"
9966 "reprobe update capacity information of the given device\n"
9967 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9968 "reset reset all buses, the given bus, bus:target:lun or device\n"
9969 "defects read the defect list of the specified device\n"
9970 "modepage display or edit (-e) the given mode page\n"
9971 "cmd send the given SCSI command, may need -i or -o as well\n"
9972 "smpcmd send the given SMP command, requires -o and -i\n"
9973 "smprg send the SMP Report General command\n"
9974 "smppc send the SMP PHY Control command, requires -p\n"
9975 "smpphylist display phys attached to a SAS expander\n"
9976 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9977 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9978 "tags report or set the number of transaction slots for a device\n"
9979 "negotiate report or set device negotiation parameters\n"
9980 "format send the SCSI FORMAT UNIT command to the named device\n"
9981 "sanitize send the SCSI SANITIZE command to the named device\n"
9982 "idle send the ATA IDLE command to the named device\n"
9983 "standby send the ATA STANDBY command to the named device\n"
9984 "sleep send the ATA SLEEP command to the named device\n"
9985 "powermode send the ATA CHECK POWER MODE command to the named device\n"
9986 "fwdownload program firmware of the named device with the given image\n"
9987 "security report or send ATA security commands to the named device\n"
9988 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9989 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9990 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9991 "zone manage Zoned Block (Shingled) devices\n"
9992 "epc send ATA Extended Power Conditions commands\n"
9993 "timestamp report or set the device's timestamp\n"
9994 "devtype report the type of device\n"
9995 "help this message\n"
9996 "Device Identifiers:\n"
9997 "bus:target specify the bus and target, lun defaults to 0\n"
9998 "bus:target:lun specify the bus, target and lun\n"
9999 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
10000 "Generic arguments:\n"
10001 "-v be verbose, print out sense information\n"
10002 "-t timeout command timeout in seconds, overrides default timeout\n"
10003 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
10004 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
10005 "-E have the kernel attempt to perform SCSI error recovery\n"
10006 "-C count specify the SCSI command retry count (needs -E to work)\n"
10007 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
10008 "modepage arguments:\n"
10009 "-l list all available mode pages\n"
10010 "-m page specify the mode page to view or edit\n"
10011 "-e edit the specified mode page\n"
10012 "-b force view to binary mode\n"
10013 "-d disable block descriptors for mode sense\n"
10014 "-P pgctl page control field 0-3\n"
10015 "defects arguments:\n"
10016 "-f format specify defect list format (block, bfi or phys)\n"
10017 "-G get the grown defect list\n"
10018 "-P get the permanent defect list\n"
10019 "inquiry arguments:\n"
10020 "-D get the standard inquiry data\n"
10021 "-S get the serial number\n"
10022 "-R get the transfer rate, etc.\n"
10023 "reportluns arguments:\n"
10024 "-c only report a count of available LUNs\n"
10025 "-l only print out luns, and not a count\n"
10026 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
10027 "readcap arguments\n"
10028 "-b only report the blocksize\n"
10029 "-h human readable device size, base 2\n"
10030 "-H human readable device size, base 10\n"
10031 "-N print the number of blocks instead of last block\n"
10032 "-q quiet, print numbers only\n"
10033 "-s only report the last block/device size\n"
10035 "-c cdb [args] specify the SCSI CDB\n"
10036 "-i len fmt specify input data and input data format\n"
10037 "-o len fmt [args] specify output data and output data fmt\n"
10038 "smpcmd arguments:\n"
10039 "-r len fmt [args] specify the SMP command to be sent\n"
10040 "-R len fmt [args] specify SMP response format\n"
10041 "smprg arguments:\n"
10042 "-l specify the long response format\n"
10043 "smppc arguments:\n"
10044 "-p phy specify the PHY to operate on\n"
10045 "-l specify the long request/response format\n"
10046 "-o operation specify the phy control operation\n"
10047 "-d name set the attached device name\n"
10048 "-m rate set the minimum physical link rate\n"
10049 "-M rate set the maximum physical link rate\n"
10050 "-T pp_timeout set the partial pathway timeout value\n"
10051 "-a enable|disable enable or disable SATA slumber\n"
10052 "-A enable|disable enable or disable SATA partial phy power\n"
10053 "-s enable|disable enable or disable SAS slumber\n"
10054 "-S enable|disable enable or disable SAS partial phy power\n"
10055 "smpphylist arguments:\n"
10056 "-l specify the long response format\n"
10057 "-q only print phys with attached devices\n"
10058 "smpmaninfo arguments:\n"
10059 "-l specify the long response format\n"
10060 "debug arguments:\n"
10061 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
10062 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
10063 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
10064 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
10065 "tags arguments:\n"
10066 "-N tags specify the number of tags to use for this device\n"
10067 "-q be quiet, don't report the number of tags\n"
10068 "-v report a number of tag-related parameters\n"
10069 "negotiate arguments:\n"
10070 "-a send a test unit ready after negotiation\n"
10071 "-c report/set current negotiation settings\n"
10072 "-D <arg> \"enable\" or \"disable\" disconnection\n"
10073 "-M mode set ATA mode\n"
10074 "-O offset set command delay offset\n"
10075 "-q be quiet, don't report anything\n"
10076 "-R syncrate synchronization rate in MHz\n"
10077 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
10078 "-U report/set user negotiation settings\n"
10079 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
10080 "-v also print a Path Inquiry CCB for the controller\n"
10081 "format arguments:\n"
10082 "-q be quiet, don't print status messages\n"
10083 "-r run in report only mode\n"
10084 "-w don't send immediate format command\n"
10085 "-y don't ask any questions\n"
10086 "sanitize arguments:\n"
10087 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
10088 "-c passes overwrite passes to perform (1 to 31)\n"
10089 "-I invert overwrite pattern after each pass\n"
10090 "-P pattern path to overwrite pattern file\n"
10091 "-q be quiet, don't print status messages\n"
10092 "-r run in report only mode\n"
10093 "-U run operation in unrestricted completion exit mode\n"
10094 "-w don't send immediate sanitize command\n"
10095 "-y don't ask any questions\n"
10096 "idle/standby arguments:\n"
10097 "-t <arg> number of seconds before respective state.\n"
10098 "fwdownload arguments:\n"
10099 "-f fw_image path to firmware image file\n"
10100 "-q don't print informational messages, only errors\n"
10101 "-s run in simulation mode\n"
10102 "-v print info for every firmware segment sent to device\n"
10103 "-y don't ask any questions\n"
10104 "security arguments:\n"
10105 "-d pwd disable security using the given password for the selected\n"
10107 "-e pwd erase the device using the given pwd for the selected user\n"
10108 "-f freeze the security configuration of the specified device\n"
10109 "-h pwd enhanced erase the device using the given pwd for the\n"
10111 "-k pwd unlock the device using the given pwd for the selected\n"
10113 "-l <high|maximum> specifies which security level to set: high or maximum\n"
10114 "-q be quiet, do not print any status messages\n"
10115 "-s pwd password the device (enable security) using the given\n"
10116 " pwd for the selected user\n"
10117 "-T timeout overrides the timeout (seconds) used for erase operation\n"
10118 "-U <user|master> specifies which user to set: user or master\n"
10119 "-y don't ask any questions\n"
10121 "-f freeze the HPA configuration of the device\n"
10122 "-l lock the HPA configuration of the device\n"
10123 "-P make the HPA max sectors persist\n"
10124 "-p pwd Set the HPA configuration password required for unlock\n"
10126 "-q be quiet, do not print any status messages\n"
10127 "-s sectors configures the maximum user accessible sectors of the\n"
10129 "-U pwd unlock the HPA configuration of the device\n"
10130 "-y don't ask any questions\n"
10132 "-f freeze the AMA configuration of the device\n"
10133 "-q be quiet, do not print any status messages\n"
10134 "-s sectors configures the maximum user accessible sectors of the\n"
10136 "persist arguments:\n"
10137 "-i action specify read_keys, read_reservation, report_cap, or\n"
10138 " read_full_status\n"
10139 "-o action specify register, register_ignore, reserve, release,\n"
10140 " clear, preempt, preempt_abort, register_move, replace_lost\n"
10141 "-a set the All Target Ports (ALL_TG_PT) bit\n"
10142 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
10143 "-k key specify the Reservation Key\n"
10144 "-K sa_key specify the Service Action Reservation Key\n"
10145 "-p set the Activate Persist Through Power Loss bit\n"
10146 "-R rtp specify the Relative Target Port\n"
10147 "-s scope specify the scope: lun, extent, element or a number\n"
10148 "-S specify Transport ID for register, requires -I\n"
10149 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
10150 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
10151 "-U unregister the current initiator for register_move\n"
10152 "attrib arguments:\n"
10153 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
10155 "-w attr specify an attribute to write, one -w argument per attr\n"
10156 "-a attr_num only display this attribute number\n"
10157 "-c get cached attributes\n"
10158 "-e elem_addr request attributes for the given element in a changer\n"
10159 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
10160 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
10161 " field_none, field_desc, field_num, field_size, field_rw\n"
10162 "-p partition request attributes for the given partition\n"
10163 "-s start_attr request attributes starting at the given number\n"
10164 "-T elem_type specify the element type (used with -e)\n"
10165 "-V logical_vol specify the logical volume ID\n"
10166 "opcodes arguments:\n"
10167 "-o opcode specify the individual opcode to list\n"
10168 "-s service_action specify the service action for the opcode\n"
10169 "-N do not return SCSI error for unsupported SA\n"
10170 "-T request nominal and recommended timeout values\n"
10171 "zone arguments:\n"
10172 "-c cmd required: rz, open, close, finish, or rwp\n"
10173 "-a apply the action to all zones\n"
10174 "-l LBA specify the zone starting LBA\n"
10175 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
10176 " closed, full, ro, offline, reset, nonseq, nonwp\n"
10177 "-P print_opt report zones printing: normal, summary, script\n"
10179 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
10180 " source, status, list\n"
10181 "-d disable power mode (timer, state)\n"
10182 "-D delayed entry (goto)\n"
10183 "-e enable power mode (timer, state)\n"
10184 "-H hold power mode (goto)\n"
10185 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
10187 "-P only display power mode (status)\n"
10188 "-r rst_src restore settings from: default, saved (restore)\n"
10189 "-s save mode (timer, state, restore)\n"
10190 "-S power_src set power source: battery, nonbattery (source)\n"
10191 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
10192 "timestamp arguments:\n"
10193 "-r report the timestamp of the device\n"
10194 "-f format report the timestamp of the device with the given\n"
10195 " strftime(3) format string\n"
10196 "-m report the timestamp of the device as milliseconds since\n"
10197 " January 1st, 1970\n"
10198 "-U report the time with UTC instead of the local time zone\n"
10199 "-s set the timestamp of the device\n"
10200 "-f format the format of the time string passed into strptime(3)\n"
10201 "-T time the time value passed into strptime(3)\n"
10202 "-U set the timestamp of the device to UTC time\n"
10204 #endif /* MINIMALISTIC */
10208 main(int argc, char **argv)
10211 char *device = NULL;
10213 struct cam_device *cam_dev = NULL;
10214 int timeout = 0, retry_count = 1;
10215 camcontrol_optret optreturn;
10217 const char *mainopt = "C:En:Q:t:u:v";
10218 const char *subopt = NULL;
10219 char combinedopt[256];
10220 int error = 0, optstart = 2;
10221 int task_attr = MSG_SIMPLE_Q_TAG;
10223 #ifndef MINIMALISTIC
10225 target_id_t target;
10227 #endif /* MINIMALISTIC */
10229 cmdlist = CAM_CMD_NONE;
10230 arglist = CAM_ARG_NONE;
10238 * Get the base option.
10240 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
10242 if (optreturn == CC_OR_AMBIGUOUS) {
10243 warnx("ambiguous option %s", argv[1]);
10246 } else if (optreturn == CC_OR_NOT_FOUND) {
10247 warnx("option %s not found", argv[1]);
10253 * Ahh, getopt(3) is a pain.
10255 * This is a gross hack. There really aren't many other good
10256 * options (excuse the pun) for parsing options in a situation like
10257 * this. getopt is kinda braindead, so you end up having to run
10258 * through the options twice, and give each invocation of getopt
10259 * the option string for the other invocation.
10261 * You would think that you could just have two groups of options.
10262 * The first group would get parsed by the first invocation of
10263 * getopt, and the second group would get parsed by the second
10264 * invocation of getopt. It doesn't quite work out that way. When
10265 * the first invocation of getopt finishes, it leaves optind pointing
10266 * to the argument _after_ the first argument in the second group.
10267 * So when the second invocation of getopt comes around, it doesn't
10268 * recognize the first argument it gets and then bails out.
10270 * A nice alternative would be to have a flag for getopt that says
10271 * "just keep parsing arguments even when you encounter an unknown
10272 * argument", but there isn't one. So there's no real clean way to
10273 * easily parse two sets of arguments without having one invocation
10274 * of getopt know about the other.
10276 * Without this hack, the first invocation of getopt would work as
10277 * long as the generic arguments are first, but the second invocation
10278 * (in the subfunction) would fail in one of two ways. In the case
10279 * where you don't set optreset, it would fail because optind may be
10280 * pointing to the argument after the one it should be pointing at.
10281 * In the case where you do set optreset, and reset optind, it would
10282 * fail because getopt would run into the first set of options, which
10283 * it doesn't understand.
10285 * All of this would "sort of" work if you could somehow figure out
10286 * whether optind had been incremented one option too far. The
10287 * mechanics of that, however, are more daunting than just giving
10288 * both invocations all of the expect options for either invocation.
10290 * Needless to say, I wouldn't mind if someone invented a better
10291 * (non-GPL!) command line parsing interface than getopt. I
10292 * wouldn't mind if someone added more knobs to getopt to make it
10293 * work better. Who knows, I may talk myself into doing it someday,
10294 * if the standards weenies let me. As it is, it just leads to
10295 * hackery like this and causes people to avoid it in some cases.
10297 * KDM, September 8th, 1998
10299 if (subopt != NULL)
10300 sprintf(combinedopt, "%s%s", mainopt, subopt);
10302 sprintf(combinedopt, "%s", mainopt);
10305 * For these options we do not parse optional device arguments and
10306 * we do not open a passthrough device.
10308 if ((cmdlist == CAM_CMD_RESCAN)
10309 || (cmdlist == CAM_CMD_RESET)
10310 || (cmdlist == CAM_CMD_DEVTREE)
10311 || (cmdlist == CAM_CMD_USAGE)
10312 || (cmdlist == CAM_CMD_DEBUG))
10315 #ifndef MINIMALISTIC
10317 && (argc > 2 && argv[2][0] != '-')) {
10321 if (isdigit(argv[2][0])) {
10322 /* device specified as bus:target[:lun] */
10323 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10325 errx(1, "numeric device specification must "
10326 "be either bus:target, or "
10328 /* default to 0 if lun was not specified */
10329 if ((arglist & CAM_ARG_LUN) == 0) {
10331 arglist |= CAM_ARG_LUN;
10335 if (cam_get_device(argv[2], name, sizeof name, &unit)
10337 errx(1, "%s", cam_errbuf);
10338 device = strdup(name);
10339 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10343 #endif /* MINIMALISTIC */
10345 * Start getopt processing at argv[2/3], since we've already
10346 * accepted argv[1..2] as the command name, and as a possible
10352 * Now we run through the argument list looking for generic
10353 * options, and ignoring options that possibly belong to
10356 while ((c = getopt(argc, argv, combinedopt))!= -1){
10359 retry_count = strtol(optarg, NULL, 0);
10360 if (retry_count < 0)
10361 errx(1, "retry count %d is < 0",
10363 arglist |= CAM_ARG_RETRIES;
10366 arglist |= CAM_ARG_ERR_RECOVER;
10369 arglist |= CAM_ARG_DEVICE;
10371 while (isspace(*tstr) && (*tstr != '\0'))
10373 device = (char *)strdup(tstr);
10377 int table_entry = 0;
10380 while (isspace(*tstr) && (*tstr != '\0'))
10382 if (isdigit(*tstr)) {
10383 task_attr = strtol(tstr, &endptr, 0);
10384 if (*endptr != '\0') {
10385 errx(1, "Invalid queue option "
10390 scsi_nv_status status;
10392 table_size = sizeof(task_attrs) /
10393 sizeof(task_attrs[0]);
10394 status = scsi_get_nv(task_attrs,
10395 table_size, tstr, &table_entry,
10396 SCSI_NV_FLAG_IG_CASE);
10397 if (status == SCSI_NV_FOUND)
10398 task_attr = task_attrs[
10399 table_entry].value;
10401 errx(1, "%s option %s",
10402 (status == SCSI_NV_AMBIGUOUS)?
10403 "ambiguous" : "invalid",
10410 timeout = strtol(optarg, NULL, 0);
10412 errx(1, "invalid timeout %d", timeout);
10413 /* Convert the timeout from seconds to ms */
10415 arglist |= CAM_ARG_TIMEOUT;
10418 arglist |= CAM_ARG_UNIT;
10419 unit = strtol(optarg, NULL, 0);
10422 arglist |= CAM_ARG_VERBOSE;
10429 #ifndef MINIMALISTIC
10431 * For most commands we'll want to open the passthrough device
10432 * associated with the specified device. In the case of the rescan
10433 * commands, we don't use a passthrough device at all, just the
10434 * transport layer device.
10436 if (devopen == 1) {
10437 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10438 && (((arglist & CAM_ARG_DEVICE) == 0)
10439 || ((arglist & CAM_ARG_UNIT) == 0))) {
10440 errx(1, "subcommand \"%s\" requires a valid device "
10441 "identifier", argv[1]);
10444 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10445 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10446 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10448 errx(1,"%s", cam_errbuf);
10450 #endif /* MINIMALISTIC */
10453 * Reset optind to 2, and reset getopt, so these routines can parse
10454 * the arguments again.
10460 #ifndef MINIMALISTIC
10461 case CAM_CMD_DEVLIST:
10462 error = getdevlist(cam_dev);
10465 error = atahpa(cam_dev, retry_count, timeout,
10466 argc, argv, combinedopt);
10469 error = ataama(cam_dev, retry_count, timeout,
10470 argc, argv, combinedopt);
10472 #endif /* MINIMALISTIC */
10473 case CAM_CMD_DEVTREE:
10474 error = getdevtree(argc, argv, combinedopt);
10476 case CAM_CMD_DEVTYPE:
10477 error = getdevtype(cam_dev);
10479 #ifndef MINIMALISTIC
10481 error = testunitready(cam_dev, task_attr, retry_count,
10484 case CAM_CMD_INQUIRY:
10485 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10486 task_attr, retry_count, timeout);
10488 case CAM_CMD_IDENTIFY:
10489 error = identify(cam_dev, retry_count, timeout);
10491 case CAM_CMD_STARTSTOP:
10492 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10493 arglist & CAM_ARG_EJECT, task_attr,
10494 retry_count, timeout);
10496 #endif /* MINIMALISTIC */
10497 case CAM_CMD_RESCAN:
10498 error = dorescan_or_reset(argc, argv, 1);
10500 case CAM_CMD_RESET:
10501 error = dorescan_or_reset(argc, argv, 0);
10503 #ifndef MINIMALISTIC
10504 case CAM_CMD_READ_DEFECTS:
10505 error = readdefects(cam_dev, argc, argv, combinedopt,
10506 task_attr, retry_count, timeout);
10508 case CAM_CMD_MODE_PAGE:
10509 modepage(cam_dev, argc, argv, combinedopt,
10510 task_attr, retry_count, timeout);
10512 case CAM_CMD_SCSI_CMD:
10513 error = scsicmd(cam_dev, argc, argv, combinedopt,
10514 task_attr, retry_count, timeout);
10516 case CAM_CMD_MMCSD_CMD:
10517 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10518 retry_count, timeout);
10520 case CAM_CMD_SMP_CMD:
10521 error = smpcmd(cam_dev, argc, argv, combinedopt,
10522 retry_count, timeout);
10524 case CAM_CMD_SMP_RG:
10525 error = smpreportgeneral(cam_dev, argc, argv,
10526 combinedopt, retry_count,
10529 case CAM_CMD_SMP_PC:
10530 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10531 retry_count, timeout);
10533 case CAM_CMD_SMP_PHYLIST:
10534 error = smpphylist(cam_dev, argc, argv, combinedopt,
10535 retry_count, timeout);
10537 case CAM_CMD_SMP_MANINFO:
10538 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10539 retry_count, timeout);
10541 case CAM_CMD_DEBUG:
10542 error = camdebug(argc, argv, combinedopt);
10545 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10548 error = ratecontrol(cam_dev, task_attr, retry_count,
10549 timeout, argc, argv, combinedopt);
10551 case CAM_CMD_FORMAT:
10552 error = scsiformat(cam_dev, argc, argv,
10553 combinedopt, task_attr, retry_count,
10556 case CAM_CMD_REPORTLUNS:
10557 error = scsireportluns(cam_dev, argc, argv,
10558 combinedopt, task_attr,
10559 retry_count, timeout);
10561 case CAM_CMD_READCAP:
10562 error = scsireadcapacity(cam_dev, argc, argv,
10563 combinedopt, task_attr,
10564 retry_count, timeout);
10567 case CAM_CMD_STANDBY:
10568 case CAM_CMD_SLEEP:
10569 case CAM_CMD_POWER_MODE:
10570 error = atapm(cam_dev, argc, argv,
10571 combinedopt, retry_count, timeout);
10575 error = ataaxm(cam_dev, argc, argv,
10576 combinedopt, retry_count, timeout);
10578 case CAM_CMD_SECURITY:
10579 error = atasecurity(cam_dev, retry_count, timeout,
10580 argc, argv, combinedopt);
10582 case CAM_CMD_DOWNLOAD_FW:
10583 error = fwdownload(cam_dev, argc, argv, combinedopt,
10584 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10587 case CAM_CMD_SANITIZE:
10588 error = sanitize(cam_dev, argc, argv, combinedopt, task_attr,
10589 retry_count, timeout);
10591 case CAM_CMD_PERSIST:
10592 error = scsipersist(cam_dev, argc, argv, combinedopt,
10593 task_attr, retry_count, timeout,
10594 arglist & CAM_ARG_VERBOSE,
10595 arglist & CAM_ARG_ERR_RECOVER);
10597 case CAM_CMD_ATTRIB:
10598 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10599 task_attr, retry_count, timeout,
10600 arglist & CAM_ARG_VERBOSE,
10601 arglist & CAM_ARG_ERR_RECOVER);
10603 case CAM_CMD_OPCODES:
10604 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10605 task_attr, retry_count, timeout,
10606 arglist & CAM_ARG_VERBOSE);
10608 case CAM_CMD_REPROBE:
10609 error = reprobe(cam_dev);
10612 error = zone(cam_dev, argc, argv, combinedopt,
10613 task_attr, retry_count, timeout,
10614 arglist & CAM_ARG_VERBOSE);
10617 error = epc(cam_dev, argc, argv, combinedopt,
10618 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10620 case CAM_CMD_TIMESTAMP:
10621 error = timestamp(cam_dev, argc, argv, combinedopt,
10622 task_attr, retry_count, timeout,
10623 arglist & CAM_ARG_VERBOSE);
10625 #endif /* MINIMALISTIC */
10626 case CAM_CMD_USAGE:
10635 if (cam_dev != NULL)
10636 cam_close_device(cam_dev);