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 char pass[sizeof(pwd->password)+1];
2484 /* pwd->password may not be null terminated */
2485 pass[sizeof(pwd->password)] = '\0';
2486 strncpy(pass, pwd->password, sizeof(pwd->password));
2487 printf(" password='%s', user='%s'",
2489 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2492 if (command == ATA_SECURITY_SET_PASSWORD) {
2493 printf(", mode='%s'",
2494 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2495 "maximum" : "high");
2503 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2504 int retry_count, u_int32_t timeout, int quiet)
2508 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2510 return ata_do_cmd(device,
2513 /*flags*/CAM_DIR_NONE,
2514 /*protocol*/AP_PROTO_NON_DATA,
2516 /*tag_action*/MSG_SIMPLE_Q_TAG,
2517 /*command*/ATA_SECURITY_FREEZE_LOCK,
2528 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2529 int retry_count, u_int32_t timeout,
2530 struct ata_security_password *pwd, int quiet)
2534 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2536 return ata_do_cmd(device,
2539 /*flags*/CAM_DIR_OUT,
2540 /*protocol*/AP_PROTO_PIO_OUT,
2541 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2542 AP_FLAG_TLEN_SECT_CNT,
2543 /*tag_action*/MSG_SIMPLE_Q_TAG,
2544 /*command*/ATA_SECURITY_UNLOCK,
2547 /*sector_count*/sizeof(*pwd) / 512,
2548 /*data_ptr*/(u_int8_t *)pwd,
2549 /*dxfer_len*/sizeof(*pwd),
2555 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2556 int retry_count, u_int32_t timeout,
2557 struct ata_security_password *pwd, int quiet)
2561 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2562 return ata_do_cmd(device,
2565 /*flags*/CAM_DIR_OUT,
2566 /*protocol*/AP_PROTO_PIO_OUT,
2567 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2568 AP_FLAG_TLEN_SECT_CNT,
2569 /*tag_action*/MSG_SIMPLE_Q_TAG,
2570 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2573 /*sector_count*/sizeof(*pwd) / 512,
2574 /*data_ptr*/(u_int8_t *)pwd,
2575 /*dxfer_len*/sizeof(*pwd),
2582 atasecurity_erase_confirm(struct cam_device *device,
2583 struct ata_params* ident_buf)
2586 printf("\nYou are about to ERASE ALL DATA from the following"
2587 " device:\n%s%d,%s%d: ", device->device_name,
2588 device->dev_unit_num, device->given_dev_name,
2589 device->given_unit_number);
2590 ata_print_ident(ident_buf);
2594 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2596 if (fgets(str, sizeof(str), stdin) != NULL) {
2597 if (strncasecmp(str, "yes", 3) == 0) {
2599 } else if (strncasecmp(str, "no", 2) == 0) {
2602 printf("Please answer \"yes\" or "
2613 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2614 int retry_count, u_int32_t timeout,
2615 u_int32_t erase_timeout,
2616 struct ata_security_password *pwd, int quiet)
2621 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2623 error = ata_do_cmd(device,
2626 /*flags*/CAM_DIR_NONE,
2627 /*protocol*/AP_PROTO_NON_DATA,
2629 /*tag_action*/MSG_SIMPLE_Q_TAG,
2630 /*command*/ATA_SECURITY_ERASE_PREPARE,
2643 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2645 error = ata_do_cmd(device,
2648 /*flags*/CAM_DIR_OUT,
2649 /*protocol*/AP_PROTO_PIO_OUT,
2650 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2651 AP_FLAG_TLEN_SECT_CNT,
2652 /*tag_action*/MSG_SIMPLE_Q_TAG,
2653 /*command*/ATA_SECURITY_ERASE_UNIT,
2656 /*sector_count*/sizeof(*pwd) / 512,
2657 /*data_ptr*/(u_int8_t *)pwd,
2658 /*dxfer_len*/sizeof(*pwd),
2659 /*timeout*/erase_timeout,
2662 if (error == 0 && quiet == 0)
2663 printf("\nErase Complete\n");
2669 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2670 int retry_count, u_int32_t timeout,
2671 struct ata_security_password *pwd, int quiet)
2675 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2677 return ata_do_cmd(device,
2680 /*flags*/CAM_DIR_OUT,
2681 /*protocol*/AP_PROTO_PIO_OUT,
2682 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2683 AP_FLAG_TLEN_SECT_CNT,
2684 /*tag_action*/MSG_SIMPLE_Q_TAG,
2685 /*command*/ATA_SECURITY_SET_PASSWORD,
2688 /*sector_count*/sizeof(*pwd) / 512,
2689 /*data_ptr*/(u_int8_t *)pwd,
2690 /*dxfer_len*/sizeof(*pwd),
2696 atasecurity_print(struct ata_params *parm)
2699 printf("\nSecurity Option Value\n");
2700 if (arglist & CAM_ARG_VERBOSE) {
2701 printf("status %04x\n",
2702 parm->security_status);
2704 printf("supported %s\n",
2705 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2706 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2708 printf("enabled %s\n",
2709 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2710 printf("drive locked %s\n",
2711 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2712 printf("security config frozen %s\n",
2713 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2714 printf("count expired %s\n",
2715 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2716 printf("security level %s\n",
2717 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2718 printf("enhanced erase supported %s\n",
2719 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2720 printf("erase time ");
2721 atasecurity_print_time(parm->erase_time);
2723 printf("enhanced erase time ");
2724 atasecurity_print_time(parm->enhanced_erase_time);
2726 printf("master password rev %04x%s\n",
2727 parm->master_passwd_revision,
2728 parm->master_passwd_revision == 0x0000 ||
2729 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2733 * Validates and copies the password in optarg to the passed buffer.
2734 * If the password in optarg is the same length as the buffer then
2735 * the data will still be copied but no null termination will occur.
2738 ata_getpwd(u_int8_t *passwd, int max, char opt)
2742 len = strlen(optarg);
2744 warnx("-%c password is too long", opt);
2746 } else if (len == 0) {
2747 warnx("-%c password is missing", opt);
2749 } else if (optarg[0] == '-'){
2750 warnx("-%c password starts with '-' (generic arg?)", opt);
2752 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2753 warnx("-%c password conflicts with existing password from -%c",
2758 /* Callers pass in a buffer which does NOT need to be terminated */
2759 strncpy(passwd, optarg, max);
2766 ATA_HPA_ACTION_PRINT,
2767 ATA_HPA_ACTION_SET_MAX,
2768 ATA_HPA_ACTION_SET_PWD,
2769 ATA_HPA_ACTION_LOCK,
2770 ATA_HPA_ACTION_UNLOCK,
2771 ATA_HPA_ACTION_FREEZE_LOCK
2775 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2776 u_int64_t maxsize, int persist)
2778 printf("\nYou are about to configure HPA to limit the user accessible\n"
2779 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2780 persist ? "persistently" : "temporarily",
2781 device->device_name, device->dev_unit_num,
2782 device->given_dev_name, device->given_unit_number);
2783 ata_print_ident(ident_buf);
2787 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2789 if (NULL != fgets(str, sizeof(str), stdin)) {
2790 if (0 == strncasecmp(str, "yes", 3)) {
2792 } else if (0 == strncasecmp(str, "no", 2)) {
2795 printf("Please answer \"yes\" or "
2806 atahpa(struct cam_device *device, int retry_count, int timeout,
2807 int argc, char **argv, char *combinedopt)
2810 struct ata_params *ident_buf;
2811 struct ccb_getdev cgd;
2812 struct ata_set_max_pwd pwd;
2813 int error, confirm, quiet, c, action, actions, persist;
2814 int security, is48bit, pwdsize;
2815 u_int64_t hpasize, maxsize;
2824 memset(&pwd, 0, sizeof(pwd));
2826 /* default action is to print hpa information */
2827 action = ATA_HPA_ACTION_PRINT;
2828 pwdsize = sizeof(pwd.password);
2830 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2833 action = ATA_HPA_ACTION_SET_MAX;
2834 maxsize = strtoumax(optarg, NULL, 0);
2839 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2841 action = ATA_HPA_ACTION_SET_PWD;
2847 action = ATA_HPA_ACTION_LOCK;
2853 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2855 action = ATA_HPA_ACTION_UNLOCK;
2861 action = ATA_HPA_ACTION_FREEZE_LOCK;
2881 warnx("too many hpa actions specified");
2885 if (get_cgd(device, &cgd) != 0) {
2886 warnx("couldn't get CGD");
2890 ccb = cam_getccb(device);
2892 warnx("couldn't allocate CCB");
2896 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2903 printf("%s%d: ", device->device_name, device->dev_unit_num);
2904 ata_print_ident(ident_buf);
2905 camxferrate(device);
2908 if (action == ATA_HPA_ACTION_PRINT) {
2910 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)
2911 ata_read_native_max(device, retry_count, timeout, ccb,
2912 ident_buf, &hpasize);
2913 atahpa_print(ident_buf, hpasize, 1);
2920 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2921 warnx("HPA is not supported by this device");
2927 if (security && !(ident_buf->support.command2 & ATA_SUPPORT_MAXSECURITY)) {
2928 warnx("HPA Security is not supported by this device");
2934 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2937 * The ATA spec requires:
2938 * 1. Read native max addr is called directly before set max addr
2939 * 2. Read native max addr is NOT called before any other set max call
2942 case ATA_HPA_ACTION_SET_MAX:
2944 atahpa_set_confirm(device, ident_buf, maxsize,
2951 error = ata_read_native_max(device, retry_count, timeout,
2952 ccb, ident_buf, &hpasize);
2954 error = atahpa_set_max(device, retry_count, timeout,
2955 ccb, is48bit, maxsize, persist);
2958 /* redo identify to get new values */
2959 error = ata_do_identify(device,
2960 retry_count, timeout, ccb,
2962 atahpa_print(ident_buf, hpasize, 1);
2964 /* Hint CAM to reprobe the device. */
2970 case ATA_HPA_ACTION_SET_PWD:
2971 error = atahpa_password(device, retry_count, timeout,
2972 ccb, is48bit, &pwd);
2973 if (error == 0 && quiet == 0)
2974 printf("HPA password has been set\n");
2977 case ATA_HPA_ACTION_LOCK:
2978 error = atahpa_lock(device, retry_count, timeout,
2980 if (error == 0 && quiet == 0)
2981 printf("HPA has been locked\n");
2984 case ATA_HPA_ACTION_UNLOCK:
2985 error = atahpa_unlock(device, retry_count, timeout,
2986 ccb, is48bit, &pwd);
2987 if (error == 0 && quiet == 0)
2988 printf("HPA has been unlocked\n");
2991 case ATA_HPA_ACTION_FREEZE_LOCK:
2992 error = atahpa_freeze_lock(device, retry_count, timeout,
2994 if (error == 0 && quiet == 0)
2995 printf("HPA has been frozen\n");
2999 errx(1, "Option currently not supported");
3009 ATA_AMA_ACTION_PRINT,
3010 ATA_AMA_ACTION_SET_MAX,
3011 ATA_AMA_ACTION_FREEZE_LOCK
3015 ataama(struct cam_device *device, int retry_count, int timeout,
3016 int argc, char **argv, char *combinedopt)
3019 struct ata_params *ident_buf;
3020 struct ccb_getdev cgd;
3021 int error, quiet, c, action, actions;
3022 u_int64_t nativesize, maxsize;
3028 /* default action is to print AMA information */
3029 action = ATA_AMA_ACTION_PRINT;
3031 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3034 action = ATA_AMA_ACTION_SET_MAX;
3035 maxsize = strtoumax(optarg, NULL, 0);
3040 action = ATA_AMA_ACTION_FREEZE_LOCK;
3051 warnx("too many AMA actions specified");
3055 if (get_cgd(device, &cgd) != 0) {
3056 warnx("couldn't get CGD");
3060 ccb = cam_getccb(device);
3062 warnx("couldn't allocate CCB");
3066 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3073 printf("%s%d: ", device->device_name, device->dev_unit_num);
3074 ata_print_ident(ident_buf);
3075 camxferrate(device);
3078 if (action == ATA_AMA_ACTION_PRINT) {
3080 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)
3081 ata_get_native_max(device, retry_count, timeout, ccb,
3083 ataama_print(ident_buf, nativesize, 1);
3090 if (!(ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)) {
3091 warnx("Accessible Max Address is not supported by this device");
3098 case ATA_AMA_ACTION_SET_MAX:
3099 error = ata_get_native_max(device, retry_count, timeout, ccb,
3102 error = ataama_set(device, retry_count, timeout,
3106 /* redo identify to get new values */
3107 error = ata_do_identify(device,
3108 retry_count, timeout, ccb,
3110 ataama_print(ident_buf, nativesize, 1);
3112 /* Hint CAM to reprobe the device. */
3118 case ATA_AMA_ACTION_FREEZE_LOCK:
3119 error = ataama_freeze(device, retry_count, timeout,
3121 if (error == 0 && quiet == 0)
3122 printf("Accessible Max Address has been frozen\n");
3126 errx(1, "Option currently not supported");
3136 atasecurity(struct cam_device *device, int retry_count, int timeout,
3137 int argc, char **argv, char *combinedopt)
3140 struct ata_params *ident_buf;
3141 int error, confirm, quiet, c, action, actions, setpwd;
3142 int security_enabled, erase_timeout, pwdsize;
3143 struct ata_security_password pwd;
3151 memset(&pwd, 0, sizeof(pwd));
3153 /* default action is to print security information */
3154 action = ATA_SECURITY_ACTION_PRINT;
3156 /* user is master by default as its safer that way */
3157 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3158 pwdsize = sizeof(pwd.password);
3160 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3163 action = ATA_SECURITY_ACTION_FREEZE;
3168 if (strcasecmp(optarg, "user") == 0) {
3169 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
3170 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
3171 } else if (strcasecmp(optarg, "master") == 0) {
3172 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3173 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
3175 warnx("-U argument '%s' is invalid (must be "
3176 "'user' or 'master')", optarg);
3182 if (strcasecmp(optarg, "high") == 0) {
3183 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3184 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3185 } else if (strcasecmp(optarg, "maximum") == 0) {
3186 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3187 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3189 warnx("-l argument '%s' is unknown (must be "
3190 "'high' or 'maximum')", optarg);
3196 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3198 action = ATA_SECURITY_ACTION_UNLOCK;
3203 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3205 action = ATA_SECURITY_ACTION_DISABLE;
3210 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3212 action = ATA_SECURITY_ACTION_ERASE;
3217 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3219 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3220 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3225 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3228 if (action == ATA_SECURITY_ACTION_PRINT)
3229 action = ATA_SECURITY_ACTION_SET_PASSWORD;
3231 * Don't increment action as this can be combined
3232 * with other actions.
3245 erase_timeout = atoi(optarg) * 1000;
3251 warnx("too many security actions specified");
3255 if ((ccb = cam_getccb(device)) == NULL) {
3256 warnx("couldn't allocate CCB");
3260 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3267 printf("%s%d: ", device->device_name, device->dev_unit_num);
3268 ata_print_ident(ident_buf);
3269 camxferrate(device);
3272 if (action == ATA_SECURITY_ACTION_PRINT) {
3273 atasecurity_print(ident_buf);
3279 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3280 warnx("Security not supported");
3286 /* default timeout 15 seconds the same as linux hdparm */
3287 timeout = timeout ? timeout : 15 * 1000;
3289 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3291 /* first set the password if requested */
3293 /* confirm we can erase before setting the password if erasing */
3295 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3296 action == ATA_SECURITY_ACTION_ERASE) &&
3297 atasecurity_erase_confirm(device, ident_buf) == 0) {
3303 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3304 pwd.revision = ident_buf->master_passwd_revision;
3305 if (pwd.revision != 0 && pwd.revision != 0xfff &&
3306 --pwd.revision == 0) {
3307 pwd.revision = 0xfffe;
3310 error = atasecurity_set_password(device, ccb, retry_count,
3311 timeout, &pwd, quiet);
3317 security_enabled = 1;
3321 case ATA_SECURITY_ACTION_FREEZE:
3322 error = atasecurity_freeze(device, ccb, retry_count,
3326 case ATA_SECURITY_ACTION_UNLOCK:
3327 if (security_enabled) {
3328 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3329 error = atasecurity_unlock(device, ccb,
3330 retry_count, timeout, &pwd, quiet);
3332 warnx("Can't unlock, drive is not locked");
3336 warnx("Can't unlock, security is disabled");
3341 case ATA_SECURITY_ACTION_DISABLE:
3342 if (security_enabled) {
3343 /* First unlock the drive if its locked */
3344 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3345 error = atasecurity_unlock(device, ccb,
3353 error = atasecurity_disable(device,
3361 warnx("Can't disable security (already disabled)");
3366 case ATA_SECURITY_ACTION_ERASE:
3367 if (security_enabled) {
3368 if (erase_timeout == 0) {
3369 erase_timeout = atasecurity_erase_timeout_msecs(
3370 ident_buf->erase_time);
3373 error = atasecurity_erase(device, ccb, retry_count,
3374 timeout, erase_timeout, &pwd, quiet);
3376 warnx("Can't secure erase (security is disabled)");
3381 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3382 if (security_enabled) {
3383 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3384 if (erase_timeout == 0) {
3386 atasecurity_erase_timeout_msecs(
3387 ident_buf->enhanced_erase_time);
3390 error = atasecurity_erase(device, ccb,
3391 retry_count, timeout,
3392 erase_timeout, &pwd,
3395 warnx("Enhanced erase is not supported");
3399 warnx("Can't secure erase (enhanced), "
3400 "(security is disabled)");
3411 #endif /* MINIMALISTIC */
3414 * Convert periph name into a bus, target and lun.
3416 * Returns the number of parsed components, or 0.
3419 parse_btl_name(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3420 cam_argmask *arglst)
3425 bzero(&ccb, sizeof(ccb));
3426 ccb.ccb_h.func_code = XPT_GDEVLIST;
3427 if (cam_get_device(tstr, ccb.cgdl.periph_name,
3428 sizeof(ccb.cgdl.periph_name), &ccb.cgdl.unit_number) == -1) {
3429 warnx("%s", cam_errbuf);
3434 * Attempt to get the passthrough device. This ioctl will
3435 * fail if the device name is null, if the device doesn't
3436 * exist, or if the passthrough driver isn't in the kernel.
3438 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3439 warn("Unable to open %s", XPT_DEVICE);
3442 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3443 warn("Unable to find bus:target:lun for device %s%d",
3444 ccb.cgdl.periph_name, ccb.cgdl.unit_number);
3449 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3450 const struct cam_status_entry *entry;
3452 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3453 warnx("Unable to find bus:target_lun for device %s%d, "
3454 "CAM status: %s (%#x)",
3455 ccb.cgdl.periph_name, ccb.cgdl.unit_number,
3456 entry ? entry->status_text : "Unknown",
3462 * The kernel fills in the bus/target/lun. We don't
3463 * need the passthrough device name and unit number since
3464 * we aren't going to open it.
3466 *bus = ccb.ccb_h.path_id;
3467 *target = ccb.ccb_h.target_id;
3468 *lun = ccb.ccb_h.target_lun;
3469 *arglst |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3474 * Parse out a bus, or a bus, target and lun in the following
3480 * Returns the number of parsed components, or 0.
3483 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3484 cam_argmask *arglst)
3489 *bus = CAM_BUS_WILDCARD;
3490 *target = CAM_TARGET_WILDCARD;
3491 *lun = CAM_LUN_WILDCARD;
3493 while (isspace(*tstr) && (*tstr != '\0'))
3496 if (strncasecmp(tstr, "all", strlen("all")) == 0) {
3497 arglist |= CAM_ARG_BUS;
3501 if (!isdigit(*tstr))
3502 return (parse_btl_name(tstr, bus, target, lun, arglst));
3504 tmpstr = strsep(&tstr, ":");
3505 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3506 *bus = strtol(tmpstr, &end, 0);
3509 *arglst |= CAM_ARG_BUS;
3511 tmpstr = strsep(&tstr, ":");
3512 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3513 *target = strtol(tmpstr, &end, 0);
3516 *arglst |= CAM_ARG_TARGET;
3518 tmpstr = strsep(&tstr, ":");
3519 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3520 *lun = strtoll(tmpstr, &end, 0);
3523 *arglst |= CAM_ARG_LUN;
3533 dorescan_or_reset(int argc, char **argv, int rescan)
3535 static const char must[] =
3536 "you must specify \"all\", a bus, a bus:target:lun or periph to %s";
3538 path_id_t bus = CAM_BUS_WILDCARD;
3539 target_id_t target = CAM_TARGET_WILDCARD;
3540 lun_id_t lun = CAM_LUN_WILDCARD;
3544 warnx(must, rescan? "rescan" : "reset");
3548 tstr = argv[optind];
3549 while (isspace(*tstr) && (*tstr != '\0'))
3551 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3552 arglist |= CAM_ARG_BUS;
3554 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3555 if (rv != 1 && rv != 3) {
3556 warnx(must, rescan ? "rescan" : "reset");
3561 if (arglist & CAM_ARG_LUN)
3562 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3564 error = rescan_or_reset_bus(bus, rescan);
3570 rescan_or_reset_bus(path_id_t bus, int rescan)
3572 union ccb *ccb = NULL, *matchccb = NULL;
3573 int fd = -1, retval;
3578 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3579 warnx("error opening transport layer device %s", XPT_DEVICE);
3580 warn("%s", XPT_DEVICE);
3584 ccb = malloc(sizeof(*ccb));
3586 warn("failed to allocate CCB");
3590 bzero(ccb, sizeof(*ccb));
3592 if (bus != CAM_BUS_WILDCARD) {
3593 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3594 ccb->ccb_h.path_id = bus;
3595 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3596 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3597 ccb->crcn.flags = CAM_FLAG_NONE;
3599 /* run this at a low priority */
3600 ccb->ccb_h.pinfo.priority = 5;
3602 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3603 warn("CAMIOCOMMAND ioctl failed");
3608 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3609 fprintf(stdout, "%s of bus %d was successful\n",
3610 rescan ? "Re-scan" : "Reset", bus);
3612 fprintf(stdout, "%s of bus %d returned error %#x\n",
3613 rescan ? "Re-scan" : "Reset", bus,
3614 ccb->ccb_h.status & CAM_STATUS_MASK);
3623 * The right way to handle this is to modify the xpt so that it can
3624 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3625 * that isn't implemented, so instead we enumerate the buses and
3626 * send the rescan or reset to those buses in the case where the
3627 * given bus is -1 (wildcard). We don't send a rescan or reset
3628 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3629 * no-op, sending a rescan to the xpt bus would result in a status of
3632 matchccb = malloc(sizeof(*matchccb));
3633 if (matchccb == NULL) {
3634 warn("failed to allocate CCB");
3638 bzero(matchccb, sizeof(*matchccb));
3639 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3640 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3641 bufsize = sizeof(struct dev_match_result) * 20;
3642 matchccb->cdm.match_buf_len = bufsize;
3643 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3644 if (matchccb->cdm.matches == NULL) {
3645 warnx("can't malloc memory for matches");
3649 matchccb->cdm.num_matches = 0;
3651 matchccb->cdm.num_patterns = 1;
3652 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3654 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3655 matchccb->cdm.pattern_buf_len);
3656 if (matchccb->cdm.patterns == NULL) {
3657 warnx("can't malloc memory for patterns");
3661 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3662 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3667 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3668 warn("CAMIOCOMMAND ioctl failed");
3673 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3674 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3675 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3676 warnx("got CAM error %#x, CDM error %d\n",
3677 matchccb->ccb_h.status, matchccb->cdm.status);
3682 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3683 struct bus_match_result *bus_result;
3685 /* This shouldn't happen. */
3686 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3689 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3692 * We don't want to rescan or reset the xpt bus.
3695 if (bus_result->path_id == CAM_XPT_PATH_ID)
3698 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3700 ccb->ccb_h.path_id = bus_result->path_id;
3701 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3702 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3703 ccb->crcn.flags = CAM_FLAG_NONE;
3705 /* run this at a low priority */
3706 ccb->ccb_h.pinfo.priority = 5;
3708 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3709 warn("CAMIOCOMMAND ioctl failed");
3714 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3715 fprintf(stdout, "%s of bus %d was successful\n",
3716 rescan? "Re-scan" : "Reset",
3717 bus_result->path_id);
3720 * Don't bail out just yet, maybe the other
3721 * rescan or reset commands will complete
3724 fprintf(stderr, "%s of bus %d returned error "
3725 "%#x\n", rescan? "Re-scan" : "Reset",
3726 bus_result->path_id,
3727 ccb->ccb_h.status & CAM_STATUS_MASK);
3731 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3732 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3739 if (matchccb != NULL) {
3740 free(matchccb->cdm.patterns);
3741 free(matchccb->cdm.matches);
3750 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3753 struct cam_device *device;
3758 if (bus == CAM_BUS_WILDCARD) {
3759 warnx("invalid bus number %d", bus);
3763 if (target == CAM_TARGET_WILDCARD) {
3764 warnx("invalid target number %d", target);
3768 if (lun == CAM_LUN_WILDCARD) {
3769 warnx("invalid lun number %jx", (uintmax_t)lun);
3775 bzero(&ccb, sizeof(union ccb));
3778 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3779 warnx("error opening transport layer device %s\n",
3781 warn("%s", XPT_DEVICE);
3785 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3786 if (device == NULL) {
3787 warnx("%s", cam_errbuf);
3792 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3793 ccb.ccb_h.path_id = bus;
3794 ccb.ccb_h.target_id = target;
3795 ccb.ccb_h.target_lun = lun;
3796 ccb.ccb_h.timeout = 5000;
3797 ccb.crcn.flags = CAM_FLAG_NONE;
3799 /* run this at a low priority */
3800 ccb.ccb_h.pinfo.priority = 5;
3803 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3804 warn("CAMIOCOMMAND ioctl failed");
3809 if (cam_send_ccb(device, &ccb) < 0) {
3810 warn("error sending XPT_RESET_DEV CCB");
3811 cam_close_device(device);
3819 cam_close_device(device);
3822 * An error code of CAM_BDR_SENT is normal for a BDR request.
3824 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3826 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3827 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3828 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3831 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3832 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3833 ccb.ccb_h.status & CAM_STATUS_MASK);
3838 #ifndef MINIMALISTIC
3840 static struct scsi_nv defect_list_type_map[] = {
3841 { "block", SRDD10_BLOCK_FORMAT },
3842 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3843 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3844 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3845 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3846 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3850 readdefects(struct cam_device *device, int argc, char **argv,
3851 char *combinedopt, int task_attr, int retry_count, int timeout)
3853 union ccb *ccb = NULL;
3854 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3855 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3856 size_t hdr_size = 0, entry_size = 0;
3859 u_int8_t *defect_list = NULL;
3860 u_int8_t list_format = 0;
3861 int list_type_set = 0;
3862 u_int32_t dlist_length = 0;
3863 u_int32_t returned_length = 0, valid_len = 0;
3864 u_int32_t num_returned = 0, num_valid = 0;
3865 u_int32_t max_possible_size = 0, hdr_max = 0;
3866 u_int32_t starting_offset = 0;
3867 u_int8_t returned_format, returned_type;
3869 int summary = 0, quiet = 0;
3871 int lists_specified = 0;
3872 int get_length = 1, first_pass = 1;
3875 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3879 scsi_nv_status status;
3882 status = scsi_get_nv(defect_list_type_map,
3883 sizeof(defect_list_type_map) /
3884 sizeof(defect_list_type_map[0]), optarg,
3885 &entry_num, SCSI_NV_FLAG_IG_CASE);
3887 if (status == SCSI_NV_FOUND) {
3888 list_format = defect_list_type_map[
3892 warnx("%s: %s %s option %s", __func__,
3893 (status == SCSI_NV_AMBIGUOUS) ?
3894 "ambiguous" : "invalid", "defect list type",
3897 goto defect_bailout;
3902 arglist |= CAM_ARG_GLIST;
3905 arglist |= CAM_ARG_PLIST;
3916 starting_offset = strtoul(optarg, &endptr, 0);
3917 if (*endptr != '\0') {
3919 warnx("invalid starting offset %s", optarg);
3920 goto defect_bailout;
3932 if (list_type_set == 0) {
3934 warnx("no defect list format specified");
3935 goto defect_bailout;
3938 if (arglist & CAM_ARG_PLIST) {
3939 list_format |= SRDD10_PLIST;
3943 if (arglist & CAM_ARG_GLIST) {
3944 list_format |= SRDD10_GLIST;
3949 * This implies a summary, and was the previous behavior.
3951 if (lists_specified == 0)
3954 ccb = cam_getccb(device);
3959 * We start off asking for just the header to determine how much
3960 * defect data is available. Some Hitachi drives return an error
3961 * if you ask for more data than the drive has. Once we know the
3962 * length, we retry the command with the returned length.
3964 if (use_12byte == 0)
3965 dlist_length = sizeof(*hdr10);
3967 dlist_length = sizeof(*hdr12);
3970 if (defect_list != NULL) {
3974 defect_list = malloc(dlist_length);
3975 if (defect_list == NULL) {
3976 warnx("can't malloc memory for defect list");
3978 goto defect_bailout;
3982 bzero(defect_list, dlist_length);
3985 * cam_getccb() zeros the CCB header only. So we need to zero the
3986 * payload portion of the ccb.
3988 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3990 scsi_read_defects(&ccb->csio,
3991 /*retries*/ retry_count,
3993 /*tag_action*/ task_attr,
3994 /*list_format*/ list_format,
3995 /*addr_desc_index*/ starting_offset,
3996 /*data_ptr*/ defect_list,
3997 /*dxfer_len*/ dlist_length,
3998 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3999 /*sense_len*/ SSD_FULL_SIZE,
4000 /*timeout*/ timeout ? timeout : 5000);
4002 /* Disable freezing the device queue */
4003 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4005 if (cam_send_ccb(device, ccb) < 0) {
4006 warn("error sending READ DEFECT DATA command");
4008 goto defect_bailout;
4011 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
4013 if (use_12byte == 0) {
4014 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
4015 hdr_size = sizeof(*hdr10);
4016 hdr_max = SRDDH10_MAX_LENGTH;
4018 if (valid_len >= hdr_size) {
4019 returned_length = scsi_2btoul(hdr10->length);
4020 returned_format = hdr10->format;
4022 returned_length = 0;
4023 returned_format = 0;
4026 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
4027 hdr_size = sizeof(*hdr12);
4028 hdr_max = SRDDH12_MAX_LENGTH;
4030 if (valid_len >= hdr_size) {
4031 returned_length = scsi_4btoul(hdr12->length);
4032 returned_format = hdr12->format;
4034 returned_length = 0;
4035 returned_format = 0;
4039 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
4040 switch (returned_type) {
4041 case SRDD10_BLOCK_FORMAT:
4042 entry_size = sizeof(struct scsi_defect_desc_block);
4044 case SRDD10_LONG_BLOCK_FORMAT:
4045 entry_size = sizeof(struct scsi_defect_desc_long_block);
4047 case SRDD10_EXT_PHYS_FORMAT:
4048 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4049 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
4051 case SRDD10_EXT_BFI_FORMAT:
4052 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4053 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
4056 warnx("Unknown defect format 0x%x\n", returned_type);
4058 goto defect_bailout;
4062 max_possible_size = (hdr_max / entry_size) * entry_size;
4063 num_returned = returned_length / entry_size;
4064 num_valid = min(returned_length, valid_len - hdr_size);
4065 num_valid /= entry_size;
4067 if (get_length != 0) {
4070 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
4071 CAM_SCSI_STATUS_ERROR) {
4072 struct scsi_sense_data *sense;
4073 int error_code, sense_key, asc, ascq;
4075 sense = &ccb->csio.sense_data;
4076 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4077 ccb->csio.sense_resid, &error_code, &sense_key,
4078 &asc, &ascq, /*show_errors*/ 1);
4081 * If the drive is reporting that it just doesn't
4082 * support the defect list format, go ahead and use
4083 * the length it reported. Otherwise, the length
4084 * may not be valid, so use the maximum.
4086 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4087 && (asc == 0x1c) && (ascq == 0x00)
4088 && (returned_length > 0)) {
4089 if ((use_12byte == 0)
4090 && (returned_length >= max_possible_size)) {
4095 dlist_length = returned_length + hdr_size;
4096 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4097 && (asc == 0x1f) && (ascq == 0x00)
4098 && (returned_length > 0)) {
4099 /* Partial defect list transfer */
4101 * Hitachi drives return this error
4102 * along with a partial defect list if they
4103 * have more defects than the 10 byte
4104 * command can support. Retry with the 12
4107 if (use_12byte == 0) {
4112 dlist_length = returned_length + hdr_size;
4113 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
4114 && (asc == 0x24) && (ascq == 0x00)) {
4115 /* Invalid field in CDB */
4117 * SBC-3 says that if the drive has more
4118 * defects than can be reported with the
4119 * 10 byte command, it should return this
4120 * error and no data. Retry with the 12
4123 if (use_12byte == 0) {
4128 dlist_length = returned_length + hdr_size;
4131 * If we got a SCSI error and no valid length,
4132 * just use the 10 byte maximum. The 12
4133 * byte maximum is too large.
4135 if (returned_length == 0)
4136 dlist_length = SRDD10_MAX_LENGTH;
4138 if ((use_12byte == 0)
4139 && (returned_length >=
4140 max_possible_size)) {
4145 dlist_length = returned_length +
4149 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4152 warnx("Error reading defect header");
4153 if (arglist & CAM_ARG_VERBOSE)
4154 cam_error_print(device, ccb, CAM_ESF_ALL,
4155 CAM_EPF_ALL, stderr);
4156 goto defect_bailout;
4158 if ((use_12byte == 0)
4159 && (returned_length >= max_possible_size)) {
4164 dlist_length = returned_length + hdr_size;
4167 fprintf(stdout, "%u", num_returned);
4169 fprintf(stdout, " defect%s",
4170 (num_returned != 1) ? "s" : "");
4172 fprintf(stdout, "\n");
4174 goto defect_bailout;
4178 * We always limit the list length to the 10-byte maximum
4179 * length (0xffff). The reason is that some controllers
4180 * can't handle larger I/Os, and we can transfer the entire
4181 * 10 byte list in one shot. For drives that support the 12
4182 * byte read defects command, we'll step through the list
4183 * by specifying a starting offset. For drives that don't
4184 * support the 12 byte command's starting offset, we'll
4185 * just display the first 64K.
4187 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4193 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4194 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4195 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4196 struct scsi_sense_data *sense;
4197 int error_code, sense_key, asc, ascq;
4199 sense = &ccb->csio.sense_data;
4200 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4201 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4202 &ascq, /*show_errors*/ 1);
4205 * According to the SCSI spec, if the disk doesn't support
4206 * the requested format, it will generally return a sense
4207 * key of RECOVERED ERROR, and an additional sense code
4208 * of "DEFECT LIST NOT FOUND". HGST drives also return
4209 * Primary/Grown defect list not found errors. So just
4210 * check for an ASC of 0x1c.
4212 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4214 const char *format_str;
4216 format_str = scsi_nv_to_str(defect_list_type_map,
4217 sizeof(defect_list_type_map) /
4218 sizeof(defect_list_type_map[0]),
4219 list_format & SRDD10_DLIST_FORMAT_MASK);
4220 warnx("requested defect format %s not available",
4221 format_str ? format_str : "unknown");
4223 format_str = scsi_nv_to_str(defect_list_type_map,
4224 sizeof(defect_list_type_map) /
4225 sizeof(defect_list_type_map[0]), returned_type);
4226 if (format_str != NULL) {
4227 warnx("Device returned %s format",
4231 warnx("Device returned unknown defect"
4232 " data format %#x", returned_type);
4233 goto defect_bailout;
4237 warnx("Error returned from read defect data command");
4238 if (arglist & CAM_ARG_VERBOSE)
4239 cam_error_print(device, ccb, CAM_ESF_ALL,
4240 CAM_EPF_ALL, stderr);
4241 goto defect_bailout;
4243 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4245 warnx("Error returned from read defect data command");
4246 if (arglist & CAM_ARG_VERBOSE)
4247 cam_error_print(device, ccb, CAM_ESF_ALL,
4248 CAM_EPF_ALL, stderr);
4249 goto defect_bailout;
4252 if (first_pass != 0) {
4253 fprintf(stderr, "Got %d defect", num_returned);
4255 if ((lists_specified == 0) || (num_returned == 0)) {
4256 fprintf(stderr, "s.\n");
4257 goto defect_bailout;
4258 } else if (num_returned == 1)
4259 fprintf(stderr, ":\n");
4261 fprintf(stderr, "s:\n");
4267 * XXX KDM I should probably clean up the printout format for the
4270 switch (returned_type) {
4271 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4272 case SRDD10_EXT_PHYS_FORMAT:
4274 struct scsi_defect_desc_phys_sector *dlist;
4276 dlist = (struct scsi_defect_desc_phys_sector *)
4277 (defect_list + hdr_size);
4279 for (i = 0; i < num_valid; i++) {
4282 sector = scsi_4btoul(dlist[i].sector);
4283 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4284 mads = (sector & SDD_EXT_PHYS_MADS) ?
4286 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4288 if (hex_format == 0)
4289 fprintf(stdout, "%d:%d:%d%s",
4290 scsi_3btoul(dlist[i].cylinder),
4292 scsi_4btoul(dlist[i].sector),
4293 mads ? " - " : "\n");
4295 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4296 scsi_3btoul(dlist[i].cylinder),
4298 scsi_4btoul(dlist[i].sector),
4299 mads ? " - " : "\n");
4302 if (num_valid < num_returned) {
4303 starting_offset += num_valid;
4308 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4309 case SRDD10_EXT_BFI_FORMAT:
4311 struct scsi_defect_desc_bytes_from_index *dlist;
4313 dlist = (struct scsi_defect_desc_bytes_from_index *)
4314 (defect_list + hdr_size);
4316 for (i = 0; i < num_valid; i++) {
4319 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4320 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4321 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4322 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4324 if (hex_format == 0)
4325 fprintf(stdout, "%d:%d:%d%s",
4326 scsi_3btoul(dlist[i].cylinder),
4328 scsi_4btoul(dlist[i].bytes_from_index),
4329 mads ? " - " : "\n");
4331 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4332 scsi_3btoul(dlist[i].cylinder),
4334 scsi_4btoul(dlist[i].bytes_from_index),
4335 mads ? " - " : "\n");
4339 if (num_valid < num_returned) {
4340 starting_offset += num_valid;
4345 case SRDDH10_BLOCK_FORMAT:
4347 struct scsi_defect_desc_block *dlist;
4349 dlist = (struct scsi_defect_desc_block *)
4350 (defect_list + hdr_size);
4352 for (i = 0; i < num_valid; i++) {
4353 if (hex_format == 0)
4354 fprintf(stdout, "%u\n",
4355 scsi_4btoul(dlist[i].address));
4357 fprintf(stdout, "0x%x\n",
4358 scsi_4btoul(dlist[i].address));
4361 if (num_valid < num_returned) {
4362 starting_offset += num_valid;
4368 case SRDD10_LONG_BLOCK_FORMAT:
4370 struct scsi_defect_desc_long_block *dlist;
4372 dlist = (struct scsi_defect_desc_long_block *)
4373 (defect_list + hdr_size);
4375 for (i = 0; i < num_valid; i++) {
4376 if (hex_format == 0)
4377 fprintf(stdout, "%ju\n",
4378 (uintmax_t)scsi_8btou64(
4381 fprintf(stdout, "0x%jx\n",
4382 (uintmax_t)scsi_8btou64(
4386 if (num_valid < num_returned) {
4387 starting_offset += num_valid;
4393 fprintf(stderr, "Unknown defect format 0x%x\n",
4400 if (defect_list != NULL)
4408 #endif /* MINIMALISTIC */
4412 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4416 ccb = cam_getccb(device);
4422 #ifndef MINIMALISTIC
4424 mode_sense(struct cam_device *device, int *cdb_len, int dbd, int llbaa, int pc,
4425 int page, int subpage, int task_attr, int retry_count, int timeout,
4426 u_int8_t *data, int datalen)
4429 int error_code, sense_key, asc, ascq;
4431 ccb = cam_getccb(device);
4433 errx(1, "mode_sense: couldn't allocate CCB");
4437 * MODE SENSE(6) can't handle more then 255 bytes. If there are more,
4438 * device must return error, so we should not get trucated data.
4440 if (*cdb_len == 6 && datalen > 255)
4443 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4445 scsi_mode_sense_subpage(&ccb->csio,
4446 /* retries */ retry_count,
4448 /* tag_action */ task_attr,
4452 /* subpage */ subpage,
4453 /* param_buf */ data,
4454 /* param_len */ datalen,
4455 /* minimum_cmd_size */ *cdb_len,
4456 /* sense_len */ SSD_FULL_SIZE,
4457 /* timeout */ timeout ? timeout : 5000);
4458 if (llbaa && ccb->csio.cdb_len == 10) {
4459 struct scsi_mode_sense_10 *cdb =
4460 (struct scsi_mode_sense_10 *)ccb->csio.cdb_io.cdb_bytes;
4461 cdb->byte2 |= SMS10_LLBAA;
4464 /* Record what CDB size the above function really set. */
4465 *cdb_len = ccb->csio.cdb_len;
4467 if (arglist & CAM_ARG_ERR_RECOVER)
4468 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4470 /* Disable freezing the device queue */
4471 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4473 if (cam_send_ccb(device, ccb) < 0)
4474 err(1, "error sending mode sense command");
4476 /* In case of ILLEGEL REQUEST try to fall back to 6-byte command. */
4477 if (*cdb_len != 6 &&
4478 ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID ||
4479 (scsi_extract_sense_ccb(ccb, &error_code, &sense_key, &asc, &ascq)
4480 && sense_key == SSD_KEY_ILLEGAL_REQUEST))) {
4485 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4486 if (arglist & CAM_ARG_VERBOSE) {
4487 cam_error_print(device, ccb, CAM_ESF_ALL,
4488 CAM_EPF_ALL, stderr);
4491 cam_close_device(device);
4492 errx(1, "mode sense command returned error");
4499 mode_select(struct cam_device *device, int cdb_len, int save_pages,
4500 int task_attr, int retry_count, int timeout, u_int8_t *data, int datalen)
4505 ccb = cam_getccb(device);
4508 errx(1, "mode_select: couldn't allocate CCB");
4510 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4512 scsi_mode_select_len(&ccb->csio,
4513 /* retries */ retry_count,
4515 /* tag_action */ task_attr,
4516 /* scsi_page_fmt */ 1,
4517 /* save_pages */ save_pages,
4518 /* param_buf */ data,
4519 /* param_len */ datalen,
4520 /* minimum_cmd_size */ cdb_len,
4521 /* sense_len */ SSD_FULL_SIZE,
4522 /* timeout */ timeout ? timeout : 5000);
4524 if (arglist & CAM_ARG_ERR_RECOVER)
4525 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4527 /* Disable freezing the device queue */
4528 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4530 if (((retval = cam_send_ccb(device, ccb)) < 0)
4531 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4532 if (arglist & CAM_ARG_VERBOSE) {
4533 cam_error_print(device, ccb, CAM_ESF_ALL,
4534 CAM_EPF_ALL, stderr);
4537 cam_close_device(device);
4540 err(1, "error sending mode select command");
4542 errx(1, "error sending mode select command");
4550 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4551 int task_attr, int retry_count, int timeout)
4554 int c, page = -1, subpage = 0, pc = 0, llbaa = 0;
4555 int binary = 0, cdb_len = 10, dbd = 0, desc = 0, edit = 0, list = 0;
4557 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4575 str_subpage = optarg;
4576 strsep(&str_subpage, ",");
4577 page = strtol(optarg, NULL, 0);
4579 subpage = strtol(str_subpage, NULL, 0);
4580 if (page < 0 || page > 0x3f)
4581 errx(1, "invalid mode page %d", page);
4582 if (subpage < 0 || subpage > 0xff)
4583 errx(1, "invalid mode subpage %d", subpage);
4592 pc = strtol(optarg, NULL, 0);
4593 if ((pc < 0) || (pc > 3))
4594 errx(1, "invalid page control field %d", pc);
4601 if (desc && page == -1)
4602 page = SMS_ALL_PAGES_PAGE;
4604 if (page == -1 && list == 0)
4605 errx(1, "you must specify a mode page!");
4608 errx(1, "-d and -D are incompatible!");
4610 if (llbaa && cdb_len != 10)
4611 errx(1, "LLBAA bit is not present in MODE SENSE(6)!");
4614 mode_list(device, cdb_len, dbd, pc, list > 1, task_attr,
4615 retry_count, timeout);
4617 mode_edit(device, cdb_len, desc, dbd, llbaa, pc, page, subpage,
4618 edit, binary, task_attr, retry_count, timeout);
4623 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4624 int task_attr, int retry_count, int timeout)
4627 u_int32_t flags = CAM_DIR_NONE;
4628 u_int8_t *data_ptr = NULL;
4630 u_int8_t atacmd[12];
4631 struct get_hook hook;
4632 int c, data_bytes = 0, valid_bytes;
4638 char *datastr = NULL, *tstr, *resstr = NULL;
4640 int fd_data = 0, fd_res = 0;
4643 ccb = cam_getccb(device);
4646 warnx("scsicmd: error allocating ccb");
4650 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4652 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4656 while (isspace(*tstr) && (*tstr != '\0'))
4658 hook.argc = argc - optind;
4659 hook.argv = argv + optind;
4661 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4664 * Increment optind by the number of arguments the
4665 * encoding routine processed. After each call to
4666 * getopt(3), optind points to the argument that
4667 * getopt should process _next_. In this case,
4668 * that means it points to the first command string
4669 * argument, if there is one. Once we increment
4670 * this, it should point to either the next command
4671 * line argument, or it should be past the end of
4678 while (isspace(*tstr) && (*tstr != '\0'))
4680 hook.argc = argc - optind;
4681 hook.argv = argv + optind;
4683 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4686 * Increment optind by the number of arguments the
4687 * encoding routine processed. After each call to
4688 * getopt(3), optind points to the argument that
4689 * getopt should process _next_. In this case,
4690 * that means it points to the first command string
4691 * argument, if there is one. Once we increment
4692 * this, it should point to either the next command
4693 * line argument, or it should be past the end of
4705 if (arglist & CAM_ARG_CMD_OUT) {
4706 warnx("command must either be "
4707 "read or write, not both");
4709 goto scsicmd_bailout;
4711 arglist |= CAM_ARG_CMD_IN;
4713 data_bytes = strtol(optarg, NULL, 0);
4714 if (data_bytes <= 0) {
4715 warnx("invalid number of input bytes %d",
4718 goto scsicmd_bailout;
4720 hook.argc = argc - optind;
4721 hook.argv = argv + optind;
4724 datastr = cget(&hook, NULL);
4726 * If the user supplied "-" instead of a format, he
4727 * wants the data to be written to stdout.
4729 if ((datastr != NULL)
4730 && (datastr[0] == '-'))
4733 data_ptr = (u_int8_t *)malloc(data_bytes);
4734 if (data_ptr == NULL) {
4735 warnx("can't malloc memory for data_ptr");
4737 goto scsicmd_bailout;
4741 if (arglist & CAM_ARG_CMD_IN) {
4742 warnx("command must either be "
4743 "read or write, not both");
4745 goto scsicmd_bailout;
4747 arglist |= CAM_ARG_CMD_OUT;
4748 flags = CAM_DIR_OUT;
4749 data_bytes = strtol(optarg, NULL, 0);
4750 if (data_bytes <= 0) {
4751 warnx("invalid number of output bytes %d",
4754 goto scsicmd_bailout;
4756 hook.argc = argc - optind;
4757 hook.argv = argv + optind;
4759 datastr = cget(&hook, NULL);
4760 data_ptr = (u_int8_t *)malloc(data_bytes);
4761 if (data_ptr == NULL) {
4762 warnx("can't malloc memory for data_ptr");
4764 goto scsicmd_bailout;
4766 bzero(data_ptr, data_bytes);
4768 * If the user supplied "-" instead of a format, he
4769 * wants the data to be read from stdin.
4771 if ((datastr != NULL)
4772 && (datastr[0] == '-'))
4775 buff_encode_visit(data_ptr, data_bytes, datastr,
4781 hook.argc = argc - optind;
4782 hook.argv = argv + optind;
4784 resstr = cget(&hook, NULL);
4785 if ((resstr != NULL) && (resstr[0] == '-'))
4795 * If fd_data is set, and we're writing to the device, we need to
4796 * read the data the user wants written from stdin.
4798 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4800 int amt_to_read = data_bytes;
4801 u_int8_t *buf_ptr = data_ptr;
4803 for (amt_read = 0; amt_to_read > 0;
4804 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4805 if (amt_read == -1) {
4806 warn("error reading data from stdin");
4808 goto scsicmd_bailout;
4810 amt_to_read -= amt_read;
4811 buf_ptr += amt_read;
4815 if (arglist & CAM_ARG_ERR_RECOVER)
4816 flags |= CAM_PASS_ERR_RECOVER;
4818 /* Disable freezing the device queue */
4819 flags |= CAM_DEV_QFRZDIS;
4823 * This is taken from the SCSI-3 draft spec.
4824 * (T10/1157D revision 0.3)
4825 * The top 3 bits of an opcode are the group code.
4826 * The next 5 bits are the command code.
4827 * Group 0: six byte commands
4828 * Group 1: ten byte commands
4829 * Group 2: ten byte commands
4831 * Group 4: sixteen byte commands
4832 * Group 5: twelve byte commands
4833 * Group 6: vendor specific
4834 * Group 7: vendor specific
4836 switch((cdb[0] >> 5) & 0x7) {
4847 /* computed by buff_encode_visit */
4858 * We should probably use csio_build_visit or something like that
4859 * here, but it's easier to encode arguments as you go. The
4860 * alternative would be skipping the CDB argument and then encoding
4861 * it here, since we've got the data buffer argument by now.
4863 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4865 cam_fill_csio(&ccb->csio,
4866 /*retries*/ retry_count,
4869 /*tag_action*/ task_attr,
4870 /*data_ptr*/ data_ptr,
4871 /*dxfer_len*/ data_bytes,
4872 /*sense_len*/ SSD_FULL_SIZE,
4873 /*cdb_len*/ cdb_len,
4874 /*timeout*/ timeout ? timeout : 5000);
4877 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4879 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4881 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4883 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4885 cam_fill_ataio(&ccb->ataio,
4886 /*retries*/ retry_count,
4890 /*data_ptr*/ data_ptr,
4891 /*dxfer_len*/ data_bytes,
4892 /*timeout*/ timeout ? timeout : 5000);
4895 if (((retval = cam_send_ccb(device, ccb)) < 0)
4896 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4897 const char warnstr[] = "error sending command";
4904 if (arglist & CAM_ARG_VERBOSE) {
4905 cam_error_print(device, ccb, CAM_ESF_ALL,
4906 CAM_EPF_ALL, stderr);
4910 goto scsicmd_bailout;
4913 if (atacmd_len && need_res) {
4915 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4917 fprintf(stdout, "\n");
4920 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4921 ccb->ataio.res.status,
4922 ccb->ataio.res.error,
4923 ccb->ataio.res.lba_low,
4924 ccb->ataio.res.lba_mid,
4925 ccb->ataio.res.lba_high,
4926 ccb->ataio.res.device,
4927 ccb->ataio.res.lba_low_exp,
4928 ccb->ataio.res.lba_mid_exp,
4929 ccb->ataio.res.lba_high_exp,
4930 ccb->ataio.res.sector_count,
4931 ccb->ataio.res.sector_count_exp);
4937 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4939 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4940 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4941 && (arglist & CAM_ARG_CMD_IN)
4942 && (valid_bytes > 0)) {
4944 buff_decode_visit(data_ptr, valid_bytes, datastr,
4946 fprintf(stdout, "\n");
4948 ssize_t amt_written;
4949 int amt_to_write = valid_bytes;
4950 u_int8_t *buf_ptr = data_ptr;
4952 for (amt_written = 0; (amt_to_write > 0) &&
4953 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4954 amt_to_write -= amt_written;
4955 buf_ptr += amt_written;
4957 if (amt_written == -1) {
4958 warn("error writing data to stdout");
4960 goto scsicmd_bailout;
4961 } else if ((amt_written == 0)
4962 && (amt_to_write > 0)) {
4963 warnx("only wrote %u bytes out of %u",
4964 valid_bytes - amt_to_write, valid_bytes);
4971 if ((data_bytes > 0) && (data_ptr != NULL))
4980 camdebug(int argc, char **argv, char *combinedopt)
4983 path_id_t bus = CAM_BUS_WILDCARD;
4984 target_id_t target = CAM_TARGET_WILDCARD;
4985 lun_id_t lun = CAM_LUN_WILDCARD;
4990 bzero(&ccb, sizeof(union ccb));
4992 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4995 arglist |= CAM_ARG_DEBUG_INFO;
4996 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4999 arglist |= CAM_ARG_DEBUG_PERIPH;
5000 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
5003 arglist |= CAM_ARG_DEBUG_SUBTRACE;
5004 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
5007 arglist |= CAM_ARG_DEBUG_TRACE;
5008 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
5011 arglist |= CAM_ARG_DEBUG_XPT;
5012 ccb.cdbg.flags |= CAM_DEBUG_XPT;
5015 arglist |= CAM_ARG_DEBUG_CDB;
5016 ccb.cdbg.flags |= CAM_DEBUG_CDB;
5019 arglist |= CAM_ARG_DEBUG_PROBE;
5020 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
5031 warnx("you must specify \"off\", \"all\" or a bus,");
5032 warnx("bus:target, bus:target:lun or periph");
5037 while (isspace(*tstr) && (*tstr != '\0'))
5040 if (strncmp(tstr, "off", 3) == 0) {
5041 ccb.cdbg.flags = CAM_DEBUG_NONE;
5042 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
5043 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
5044 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
5046 rv = parse_btl(tstr, &bus, &target, &lun, &arglist);
5048 warnx("you must specify \"all\", \"off\", or a bus,");
5049 warnx("bus:target, bus:target:lun or periph to debug");
5054 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
5055 warnx("error opening transport layer device %s", XPT_DEVICE);
5056 warn("%s", XPT_DEVICE);
5060 ccb.ccb_h.func_code = XPT_DEBUG;
5061 ccb.ccb_h.path_id = bus;
5062 ccb.ccb_h.target_id = target;
5063 ccb.ccb_h.target_lun = lun;
5065 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
5066 warn("CAMIOCOMMAND ioctl failed");
5069 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
5070 CAM_FUNC_NOTAVAIL) {
5071 warnx("CAM debugging not available");
5072 warnx("you need to put options CAMDEBUG in"
5073 " your kernel config file!");
5075 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
5077 warnx("XPT_DEBUG CCB failed with status %#x",
5081 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
5083 "Debugging turned off\n");
5086 "Debugging enabled for "
5088 bus, target, (uintmax_t)lun);
5098 tagcontrol(struct cam_device *device, int argc, char **argv,
5108 ccb = cam_getccb(device);
5111 warnx("tagcontrol: error allocating ccb");
5115 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5118 numtags = strtol(optarg, NULL, 0);
5120 warnx("tag count %d is < 0", numtags);
5122 goto tagcontrol_bailout;
5133 cam_path_string(device, pathstr, sizeof(pathstr));
5136 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
5137 ccb->ccb_h.func_code = XPT_REL_SIMQ;
5138 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5139 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5140 ccb->crs.openings = numtags;
5143 if (cam_send_ccb(device, ccb) < 0) {
5144 warn("error sending XPT_REL_SIMQ CCB");
5146 goto tagcontrol_bailout;
5149 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5150 warnx("XPT_REL_SIMQ CCB failed");
5151 cam_error_print(device, ccb, CAM_ESF_ALL,
5152 CAM_EPF_ALL, stderr);
5154 goto tagcontrol_bailout;
5159 fprintf(stdout, "%stagged openings now %d\n",
5160 pathstr, ccb->crs.openings);
5163 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5165 ccb->ccb_h.func_code = XPT_GDEV_STATS;
5167 if (cam_send_ccb(device, ccb) < 0) {
5168 warn("error sending XPT_GDEV_STATS CCB");
5170 goto tagcontrol_bailout;
5173 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5174 warnx("XPT_GDEV_STATS CCB failed");
5175 cam_error_print(device, ccb, CAM_ESF_ALL,
5176 CAM_EPF_ALL, stderr);
5178 goto tagcontrol_bailout;
5181 if (arglist & CAM_ARG_VERBOSE) {
5182 fprintf(stdout, "%s", pathstr);
5183 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5184 fprintf(stdout, "%s", pathstr);
5185 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5186 fprintf(stdout, "%s", pathstr);
5187 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5188 fprintf(stdout, "%s", pathstr);
5189 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5190 fprintf(stdout, "%s", pathstr);
5191 fprintf(stdout, "held %d\n", ccb->cgds.held);
5192 fprintf(stdout, "%s", pathstr);
5193 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5194 fprintf(stdout, "%s", pathstr);
5195 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5198 fprintf(stdout, "%s", pathstr);
5199 fprintf(stdout, "device openings: ");
5201 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5202 ccb->cgds.dev_active);
5212 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5216 cam_path_string(device, pathstr, sizeof(pathstr));
5218 if (cts->transport == XPORT_SPI) {
5219 struct ccb_trans_settings_spi *spi =
5220 &cts->xport_specific.spi;
5222 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5224 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5227 if (spi->sync_offset != 0) {
5230 freq = scsi_calc_syncsrate(spi->sync_period);
5231 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5232 pathstr, freq / 1000, freq % 1000);
5236 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5237 fprintf(stdout, "%soffset: %d\n", pathstr,
5241 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5242 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5243 (0x01 << spi->bus_width) * 8);
5246 if (spi->valid & CTS_SPI_VALID_DISC) {
5247 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5248 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5249 "enabled" : "disabled");
5252 if (cts->transport == XPORT_FC) {
5253 struct ccb_trans_settings_fc *fc =
5254 &cts->xport_specific.fc;
5256 if (fc->valid & CTS_FC_VALID_WWNN)
5257 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5258 (long long) fc->wwnn);
5259 if (fc->valid & CTS_FC_VALID_WWPN)
5260 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5261 (long long) fc->wwpn);
5262 if (fc->valid & CTS_FC_VALID_PORT)
5263 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5264 if (fc->valid & CTS_FC_VALID_SPEED)
5265 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5266 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5268 if (cts->transport == XPORT_SAS) {
5269 struct ccb_trans_settings_sas *sas =
5270 &cts->xport_specific.sas;
5272 if (sas->valid & CTS_SAS_VALID_SPEED)
5273 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5274 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5276 if (cts->transport == XPORT_ATA) {
5277 struct ccb_trans_settings_pata *pata =
5278 &cts->xport_specific.ata;
5280 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5281 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5282 ata_mode2string(pata->mode));
5284 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5285 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5288 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5289 fprintf(stdout, "%sPIO transaction length: %d\n",
5290 pathstr, pata->bytecount);
5293 if (cts->transport == XPORT_SATA) {
5294 struct ccb_trans_settings_sata *sata =
5295 &cts->xport_specific.sata;
5297 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5298 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5301 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5302 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5303 ata_mode2string(sata->mode));
5305 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5306 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5309 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5310 fprintf(stdout, "%sPIO transaction length: %d\n",
5311 pathstr, sata->bytecount);
5313 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5314 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5317 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5318 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5321 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5322 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5326 if (cts->protocol == PROTO_ATA) {
5327 struct ccb_trans_settings_ata *ata=
5328 &cts->proto_specific.ata;
5330 if (ata->valid & CTS_ATA_VALID_TQ) {
5331 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5332 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5333 "enabled" : "disabled");
5336 if (cts->protocol == PROTO_SCSI) {
5337 struct ccb_trans_settings_scsi *scsi=
5338 &cts->proto_specific.scsi;
5340 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5341 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5342 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5343 "enabled" : "disabled");
5347 if (cts->protocol == PROTO_NVME) {
5348 struct ccb_trans_settings_nvme *nvmex =
5349 &cts->xport_specific.nvme;
5351 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5352 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5353 NVME_MAJOR(nvmex->spec),
5354 NVME_MINOR(nvmex->spec));
5356 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5357 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5358 nvmex->lanes, nvmex->max_lanes);
5359 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5360 nvmex->speed, nvmex->max_speed);
5367 * Get a path inquiry CCB for the specified device.
5370 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5375 ccb = cam_getccb(device);
5377 warnx("get_cpi: couldn't allocate CCB");
5380 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5381 ccb->ccb_h.func_code = XPT_PATH_INQ;
5382 if (cam_send_ccb(device, ccb) < 0) {
5383 warn("get_cpi: error sending Path Inquiry CCB");
5385 goto get_cpi_bailout;
5387 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5388 if (arglist & CAM_ARG_VERBOSE)
5389 cam_error_print(device, ccb, CAM_ESF_ALL,
5390 CAM_EPF_ALL, stderr);
5392 goto get_cpi_bailout;
5394 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5402 * Get a get device CCB for the specified device.
5405 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5410 ccb = cam_getccb(device);
5412 warnx("get_cgd: couldn't allocate CCB");
5415 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5416 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5417 if (cam_send_ccb(device, ccb) < 0) {
5418 warn("get_cgd: error sending Get type information CCB");
5420 goto get_cgd_bailout;
5422 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5423 if (arglist & CAM_ARG_VERBOSE)
5424 cam_error_print(device, ccb, CAM_ESF_ALL,
5425 CAM_EPF_ALL, stderr);
5427 goto get_cgd_bailout;
5429 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5437 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5441 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5442 int timeout, int verbosemode)
5444 union ccb *ccb = NULL;
5445 struct scsi_vpd_supported_page_list sup_pages;
5449 ccb = cam_getccb(dev);
5451 warn("Unable to allocate CCB");
5456 /* cam_getccb cleans up the header, caller has to zero the payload */
5457 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5459 bzero(&sup_pages, sizeof(sup_pages));
5461 scsi_inquiry(&ccb->csio,
5462 /*retries*/ retry_count,
5464 /* tag_action */ MSG_SIMPLE_Q_TAG,
5465 /* inq_buf */ (u_int8_t *)&sup_pages,
5466 /* inq_len */ sizeof(sup_pages),
5468 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5469 /* sense_len */ SSD_FULL_SIZE,
5470 /* timeout */ timeout ? timeout : 5000);
5472 /* Disable freezing the device queue */
5473 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5475 if (retry_count != 0)
5476 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5478 if (cam_send_ccb(dev, ccb) < 0) {
5485 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5486 if (verbosemode != 0)
5487 cam_error_print(dev, ccb, CAM_ESF_ALL,
5488 CAM_EPF_ALL, stderr);
5493 for (i = 0; i < sup_pages.length; i++) {
5494 if (sup_pages.list[i] == page_id) {
5507 * devtype is filled in with the type of device.
5508 * Returns 0 for success, non-zero for failure.
5511 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5512 int verbosemode, camcontrol_devtype *devtype)
5514 struct ccb_getdev cgd;
5517 retval = get_cgd(dev, &cgd);
5521 switch (cgd.protocol) {
5527 *devtype = CC_DT_ATA;
5529 break; /*NOTREACHED*/
5531 *devtype = CC_DT_NVME;
5533 break; /*NOTREACHED*/
5535 *devtype = CC_DT_MMCSD;
5537 break; /*NOTREACHED*/
5539 *devtype = CC_DT_UNKNOWN;
5541 break; /*NOTREACHED*/
5544 if (retry_count == -1) {
5546 * For a retry count of -1, used only the cached data to avoid
5547 * I/O to the drive. Sending the identify command to the drive
5548 * can cause issues for SATL attachaed drives since identify is
5549 * not an NCQ command.
5551 if (cgd.ident_data.config != 0)
5552 *devtype = CC_DT_SATL;
5554 *devtype = CC_DT_SCSI;
5557 * Check for the ATA Information VPD page (0x89). If this is an
5558 * ATA device behind a SCSI to ATA translation layer (SATL),
5559 * this VPD page should be present.
5561 * If that VPD page isn't present, or we get an error back from
5562 * the INQUIRY command, we'll just treat it as a normal SCSI
5565 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5566 timeout, verbosemode);
5568 *devtype = CC_DT_SATL;
5570 *devtype = CC_DT_SCSI;
5579 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5580 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5581 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5582 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5583 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5584 int is48bit, camcontrol_devtype devtype)
5588 if (devtype == CC_DT_ATA) {
5589 cam_fill_ataio(&ccb->ataio,
5590 /*retries*/ retry_count,
5593 /*tag_action*/ tag_action,
5594 /*data_ptr*/ data_ptr,
5595 /*dxfer_len*/ dxfer_len,
5596 /*timeout*/ timeout);
5597 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5598 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5601 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5604 if (auxiliary != 0) {
5605 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5606 ccb->ataio.aux = auxiliary;
5609 if (ata_flags & AP_FLAG_CHK_COND)
5610 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5612 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5613 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5614 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5615 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5617 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5618 protocol |= AP_EXTEND;
5620 retval = scsi_ata_pass(&ccb->csio,
5621 /*retries*/ retry_count,
5624 /*tag_action*/ tag_action,
5625 /*protocol*/ protocol,
5626 /*ata_flags*/ ata_flags,
5627 /*features*/ features,
5628 /*sector_count*/ sector_count,
5630 /*command*/ command,
5633 /*auxiliary*/ auxiliary,
5635 /*data_ptr*/ data_ptr,
5636 /*dxfer_len*/ dxfer_len,
5637 /*cdb_storage*/ cdb_storage,
5638 /*cdb_storage_len*/ cdb_storage_len,
5639 /*minimum_cmd_size*/ 0,
5640 /*sense_len*/ sense_len,
5641 /*timeout*/ timeout);
5648 * Returns: 0 -- success, 1 -- error, 2 -- lba truncated,
5649 * 4 -- count truncated, 6 -- lba and count truncated.
5652 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5653 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5657 switch (ccb->ccb_h.func_code) {
5660 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5664 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5665 * or 16 byte, and need to see what
5667 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5668 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5670 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5671 if ((opcode != ATA_PASS_12)
5672 && (opcode != ATA_PASS_16)) {
5673 warnx("%s: unsupported opcode %02x", __func__, opcode);
5677 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5679 /* Note: the _ccb() variant returns 0 for an error */
5683 sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
5684 switch (error_code) {
5685 case SSD_DESC_CURRENT_ERROR:
5686 case SSD_DESC_DEFERRED_ERROR: {
5687 struct scsi_sense_data_desc *sense;
5688 struct scsi_sense_ata_ret_desc *desc;
5691 sense = (struct scsi_sense_data_desc *)
5692 &ccb->csio.sense_data;
5694 desc_ptr = scsi_find_desc(sense, sense_len,
5696 if (desc_ptr == NULL) {
5697 cam_error_print(dev, ccb, CAM_ESF_ALL,
5698 CAM_EPF_ALL, stderr);
5701 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5703 *error = desc->error;
5704 *count = (desc->count_15_8 << 8) |
5706 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5707 ((uint64_t)desc->lba_39_32 << 32) |
5708 ((uint64_t)desc->lba_31_24 << 24) |
5709 (desc->lba_23_16 << 16) |
5710 (desc->lba_15_8 << 8) |
5712 *device = desc->device;
5713 *status = desc->status;
5716 * If the extend bit isn't set, the result is for a
5717 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5718 * command without the extend bit set. This means
5719 * that the device is supposed to return 28-bit
5720 * status. The count field is only 8 bits, and the
5721 * LBA field is only 8 bits.
5723 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5729 case SSD_CURRENT_ERROR:
5730 case SSD_DEFERRED_ERROR: {
5734 * In my understanding of SAT-5 specification, saying:
5735 * "without interpreting the contents of the STATUS",
5736 * this should not happen if CK_COND was set, but it
5737 * does at least for some devices, so try to revert.
5739 if ((sense_key == SSD_KEY_ABORTED_COMMAND) &&
5740 (asc == 0) && (ascq == 0)) {
5741 *status = ATA_STATUS_ERROR;
5742 *error = ATA_ERROR_ABORT;
5749 if ((sense_key != SSD_KEY_RECOVERED_ERROR) ||
5750 (asc != 0x00) || (ascq != 0x1d))
5754 scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5755 SSD_DESC_INFO, &val, NULL);
5756 *error = (val >> 24) & 0xff;
5757 *status = (val >> 16) & 0xff;
5758 *device = (val >> 8) & 0xff;
5759 *count = val & 0xff;
5762 scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5763 SSD_DESC_COMMAND, &val, NULL);
5764 *lba = ((val >> 16) & 0xff) | (val & 0xff00) |
5765 ((val & 0xff) << 16);
5767 /* Report UPPER NONZERO bits as errors 2, 4 and 6. */
5768 return ((val >> 28) & 0x06);
5777 struct ata_res *res;
5779 /* Only some statuses return ATA result register set. */
5780 if (cam_ccb_status(ccb) != CAM_REQ_CMP &&
5781 cam_ccb_status(ccb) != CAM_ATA_STATUS_ERROR)
5784 res = &ccb->ataio.res;
5785 *error = res->error;
5786 *status = res->status;
5787 *device = res->device;
5788 *count = res->sector_count;
5789 *lba = (res->lba_high << 16) |
5790 (res->lba_mid << 8) |
5792 if (ccb->ataio.cmd.flags & CAM_ATAIO_48BIT) {
5793 *count |= (res->sector_count_exp << 8);
5794 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5795 ((uint64_t)res->lba_mid_exp << 32) |
5796 ((uint64_t)res->lba_high_exp << 40);
5798 *lba |= (res->device & 0xf) << 24;
5809 cpi_print(struct ccb_pathinq *cpi)
5811 char adapter_str[1024];
5814 snprintf(adapter_str, sizeof(adapter_str),
5815 "%s%d:", cpi->dev_name, cpi->unit_number);
5817 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5820 for (i = 1; i < UINT8_MAX; i = i << 1) {
5823 if ((i & cpi->hba_inquiry) == 0)
5826 fprintf(stdout, "%s supports ", adapter_str);
5830 str = "MDP message";
5833 str = "32 bit wide SCSI";
5836 str = "16 bit wide SCSI";
5839 str = "SDTR message";
5842 str = "linked CDBs";
5845 str = "tag queue messages";
5848 str = "soft reset alternative";
5851 str = "SATA Port Multiplier";
5854 str = "unknown PI bit set";
5857 fprintf(stdout, "%s\n", str);
5860 for (i = 1; i < UINT32_MAX; i = i << 1) {
5863 if ((i & cpi->hba_misc) == 0)
5866 fprintf(stdout, "%s ", adapter_str);
5870 str = "can understand ata_ext requests";
5873 str = "64bit extended LUNs supported";
5876 str = "bus scans from high ID to low ID";
5879 str = "removable devices not included in scan";
5881 case PIM_NOINITIATOR:
5882 str = "initiator role not supported";
5884 case PIM_NOBUSRESET:
5885 str = "user has disabled initial BUS RESET or"
5886 " controller is in target/mixed mode";
5889 str = "do not send 6-byte commands";
5892 str = "scan bus sequentially";
5895 str = "unmapped I/O supported";
5898 str = "does its own scanning";
5901 str = "unknown PIM bit set";
5904 fprintf(stdout, "%s\n", str);
5907 for (i = 1; i < UINT16_MAX; i = i << 1) {
5910 if ((i & cpi->target_sprt) == 0)
5913 fprintf(stdout, "%s supports ", adapter_str);
5916 str = "target mode processor mode";
5919 str = "target mode phase cog. mode";
5921 case PIT_DISCONNECT:
5922 str = "disconnects in target mode";
5925 str = "terminate I/O message in target mode";
5928 str = "group 6 commands in target mode";
5931 str = "group 7 commands in target mode";
5934 str = "unknown PIT bit set";
5938 fprintf(stdout, "%s\n", str);
5940 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5942 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5944 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5946 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5947 adapter_str, cpi->hpath_id);
5948 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5950 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5951 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5952 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5953 adapter_str, cpi->hba_vendor);
5954 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5955 adapter_str, cpi->hba_device);
5956 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5957 adapter_str, cpi->hba_subvendor);
5958 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5959 adapter_str, cpi->hba_subdevice);
5960 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5961 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5962 if (cpi->base_transfer_speed > 1000)
5963 fprintf(stdout, "%d.%03dMB/sec\n",
5964 cpi->base_transfer_speed / 1000,
5965 cpi->base_transfer_speed % 1000);
5967 fprintf(stdout, "%dKB/sec\n",
5968 (cpi->base_transfer_speed % 1000) * 1000);
5969 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5970 adapter_str, cpi->maxio);
5974 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5975 struct ccb_trans_settings *cts)
5981 ccb = cam_getccb(device);
5984 warnx("get_print_cts: error allocating ccb");
5988 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5990 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5992 if (user_settings == 0)
5993 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5995 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5997 if (cam_send_ccb(device, ccb) < 0) {
5998 warn("error sending XPT_GET_TRAN_SETTINGS CCB");
6000 goto get_print_cts_bailout;
6003 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6004 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
6005 if (arglist & CAM_ARG_VERBOSE)
6006 cam_error_print(device, ccb, CAM_ESF_ALL,
6007 CAM_EPF_ALL, stderr);
6009 goto get_print_cts_bailout;
6013 cts_print(device, &ccb->cts);
6016 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
6018 get_print_cts_bailout:
6026 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
6027 int timeout, int argc, char **argv, char *combinedopt)
6031 int user_settings = 0;
6033 int disc_enable = -1, tag_enable = -1;
6036 double syncrate = -1;
6039 int change_settings = 0, send_tur = 0;
6040 struct ccb_pathinq cpi;
6042 ccb = cam_getccb(device);
6044 warnx("ratecontrol: error allocating ccb");
6047 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6056 if (strncasecmp(optarg, "enable", 6) == 0)
6058 else if (strncasecmp(optarg, "disable", 7) == 0)
6061 warnx("-D argument \"%s\" is unknown", optarg);
6063 goto ratecontrol_bailout;
6065 change_settings = 1;
6068 mode = ata_string2mode(optarg);
6070 warnx("unknown mode '%s'", optarg);
6072 goto ratecontrol_bailout;
6074 change_settings = 1;
6077 offset = strtol(optarg, NULL, 0);
6079 warnx("offset value %d is < 0", offset);
6081 goto ratecontrol_bailout;
6083 change_settings = 1;
6089 syncrate = atof(optarg);
6091 warnx("sync rate %f is < 0", syncrate);
6093 goto ratecontrol_bailout;
6095 change_settings = 1;
6098 if (strncasecmp(optarg, "enable", 6) == 0)
6100 else if (strncasecmp(optarg, "disable", 7) == 0)
6103 warnx("-T argument \"%s\" is unknown", optarg);
6105 goto ratecontrol_bailout;
6107 change_settings = 1;
6113 bus_width = strtol(optarg, NULL, 0);
6114 if (bus_width < 0) {
6115 warnx("bus width %d is < 0", bus_width);
6117 goto ratecontrol_bailout;
6119 change_settings = 1;
6126 * Grab path inquiry information, so we can determine whether
6127 * or not the initiator is capable of the things that the user
6130 if ((retval = get_cpi(device, &cpi)) != 0)
6131 goto ratecontrol_bailout;
6132 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
6134 fprintf(stdout, "%s parameters:\n",
6135 user_settings ? "User" : "Current");
6137 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
6139 goto ratecontrol_bailout;
6141 if (arglist & CAM_ARG_VERBOSE)
6144 if (change_settings) {
6145 int didsettings = 0;
6146 struct ccb_trans_settings_spi *spi = NULL;
6147 struct ccb_trans_settings_pata *pata = NULL;
6148 struct ccb_trans_settings_sata *sata = NULL;
6149 struct ccb_trans_settings_ata *ata = NULL;
6150 struct ccb_trans_settings_scsi *scsi = NULL;
6152 if (ccb->cts.transport == XPORT_SPI)
6153 spi = &ccb->cts.xport_specific.spi;
6154 if (ccb->cts.transport == XPORT_ATA)
6155 pata = &ccb->cts.xport_specific.ata;
6156 if (ccb->cts.transport == XPORT_SATA)
6157 sata = &ccb->cts.xport_specific.sata;
6158 if (ccb->cts.protocol == PROTO_ATA)
6159 ata = &ccb->cts.proto_specific.ata;
6160 if (ccb->cts.protocol == PROTO_SCSI)
6161 scsi = &ccb->cts.proto_specific.scsi;
6162 ccb->cts.xport_specific.valid = 0;
6163 ccb->cts.proto_specific.valid = 0;
6164 if (spi && disc_enable != -1) {
6165 spi->valid |= CTS_SPI_VALID_DISC;
6166 if (disc_enable == 0)
6167 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6169 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6172 if (tag_enable != -1) {
6173 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6174 warnx("HBA does not support tagged queueing, "
6175 "so you cannot modify tag settings");
6177 goto ratecontrol_bailout;
6180 ata->valid |= CTS_SCSI_VALID_TQ;
6181 if (tag_enable == 0)
6182 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6184 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6187 scsi->valid |= CTS_SCSI_VALID_TQ;
6188 if (tag_enable == 0)
6189 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6191 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6195 if (spi && offset != -1) {
6196 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6197 warnx("HBA is not capable of changing offset");
6199 goto ratecontrol_bailout;
6201 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6202 spi->sync_offset = offset;
6205 if (spi && syncrate != -1) {
6206 int prelim_sync_period;
6208 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6209 warnx("HBA is not capable of changing "
6212 goto ratecontrol_bailout;
6214 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6216 * The sync rate the user gives us is in MHz.
6217 * We need to translate it into KHz for this
6222 * Next, we calculate a "preliminary" sync period
6223 * in tenths of a nanosecond.
6226 prelim_sync_period = 0;
6228 prelim_sync_period = 10000000 / syncrate;
6230 scsi_calc_syncparam(prelim_sync_period);
6233 if (sata && syncrate != -1) {
6234 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6235 warnx("HBA is not capable of changing "
6238 goto ratecontrol_bailout;
6240 if (!user_settings) {
6241 warnx("You can modify only user rate "
6242 "settings for SATA");
6244 goto ratecontrol_bailout;
6246 sata->revision = ata_speed2revision(syncrate * 100);
6247 if (sata->revision < 0) {
6248 warnx("Invalid rate %f", syncrate);
6250 goto ratecontrol_bailout;
6252 sata->valid |= CTS_SATA_VALID_REVISION;
6255 if ((pata || sata) && mode != -1) {
6256 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6257 warnx("HBA is not capable of changing "
6260 goto ratecontrol_bailout;
6262 if (!user_settings) {
6263 warnx("You can modify only user mode "
6264 "settings for ATA/SATA");
6266 goto ratecontrol_bailout;
6270 pata->valid |= CTS_ATA_VALID_MODE;
6273 sata->valid |= CTS_SATA_VALID_MODE;
6278 * The bus_width argument goes like this:
6282 * Therefore, if you shift the number of bits given on the
6283 * command line right by 4, you should get the correct
6286 if (spi && bus_width != -1) {
6288 * We might as well validate things here with a
6289 * decipherable error message, rather than what
6290 * will probably be an indecipherable error message
6291 * by the time it gets back to us.
6293 if ((bus_width == 16)
6294 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6295 warnx("HBA does not support 16 bit bus width");
6297 goto ratecontrol_bailout;
6298 } else if ((bus_width == 32)
6299 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6300 warnx("HBA does not support 32 bit bus width");
6302 goto ratecontrol_bailout;
6303 } else if ((bus_width != 8)
6304 && (bus_width != 16)
6305 && (bus_width != 32)) {
6306 warnx("Invalid bus width %d", bus_width);
6308 goto ratecontrol_bailout;
6310 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6311 spi->bus_width = bus_width >> 4;
6314 if (didsettings == 0) {
6315 goto ratecontrol_bailout;
6317 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6318 if (cam_send_ccb(device, ccb) < 0) {
6319 warn("error sending XPT_SET_TRAN_SETTINGS CCB");
6321 goto ratecontrol_bailout;
6323 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6324 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6325 if (arglist & CAM_ARG_VERBOSE) {
6326 cam_error_print(device, ccb, CAM_ESF_ALL,
6327 CAM_EPF_ALL, stderr);
6330 goto ratecontrol_bailout;
6334 retval = testunitready(device, task_attr, retry_count, timeout,
6335 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6337 * If the TUR didn't succeed, just bail.
6341 fprintf(stderr, "Test Unit Ready failed\n");
6342 goto ratecontrol_bailout;
6345 if ((change_settings || send_tur) && !quiet &&
6346 (ccb->cts.transport == XPORT_ATA ||
6347 ccb->cts.transport == XPORT_SATA || send_tur)) {
6348 fprintf(stdout, "New parameters:\n");
6349 retval = get_print_cts(device, user_settings, 0, NULL);
6352 ratecontrol_bailout:
6358 scsiformat(struct cam_device *device, int argc, char **argv,
6359 char *combinedopt, int task_attr, int retry_count, int timeout)
6363 int ycount = 0, quiet = 0;
6364 int error = 0, retval = 0;
6365 int use_timeout = 10800 * 1000;
6367 struct format_defect_list_header fh;
6368 u_int8_t *data_ptr = NULL;
6369 u_int32_t dxfer_len = 0;
6371 int num_warnings = 0;
6374 ccb = cam_getccb(device);
6377 warnx("scsiformat: error allocating ccb");
6381 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6383 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6403 if (quiet == 0 && ycount == 0) {
6404 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6405 "following device:\n");
6407 error = scsidoinquiry(device, argc, argv, combinedopt,
6408 task_attr, retry_count, timeout);
6411 warnx("scsiformat: error sending inquiry");
6412 goto scsiformat_bailout;
6417 if (!get_confirmation()) {
6419 goto scsiformat_bailout;
6424 use_timeout = timeout;
6427 fprintf(stdout, "Current format timeout is %d seconds\n",
6428 use_timeout / 1000);
6432 * If the user hasn't disabled questions and didn't specify a
6433 * timeout on the command line, ask them if they want the current
6437 && (timeout == 0)) {
6439 int new_timeout = 0;
6441 fprintf(stdout, "Enter new timeout in seconds or press\n"
6442 "return to keep the current timeout [%d] ",
6443 use_timeout / 1000);
6445 if (fgets(str, sizeof(str), stdin) != NULL) {
6447 new_timeout = atoi(str);
6450 if (new_timeout != 0) {
6451 use_timeout = new_timeout * 1000;
6452 fprintf(stdout, "Using new timeout value %d\n",
6453 use_timeout / 1000);
6458 * Keep this outside the if block below to silence any unused
6459 * variable warnings.
6461 bzero(&fh, sizeof(fh));
6464 * If we're in immediate mode, we've got to include the format
6467 if (immediate != 0) {
6468 fh.byte2 = FU_DLH_IMMED;
6469 data_ptr = (u_int8_t *)&fh;
6470 dxfer_len = sizeof(fh);
6471 byte2 = FU_FMT_DATA;
6472 } else if (quiet == 0) {
6473 fprintf(stdout, "Formatting...");
6477 scsi_format_unit(&ccb->csio,
6478 /* retries */ retry_count,
6480 /* tag_action */ task_attr,
6483 /* data_ptr */ data_ptr,
6484 /* dxfer_len */ dxfer_len,
6485 /* sense_len */ SSD_FULL_SIZE,
6486 /* timeout */ use_timeout);
6488 /* Disable freezing the device queue */
6489 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6491 if (arglist & CAM_ARG_ERR_RECOVER)
6492 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6494 if (((retval = cam_send_ccb(device, ccb)) < 0)
6495 || ((immediate == 0)
6496 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6497 const char errstr[] = "error sending format command";
6504 if (arglist & CAM_ARG_VERBOSE) {
6505 cam_error_print(device, ccb, CAM_ESF_ALL,
6506 CAM_EPF_ALL, stderr);
6509 goto scsiformat_bailout;
6513 * If we ran in non-immediate mode, we already checked for errors
6514 * above and printed out any necessary information. If we're in
6515 * immediate mode, we need to loop through and get status
6516 * information periodically.
6518 if (immediate == 0) {
6520 fprintf(stdout, "Format Complete\n");
6522 goto scsiformat_bailout;
6529 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6532 * There's really no need to do error recovery or
6533 * retries here, since we're just going to sit in a
6534 * loop and wait for the device to finish formatting.
6536 scsi_test_unit_ready(&ccb->csio,
6539 /* tag_action */ task_attr,
6540 /* sense_len */ SSD_FULL_SIZE,
6541 /* timeout */ 5000);
6543 /* Disable freezing the device queue */
6544 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6546 retval = cam_send_ccb(device, ccb);
6549 * If we get an error from the ioctl, bail out. SCSI
6550 * errors are expected.
6553 warn("error sending TEST UNIT READY command");
6555 goto scsiformat_bailout;
6558 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6560 if ((status != CAM_REQ_CMP)
6561 && (status == CAM_SCSI_STATUS_ERROR)
6562 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6563 struct scsi_sense_data *sense;
6564 int error_code, sense_key, asc, ascq;
6566 sense = &ccb->csio.sense_data;
6567 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6568 ccb->csio.sense_resid, &error_code, &sense_key,
6569 &asc, &ascq, /*show_errors*/ 1);
6572 * According to the SCSI-2 and SCSI-3 specs, a
6573 * drive that is in the middle of a format should
6574 * return NOT READY with an ASC of "logical unit
6575 * not ready, format in progress". The sense key
6576 * specific bytes will then be a progress indicator.
6578 if ((sense_key == SSD_KEY_NOT_READY)
6579 && (asc == 0x04) && (ascq == 0x04)) {
6582 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6583 ccb->csio.sense_resid, sks) == 0)
6586 u_int64_t percentage;
6588 val = scsi_2btoul(&sks[1]);
6589 percentage = 10000ull * val;
6592 "\rFormatting: %ju.%02u %% "
6594 (uintmax_t)(percentage /
6596 (unsigned)((percentage /
6600 } else if ((quiet == 0)
6601 && (++num_warnings <= 1)) {
6602 warnx("Unexpected SCSI Sense Key "
6603 "Specific value returned "
6605 scsi_sense_print(device, &ccb->csio,
6607 warnx("Unable to print status "
6608 "information, but format will "
6610 warnx("will exit when format is "
6615 warnx("Unexpected SCSI error during format");
6616 cam_error_print(device, ccb, CAM_ESF_ALL,
6617 CAM_EPF_ALL, stderr);
6619 goto scsiformat_bailout;
6622 } else if (status != CAM_REQ_CMP) {
6623 warnx("Unexpected CAM status %#x", status);
6624 if (arglist & CAM_ARG_VERBOSE)
6625 cam_error_print(device, ccb, CAM_ESF_ALL,
6626 CAM_EPF_ALL, stderr);
6628 goto scsiformat_bailout;
6631 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6634 fprintf(stdout, "\nFormat Complete\n");
6644 sanitize_wait_ata(struct cam_device *device, union ccb *ccb, int quiet,
6645 camcontrol_devtype devtype)
6648 uint8_t error = 0, ata_device = 0, status = 0;
6654 retval = build_ata_cmd(ccb,
6656 /*flags*/ CAM_DIR_NONE,
6657 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6658 /*protocol*/ AP_PROTO_NON_DATA,
6659 /*ata_flags*/ AP_FLAG_CHK_COND,
6660 /*features*/ 0x00, /* SANITIZE STATUS EXT */
6663 /*command*/ ATA_SANITIZE,
6667 /*cdb_storage*/ NULL,
6668 /*cdb_storage_len*/ 0,
6669 /*sense_len*/ SSD_FULL_SIZE,
6672 /*devtype*/ devtype);
6674 warnx("%s: build_ata_cmd() failed, likely "
6675 "programmer error", __func__);
6679 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6680 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6681 retval = cam_send_ccb(device, ccb);
6683 warn("error sending SANITIZE STATUS EXT command");
6687 retval = get_ata_status(device, ccb, &error, &count, &lba,
6688 &ata_device, &status);
6690 warnx("Can't get SANITIZE STATUS EXT status, "
6691 "sanitize may still run.");
6694 if (status & ATA_STATUS_ERROR) {
6695 warnx("SANITIZE STATUS EXT failed, "
6696 "sanitize may still run.");
6699 if (count & 0x4000) {
6704 "Sanitizing: %u.%02u%% (%d/%d)\r",
6705 (perc / (0x10000 * 100)),
6706 ((perc / 0x10000) % 100),
6711 } else if ((count & 0x8000) == 0) {
6712 warnx("Sanitize complete with an error. ");
6721 sanitize_wait_scsi(struct cam_device *device, union ccb *ccb, int task_attr, int quiet)
6723 int warnings = 0, retval;
6728 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6731 * There's really no need to do error recovery or
6732 * retries here, since we're just going to sit in a
6733 * loop and wait for the device to finish sanitizing.
6735 scsi_test_unit_ready(&ccb->csio,
6738 /* tag_action */ task_attr,
6739 /* sense_len */ SSD_FULL_SIZE,
6740 /* timeout */ 5000);
6742 /* Disable freezing the device queue */
6743 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6745 retval = cam_send_ccb(device, ccb);
6748 * If we get an error from the ioctl, bail out. SCSI
6749 * errors are expected.
6752 warn("error sending TEST UNIT READY command");
6756 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6757 if ((status == CAM_SCSI_STATUS_ERROR) &&
6758 ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6759 struct scsi_sense_data *sense;
6760 int error_code, sense_key, asc, ascq;
6762 sense = &ccb->csio.sense_data;
6763 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6764 ccb->csio.sense_resid, &error_code, &sense_key,
6765 &asc, &ascq, /*show_errors*/ 1);
6768 * According to the SCSI-3 spec, a drive that is in the
6769 * middle of a sanitize should return NOT READY with an
6770 * ASC of "logical unit not ready, sanitize in
6771 * progress". The sense key specific bytes will then
6772 * be a progress indicator.
6774 if ((sense_key == SSD_KEY_NOT_READY)
6775 && (asc == 0x04) && (ascq == 0x1b)) {
6778 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6779 ccb->csio.sense_resid, sks) == 0)
6781 val = scsi_2btoul(&sks[1]);
6784 "Sanitizing: %u.%02u%% (%d/%d)\r",
6785 (perc / (0x10000 * 100)),
6786 ((perc / 0x10000) % 100),
6789 } else if ((quiet == 0) && (++warnings <= 1)) {
6790 warnx("Unexpected SCSI Sense Key "
6791 "Specific value returned "
6792 "during sanitize:");
6793 scsi_sense_print(device, &ccb->csio,
6795 warnx("Unable to print status "
6796 "information, but sanitze will "
6798 warnx("will exit when sanitize is "
6803 warnx("Unexpected SCSI error during sanitize");
6804 cam_error_print(device, ccb, CAM_ESF_ALL,
6805 CAM_EPF_ALL, stderr);
6809 } else if (status != CAM_REQ_CMP && status != CAM_REQUEUE_REQ) {
6810 warnx("Unexpected CAM status %#x", status);
6811 if (arglist & CAM_ARG_VERBOSE)
6812 cam_error_print(device, ccb, CAM_ESF_ALL,
6813 CAM_EPF_ALL, stderr);
6816 } while ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6821 sanitize(struct cam_device *device, int argc, char **argv,
6822 char *combinedopt, int task_attr, int retry_count, int timeout)
6825 u_int8_t action = 0;
6827 int ycount = 0, quiet = 0;
6835 const char *pattern = NULL;
6836 u_int8_t *data_ptr = NULL;
6837 u_int32_t dxfer_len = 0;
6839 uint16_t feature, count;
6842 camcontrol_devtype dt;
6845 * Get the device type, request no I/O be done to do this.
6847 error = get_device_type(device, -1, 0, 0, &dt);
6848 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
6849 warnx("sanitize: can't get device type");
6853 ccb = cam_getccb(device);
6856 warnx("sanitize: error allocating ccb");
6860 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6862 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6865 if (strcasecmp(optarg, "overwrite") == 0)
6866 action = SSZ_SERVICE_ACTION_OVERWRITE;
6867 else if (strcasecmp(optarg, "block") == 0)
6868 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6869 else if (strcasecmp(optarg, "crypto") == 0)
6870 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6871 else if (strcasecmp(optarg, "exitfailure") == 0)
6872 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6874 warnx("invalid service operation \"%s\"",
6877 goto sanitize_bailout;
6881 passes = strtol(optarg, NULL, 0);
6882 if (passes < 1 || passes > 31) {
6883 warnx("invalid passes value %d", passes);
6885 goto sanitize_bailout;
6904 /* ATA supports only immediate commands. */
6905 if (dt == CC_DT_SCSI)
6918 warnx("an action is required");
6920 goto sanitize_bailout;
6921 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6922 struct scsi_sanitize_parameter_list *pl;
6926 if (pattern == NULL) {
6927 warnx("overwrite action requires -P argument");
6929 goto sanitize_bailout;
6931 fd = open(pattern, O_RDONLY);
6933 warn("cannot open pattern file %s", pattern);
6935 goto sanitize_bailout;
6937 if (fstat(fd, &sb) < 0) {
6938 warn("cannot stat pattern file %s", pattern);
6940 goto sanitize_bailout;
6943 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6944 warnx("pattern file size exceeds maximum value %d",
6945 SSZPL_MAX_PATTERN_LENGTH);
6947 goto sanitize_bailout;
6949 dxfer_len = sizeof(*pl) + sz;
6950 data_ptr = calloc(1, dxfer_len);
6951 if (data_ptr == NULL) {
6952 warnx("cannot allocate parameter list buffer");
6954 goto sanitize_bailout;
6957 amt = read(fd, data_ptr + sizeof(*pl), sz);
6959 warn("cannot read pattern file");
6961 goto sanitize_bailout;
6962 } else if (amt != sz) {
6963 warnx("short pattern file read");
6965 goto sanitize_bailout;
6968 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6974 pl->byte1 |= SSZPL_INVERT;
6975 scsi_ulto2b(sz, pl->length);
6981 else if (invert != 0)
6983 else if (pattern != NULL)
6988 warnx("%s argument only valid with overwrite "
6991 goto sanitize_bailout;
6995 if (quiet == 0 && ycount == 0) {
6996 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6997 "following device:\n");
6999 if (dt == CC_DT_SCSI) {
7000 error = scsidoinquiry(device, argc, argv, combinedopt,
7001 task_attr, retry_count, timeout);
7002 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7003 struct ata_params *ident_buf;
7004 error = ata_do_identify(device, retry_count, timeout,
7007 printf("%s%d: ", device->device_name,
7008 device->dev_unit_num);
7009 ata_print_ident(ident_buf);
7016 warnx("sanitize: error sending inquiry");
7017 goto sanitize_bailout;
7022 if (!get_confirmation()) {
7024 goto sanitize_bailout;
7029 use_timeout = timeout;
7031 use_timeout = (immediate ? 10 : 10800) * 1000;
7033 if (immediate == 0 && quiet == 0) {
7034 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
7035 use_timeout / 1000);
7039 * If the user hasn't disabled questions and didn't specify a
7040 * timeout on the command line, ask them if they want the current
7043 if (immediate == 0 && ycount == 0 && timeout == 0) {
7045 int new_timeout = 0;
7047 fprintf(stdout, "Enter new timeout in seconds or press\n"
7048 "return to keep the current timeout [%d] ",
7049 use_timeout / 1000);
7051 if (fgets(str, sizeof(str), stdin) != NULL) {
7053 new_timeout = atoi(str);
7056 if (new_timeout != 0) {
7057 use_timeout = new_timeout * 1000;
7058 fprintf(stdout, "Using new timeout value %d\n",
7059 use_timeout / 1000);
7063 if (dt == CC_DT_SCSI) {
7066 byte2 |= SSZ_UNRESTRICTED_EXIT;
7069 scsi_sanitize(&ccb->csio,
7070 /* retries */ retry_count,
7072 /* tag_action */ task_attr,
7075 /* data_ptr */ data_ptr,
7076 /* dxfer_len */ dxfer_len,
7077 /* sense_len */ SSD_FULL_SIZE,
7078 /* timeout */ use_timeout);
7080 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7081 if (arglist & CAM_ARG_ERR_RECOVER)
7082 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7083 if (cam_send_ccb(device, ccb) < 0) {
7084 warn("error sending sanitize command");
7086 goto sanitize_bailout;
7088 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7089 if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
7090 feature = 0x14; /* OVERWRITE EXT */
7091 lba = 0x4F5700000000 | scsi_4btoul(data_ptr + 4);
7092 count = (passes == 0) ? 1 : (passes >= 16) ? 0 : passes;
7094 count |= 0x80; /* INVERT PATTERN */
7096 count |= 0x10; /* FAILURE MODE */
7097 } else if (action == SSZ_SERVICE_ACTION_BLOCK_ERASE) {
7098 feature = 0x12; /* BLOCK ERASE EXT */
7099 lba = 0x0000426B4572;
7102 count |= 0x10; /* FAILURE MODE */
7103 } else if (action == SSZ_SERVICE_ACTION_CRYPTO_ERASE) {
7104 feature = 0x11; /* CRYPTO SCRAMBLE EXT */
7105 lba = 0x000043727970;
7108 count |= 0x10; /* FAILURE MODE */
7109 } else if (action == SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE) {
7110 feature = 0x00; /* SANITIZE STATUS EXT */
7112 count = 1; /* CLEAR SANITIZE OPERATION FAILED */
7115 goto sanitize_bailout;
7118 error = ata_do_cmd(device,
7121 /*flags*/CAM_DIR_NONE,
7122 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
7124 /*tag_action*/MSG_SIMPLE_Q_TAG,
7125 /*command*/ATA_SANITIZE,
7126 /*features*/feature,
7128 /*sector_count*/count,
7131 /*timeout*/ use_timeout,
7135 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7136 struct scsi_sense_data *sense;
7137 int error_code, sense_key, asc, ascq;
7139 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
7140 CAM_SCSI_STATUS_ERROR) {
7141 sense = &ccb->csio.sense_data;
7142 scsi_extract_sense_len(sense, ccb->csio.sense_len -
7143 ccb->csio.sense_resid, &error_code, &sense_key,
7144 &asc, &ascq, /*show_errors*/ 1);
7146 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
7147 asc == 0x20 && ascq == 0x00)
7148 warnx("sanitize is not supported by "
7151 warnx("error sanitizing this device");
7153 warnx("error sanitizing this device");
7155 if (arglist & CAM_ARG_VERBOSE) {
7156 cam_error_print(device, ccb, CAM_ESF_ALL,
7157 CAM_EPF_ALL, stderr);
7160 goto sanitize_bailout;
7164 * If we ran in non-immediate mode, we already checked for errors
7165 * above and printed out any necessary information. If we're in
7166 * immediate mode, we need to loop through and get status
7167 * information periodically.
7169 if (immediate == 0) {
7171 fprintf(stdout, "Sanitize Complete\n");
7173 goto sanitize_bailout;
7177 if (dt == CC_DT_SCSI) {
7178 error = sanitize_wait_scsi(device, ccb, task_attr, quiet);
7179 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7180 error = sanitize_wait_ata(device, ccb, quiet, dt);
7183 if (error == 0 && quiet == 0)
7184 fprintf(stdout, "Sanitize Complete \n");
7189 if (data_ptr != NULL)
7197 scsireportluns(struct cam_device *device, int argc, char **argv,
7198 char *combinedopt, int task_attr, int retry_count, int timeout)
7201 int c, countonly, lunsonly;
7202 struct scsi_report_luns_data *lundata;
7204 uint8_t report_type;
7205 uint32_t list_len, i, j;
7210 report_type = RPL_REPORT_DEFAULT;
7211 ccb = cam_getccb(device);
7214 warnx("%s: error allocating ccb", __func__);
7218 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7223 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7232 if (strcasecmp(optarg, "default") == 0)
7233 report_type = RPL_REPORT_DEFAULT;
7234 else if (strcasecmp(optarg, "wellknown") == 0)
7235 report_type = RPL_REPORT_WELLKNOWN;
7236 else if (strcasecmp(optarg, "all") == 0)
7237 report_type = RPL_REPORT_ALL;
7239 warnx("%s: invalid report type \"%s\"",
7250 if ((countonly != 0)
7251 && (lunsonly != 0)) {
7252 warnx("%s: you can only specify one of -c or -l", __func__);
7257 * According to SPC-4, the allocation length must be at least 16
7258 * bytes -- enough for the header and one LUN.
7260 alloc_len = sizeof(*lundata) + 8;
7264 lundata = malloc(alloc_len);
7266 if (lundata == NULL) {
7267 warn("%s: error mallocing %d bytes", __func__, alloc_len);
7272 scsi_report_luns(&ccb->csio,
7273 /*retries*/ retry_count,
7275 /*tag_action*/ task_attr,
7276 /*select_report*/ report_type,
7277 /*rpl_buf*/ lundata,
7278 /*alloc_len*/ alloc_len,
7279 /*sense_len*/ SSD_FULL_SIZE,
7280 /*timeout*/ timeout ? timeout : 5000);
7282 /* Disable freezing the device queue */
7283 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7285 if (arglist & CAM_ARG_ERR_RECOVER)
7286 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7288 if (cam_send_ccb(device, ccb) < 0) {
7289 warn("error sending REPORT LUNS command");
7294 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7295 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7301 list_len = scsi_4btoul(lundata->length);
7304 * If we need to list the LUNs, and our allocation
7305 * length was too short, reallocate and retry.
7307 if ((countonly == 0)
7308 && (list_len > (alloc_len - sizeof(*lundata)))) {
7309 alloc_len = list_len + sizeof(*lundata);
7315 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7316 ((list_len / 8) > 1) ? "s" : "");
7321 for (i = 0; i < (list_len / 8); i++) {
7325 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7327 fprintf(stdout, ",");
7328 switch (lundata->luns[i].lundata[j] &
7329 RPL_LUNDATA_ATYP_MASK) {
7330 case RPL_LUNDATA_ATYP_PERIPH:
7331 if ((lundata->luns[i].lundata[j] &
7332 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7333 fprintf(stdout, "%d:",
7334 lundata->luns[i].lundata[j] &
7335 RPL_LUNDATA_PERIPH_BUS_MASK);
7337 && ((lundata->luns[i].lundata[j+2] &
7338 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7341 fprintf(stdout, "%d",
7342 lundata->luns[i].lundata[j+1]);
7344 case RPL_LUNDATA_ATYP_FLAT: {
7346 tmplun[0] = lundata->luns[i].lundata[j] &
7347 RPL_LUNDATA_FLAT_LUN_MASK;
7348 tmplun[1] = lundata->luns[i].lundata[j+1];
7350 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7354 case RPL_LUNDATA_ATYP_LUN:
7355 fprintf(stdout, "%d:%d:%d",
7356 (lundata->luns[i].lundata[j+1] &
7357 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7358 lundata->luns[i].lundata[j] &
7359 RPL_LUNDATA_LUN_TARG_MASK,
7360 lundata->luns[i].lundata[j+1] &
7361 RPL_LUNDATA_LUN_LUN_MASK);
7363 case RPL_LUNDATA_ATYP_EXTLUN: {
7364 int field_len_code, eam_code;
7366 eam_code = lundata->luns[i].lundata[j] &
7367 RPL_LUNDATA_EXT_EAM_MASK;
7368 field_len_code = (lundata->luns[i].lundata[j] &
7369 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7371 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7372 && (field_len_code == 0x00)) {
7373 fprintf(stdout, "%d",
7374 lundata->luns[i].lundata[j+1]);
7375 } else if ((eam_code ==
7376 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7377 && (field_len_code == 0x03)) {
7381 * This format takes up all 8 bytes.
7382 * If we aren't starting at offset 0,
7386 fprintf(stdout, "Invalid "
7389 "specified format", j);
7393 bzero(tmp_lun, sizeof(tmp_lun));
7394 bcopy(&lundata->luns[i].lundata[j+1],
7395 &tmp_lun[1], sizeof(tmp_lun) - 1);
7396 fprintf(stdout, "%#jx",
7397 (intmax_t)scsi_8btou64(tmp_lun));
7400 fprintf(stderr, "Unknown Extended LUN"
7401 "Address method %#x, length "
7402 "code %#x", eam_code,
7409 fprintf(stderr, "Unknown LUN address method "
7410 "%#x\n", lundata->luns[i].lundata[0] &
7411 RPL_LUNDATA_ATYP_MASK);
7415 * For the flat addressing method, there are no
7416 * other levels after it.
7421 fprintf(stdout, "\n");
7434 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7435 char *combinedopt, int task_attr, int retry_count, int timeout)
7438 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7439 struct scsi_read_capacity_data rcap;
7440 struct scsi_read_capacity_data_long rcaplong;
7455 ccb = cam_getccb(device);
7458 warnx("%s: error allocating ccb", __func__);
7462 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7464 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7494 if ((blocksizeonly != 0)
7495 && (numblocks != 0)) {
7496 warnx("%s: you can only specify one of -b or -N", __func__);
7501 if ((blocksizeonly != 0)
7502 && (sizeonly != 0)) {
7503 warnx("%s: you can only specify one of -b or -s", __func__);
7510 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7516 && (blocksizeonly != 0)) {
7517 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7525 scsi_read_capacity(&ccb->csio,
7526 /*retries*/ retry_count,
7528 /*tag_action*/ task_attr,
7531 /*timeout*/ timeout ? timeout : 5000);
7533 /* Disable freezing the device queue */
7534 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7536 if (arglist & CAM_ARG_ERR_RECOVER)
7537 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7539 if (cam_send_ccb(device, ccb) < 0) {
7540 warn("error sending READ CAPACITY command");
7545 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7546 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7551 maxsector = scsi_4btoul(rcap.addr);
7552 block_len = scsi_4btoul(rcap.length);
7555 * A last block of 2^32-1 means that the true capacity is over 2TB,
7556 * and we need to issue the long READ CAPACITY to get the real
7557 * capacity. Otherwise, we're all set.
7559 if (maxsector != 0xffffffff)
7563 scsi_read_capacity_16(&ccb->csio,
7564 /*retries*/ retry_count,
7566 /*tag_action*/ task_attr,
7570 /*rcap_buf*/ (uint8_t *)&rcaplong,
7571 /*rcap_buf_len*/ sizeof(rcaplong),
7572 /*sense_len*/ SSD_FULL_SIZE,
7573 /*timeout*/ timeout ? timeout : 5000);
7575 /* Disable freezing the device queue */
7576 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7578 if (arglist & CAM_ARG_ERR_RECOVER)
7579 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7581 if (cam_send_ccb(device, ccb) < 0) {
7582 warn("error sending READ CAPACITY (16) command");
7587 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7588 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7593 maxsector = scsi_8btou64(rcaplong.addr);
7594 block_len = scsi_4btoul(rcaplong.length);
7597 if (blocksizeonly == 0) {
7599 * Humanize implies !quiet, and also implies numblocks.
7601 if (humanize != 0) {
7606 tmpbytes = (maxsector + 1) * block_len;
7607 ret = humanize_number(tmpstr, sizeof(tmpstr),
7608 tmpbytes, "", HN_AUTOSCALE,
7611 HN_DIVISOR_1000 : 0));
7613 warnx("%s: humanize_number failed!", __func__);
7617 fprintf(stdout, "Device Size: %s%s", tmpstr,
7618 (sizeonly == 0) ? ", " : "\n");
7619 } else if (numblocks != 0) {
7620 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7621 "Blocks: " : "", (uintmax_t)maxsector + 1,
7622 (sizeonly == 0) ? ", " : "\n");
7624 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7625 "Last Block: " : "", (uintmax_t)maxsector,
7626 (sizeonly == 0) ? ", " : "\n");
7630 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7631 "Block Length: " : "", block_len, (quiet == 0) ?
7640 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7641 int retry_count, int timeout)
7645 uint8_t *smp_request = NULL, *smp_response = NULL;
7646 int request_size = 0, response_size = 0;
7647 int fd_request = 0, fd_response = 0;
7648 char *datastr = NULL;
7649 struct get_hook hook;
7654 * Note that at the moment we don't support sending SMP CCBs to
7655 * devices that aren't probed by CAM.
7657 ccb = cam_getccb(device);
7659 warnx("%s: error allocating CCB", __func__);
7663 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7665 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7668 arglist |= CAM_ARG_CMD_IN;
7669 response_size = strtol(optarg, NULL, 0);
7670 if (response_size <= 0) {
7671 warnx("invalid number of response bytes %d",
7674 goto smpcmd_bailout;
7676 hook.argc = argc - optind;
7677 hook.argv = argv + optind;
7680 datastr = cget(&hook, NULL);
7682 * If the user supplied "-" instead of a format, he
7683 * wants the data to be written to stdout.
7685 if ((datastr != NULL)
7686 && (datastr[0] == '-'))
7689 smp_response = (u_int8_t *)malloc(response_size);
7690 if (smp_response == NULL) {
7691 warn("can't malloc memory for SMP response");
7693 goto smpcmd_bailout;
7697 arglist |= CAM_ARG_CMD_OUT;
7698 request_size = strtol(optarg, NULL, 0);
7699 if (request_size <= 0) {
7700 warnx("invalid number of request bytes %d",
7703 goto smpcmd_bailout;
7705 hook.argc = argc - optind;
7706 hook.argv = argv + optind;
7708 datastr = cget(&hook, NULL);
7709 smp_request = (u_int8_t *)malloc(request_size);
7710 if (smp_request == NULL) {
7711 warn("can't malloc memory for SMP request");
7713 goto smpcmd_bailout;
7715 bzero(smp_request, request_size);
7717 * If the user supplied "-" instead of a format, he
7718 * wants the data to be read from stdin.
7720 if ((datastr != NULL)
7721 && (datastr[0] == '-'))
7724 buff_encode_visit(smp_request, request_size,
7735 * If fd_data is set, and we're writing to the device, we need to
7736 * read the data the user wants written from stdin.
7738 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7740 int amt_to_read = request_size;
7741 u_int8_t *buf_ptr = smp_request;
7743 for (amt_read = 0; amt_to_read > 0;
7744 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7745 if (amt_read == -1) {
7746 warn("error reading data from stdin");
7748 goto smpcmd_bailout;
7750 amt_to_read -= amt_read;
7751 buf_ptr += amt_read;
7755 if (((arglist & CAM_ARG_CMD_IN) == 0)
7756 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7757 warnx("%s: need both the request (-r) and response (-R) "
7758 "arguments", __func__);
7760 goto smpcmd_bailout;
7763 flags |= CAM_DEV_QFRZDIS;
7765 cam_fill_smpio(&ccb->smpio,
7766 /*retries*/ retry_count,
7769 /*smp_request*/ smp_request,
7770 /*smp_request_len*/ request_size,
7771 /*smp_response*/ smp_response,
7772 /*smp_response_len*/ response_size,
7773 /*timeout*/ timeout ? timeout : 5000);
7775 ccb->smpio.flags = SMP_FLAG_NONE;
7777 if (((retval = cam_send_ccb(device, ccb)) < 0)
7778 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7779 const char warnstr[] = "error sending command";
7786 if (arglist & CAM_ARG_VERBOSE) {
7787 cam_error_print(device, ccb, CAM_ESF_ALL,
7788 CAM_EPF_ALL, stderr);
7792 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7793 && (response_size > 0)) {
7794 if (fd_response == 0) {
7795 buff_decode_visit(smp_response, response_size,
7796 datastr, arg_put, NULL);
7797 fprintf(stdout, "\n");
7799 ssize_t amt_written;
7800 int amt_to_write = response_size;
7801 u_int8_t *buf_ptr = smp_response;
7803 for (amt_written = 0; (amt_to_write > 0) &&
7804 (amt_written = write(STDOUT_FILENO, buf_ptr,
7805 amt_to_write)) > 0;){
7806 amt_to_write -= amt_written;
7807 buf_ptr += amt_written;
7809 if (amt_written == -1) {
7810 warn("error writing data to stdout");
7812 goto smpcmd_bailout;
7813 } else if ((amt_written == 0)
7814 && (amt_to_write > 0)) {
7815 warnx("only wrote %u bytes out of %u",
7816 response_size - amt_to_write,
7825 if (smp_request != NULL)
7828 if (smp_response != NULL)
7835 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7836 int retry_count, int timeout)
7840 int32_t mmc_opcode = 0, mmc_arg = 0;
7841 int32_t mmc_flags = -1;
7844 int is_bw_4 = 0, is_bw_1 = 0;
7845 int is_highspeed = 0, is_stdspeed = 0;
7846 int is_info_request = 0;
7848 uint8_t mmc_data_byte = 0;
7850 /* For IO_RW_EXTENDED command */
7851 uint8_t *mmc_data = NULL;
7852 struct mmc_data mmc_d;
7853 int mmc_data_len = 0;
7856 * Note that at the moment we don't support sending SMP CCBs to
7857 * devices that aren't probed by CAM.
7859 ccb = cam_getccb(device);
7861 warnx("%s: error allocating CCB", __func__);
7865 bzero(&(&ccb->ccb_h)[1],
7866 sizeof(union ccb) - sizeof(struct ccb_hdr));
7868 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7877 if (!strcmp(optarg, "high"))
7883 is_info_request = 1;
7886 mmc_opcode = strtol(optarg, NULL, 0);
7887 if (mmc_opcode < 0) {
7888 warnx("invalid MMC opcode %d",
7891 goto mmccmd_bailout;
7895 mmc_arg = strtol(optarg, NULL, 0);
7897 warnx("invalid MMC arg %d",
7900 goto mmccmd_bailout;
7904 mmc_flags = strtol(optarg, NULL, 0);
7905 if (mmc_flags < 0) {
7906 warnx("invalid MMC flags %d",
7909 goto mmccmd_bailout;
7913 mmc_data_len = strtol(optarg, NULL, 0);
7914 if (mmc_data_len <= 0) {
7915 warnx("invalid MMC data len %d",
7918 goto mmccmd_bailout;
7925 mmc_data_byte = strtol(optarg, NULL, 0);
7931 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7933 /* If flags are left default, supply the right flags */
7935 switch (mmc_opcode) {
7936 case MMC_GO_IDLE_STATE:
7937 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7939 case IO_SEND_OP_COND:
7940 mmc_flags = MMC_RSP_R4;
7942 case SD_SEND_RELATIVE_ADDR:
7943 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7945 case MMC_SELECT_CARD:
7946 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7947 mmc_arg = mmc_arg << 16;
7949 case SD_IO_RW_DIRECT:
7950 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7951 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7953 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7955 case SD_IO_RW_EXTENDED:
7956 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7957 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7958 int len_arg = mmc_data_len;
7959 if (mmc_data_len == 512)
7963 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7965 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7968 mmc_flags = MMC_RSP_R1;
7972 // Switch bus width instead of sending IO command
7973 if (is_bw_4 || is_bw_1) {
7974 struct ccb_trans_settings_mmc *cts;
7975 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7976 ccb->ccb_h.flags = 0;
7977 cts = &ccb->cts.proto_specific.mmc;
7978 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7979 cts->ios_valid = MMC_BW;
7980 if (((retval = cam_send_ccb(device, ccb)) < 0)
7981 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7982 warn("Error sending command");
7984 printf("Parameters set OK\n");
7990 // Switch bus speed instead of sending IO command
7991 if (is_stdspeed || is_highspeed) {
7992 struct ccb_trans_settings_mmc *cts;
7993 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7994 ccb->ccb_h.flags = 0;
7995 cts = &ccb->cts.proto_specific.mmc;
7996 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
7997 cts->ios_valid = MMC_BT;
7998 if (((retval = cam_send_ccb(device, ccb)) < 0)
7999 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8000 warn("Error sending command");
8002 printf("Speed set OK (HS: %d)\n", is_highspeed);
8008 // Get information about controller and its settings
8009 if (is_info_request) {
8010 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
8011 ccb->ccb_h.flags = 0;
8012 struct ccb_trans_settings_mmc *cts;
8013 cts = &ccb->cts.proto_specific.mmc;
8014 if (((retval = cam_send_ccb(device, ccb)) < 0)
8015 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8016 warn("Error sending command");
8019 printf("Host controller information\n");
8020 printf("Host OCR: 0x%x\n", cts->host_ocr);
8021 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
8022 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
8023 printf("Supported bus width: ");
8024 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
8026 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
8028 printf("\nCurrent settings:\n");
8029 printf("Bus width: ");
8030 switch (cts->ios.bus_width) {
8041 printf("Freq: %d.%03d MHz%s\n",
8042 cts->ios.clock / 1000000,
8043 (cts->ios.clock / 1000) % 1000,
8044 cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : "");
8048 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
8050 if (mmc_data_len > 0) {
8051 flags |= CAM_DIR_IN;
8052 mmc_data = malloc(mmc_data_len);
8053 memset(mmc_data, 0, mmc_data_len);
8054 mmc_d.len = mmc_data_len;
8055 mmc_d.data = mmc_data;
8056 mmc_d.flags = MMC_DATA_READ;
8057 } else flags |= CAM_DIR_NONE;
8059 cam_fill_mmcio(&ccb->mmcio,
8060 /*retries*/ retry_count,
8063 /*mmc_opcode*/ mmc_opcode,
8064 /*mmc_arg*/ mmc_arg,
8065 /*mmc_flags*/ mmc_flags,
8066 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
8067 /*timeout*/ timeout ? timeout : 5000);
8069 if (((retval = cam_send_ccb(device, ccb)) < 0)
8070 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8071 const char warnstr[] = "error sending command";
8078 if (arglist & CAM_ARG_VERBOSE) {
8079 cam_error_print(device, ccb, CAM_ESF_ALL,
8080 CAM_EPF_ALL, stderr);
8084 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
8085 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
8086 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
8087 ccb->mmcio.cmd.resp[1],
8088 ccb->mmcio.cmd.resp[2],
8089 ccb->mmcio.cmd.resp[3]);
8091 switch (mmc_opcode) {
8092 case SD_IO_RW_DIRECT:
8093 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
8094 SD_R5_DATA(ccb->mmcio.cmd.resp),
8095 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
8097 case SD_IO_RW_EXTENDED:
8098 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
8099 hexdump(mmc_data, mmc_data_len, NULL, 0);
8101 case SD_SEND_RELATIVE_ADDR:
8102 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
8105 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
8112 if (mmc_data_len > 0 && mmc_data != NULL)
8119 smpreportgeneral(struct cam_device *device, int argc, char **argv,
8120 char *combinedopt, int retry_count, int timeout)
8123 struct smp_report_general_request *request = NULL;
8124 struct smp_report_general_response *response = NULL;
8125 struct sbuf *sb = NULL;
8127 int c, long_response = 0;
8131 * Note that at the moment we don't support sending SMP CCBs to
8132 * devices that aren't probed by CAM.
8134 ccb = cam_getccb(device);
8136 warnx("%s: error allocating CCB", __func__);
8140 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8142 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8151 request = malloc(sizeof(*request));
8152 if (request == NULL) {
8153 warn("%s: unable to allocate %zd bytes", __func__,
8159 response = malloc(sizeof(*response));
8160 if (response == NULL) {
8161 warn("%s: unable to allocate %zd bytes", __func__,
8168 smp_report_general(&ccb->smpio,
8172 /*request_len*/ sizeof(*request),
8173 (uint8_t *)response,
8174 /*response_len*/ sizeof(*response),
8175 /*long_response*/ long_response,
8178 if (((retval = cam_send_ccb(device, ccb)) < 0)
8179 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8180 const char warnstr[] = "error sending command";
8187 if (arglist & CAM_ARG_VERBOSE) {
8188 cam_error_print(device, ccb, CAM_ESF_ALL,
8189 CAM_EPF_ALL, stderr);
8196 * If the device supports the long response bit, try again and see
8197 * if we can get all of the data.
8199 if ((response->long_response & SMP_RG_LONG_RESPONSE)
8200 && (long_response == 0)) {
8201 ccb->ccb_h.status = CAM_REQ_INPROG;
8202 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8208 * XXX KDM detect and decode SMP errors here.
8210 sb = sbuf_new_auto();
8212 warnx("%s: error allocating sbuf", __func__);
8216 smp_report_general_sbuf(response, sizeof(*response), sb);
8218 if (sbuf_finish(sb) != 0) {
8219 warnx("%s: sbuf_finish", __func__);
8223 printf("%s", sbuf_data(sb));
8229 if (request != NULL)
8232 if (response != NULL)
8241 static struct camcontrol_opts phy_ops[] = {
8242 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
8243 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
8244 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
8245 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
8246 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
8247 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
8248 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
8249 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
8250 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
8255 smpphycontrol(struct cam_device *device, int argc, char **argv,
8256 char *combinedopt, int retry_count, int timeout)
8259 struct smp_phy_control_request *request = NULL;
8260 struct smp_phy_control_response *response = NULL;
8261 int long_response = 0;
8264 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
8266 uint64_t attached_dev_name = 0;
8267 int dev_name_set = 0;
8268 uint32_t min_plr = 0, max_plr = 0;
8269 uint32_t pp_timeout_val = 0;
8270 int slumber_partial = 0;
8271 int set_pp_timeout_val = 0;
8275 * Note that at the moment we don't support sending SMP CCBs to
8276 * devices that aren't probed by CAM.
8278 ccb = cam_getccb(device);
8280 warnx("%s: error allocating CCB", __func__);
8284 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8286 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8294 if (strcasecmp(optarg, "enable") == 0)
8296 else if (strcasecmp(optarg, "disable") == 0)
8299 warnx("%s: Invalid argument %s", __func__,
8306 slumber_partial |= enable <<
8307 SMP_PC_SAS_SLUMBER_SHIFT;
8310 slumber_partial |= enable <<
8311 SMP_PC_SAS_PARTIAL_SHIFT;
8314 slumber_partial |= enable <<
8315 SMP_PC_SATA_SLUMBER_SHIFT;
8318 slumber_partial |= enable <<
8319 SMP_PC_SATA_PARTIAL_SHIFT;
8322 warnx("%s: programmer error", __func__);
8325 break; /*NOTREACHED*/
8330 attached_dev_name = (uintmax_t)strtoumax(optarg,
8339 * We don't do extensive checking here, so this
8340 * will continue to work when new speeds come out.
8342 min_plr = strtoul(optarg, NULL, 0);
8344 || (min_plr > 0xf)) {
8345 warnx("%s: invalid link rate %x",
8353 * We don't do extensive checking here, so this
8354 * will continue to work when new speeds come out.
8356 max_plr = strtoul(optarg, NULL, 0);
8358 || (max_plr > 0xf)) {
8359 warnx("%s: invalid link rate %x",
8366 camcontrol_optret optreturn;
8367 cam_argmask argnums;
8370 if (phy_op_set != 0) {
8371 warnx("%s: only one phy operation argument "
8372 "(-o) allowed", __func__);
8380 * Allow the user to specify the phy operation
8381 * numerically, as well as with a name. This will
8382 * future-proof it a bit, so options that are added
8383 * in future specs can be used.
8385 if (isdigit(optarg[0])) {
8386 phy_operation = strtoul(optarg, NULL, 0);
8387 if ((phy_operation == 0)
8388 || (phy_operation > 0xff)) {
8389 warnx("%s: invalid phy operation %#x",
8390 __func__, phy_operation);
8396 optreturn = getoption(phy_ops, optarg, &phy_operation,
8399 if (optreturn == CC_OR_AMBIGUOUS) {
8400 warnx("%s: ambiguous option %s", __func__,
8405 } else if (optreturn == CC_OR_NOT_FOUND) {
8406 warnx("%s: option %s not found", __func__,
8418 pp_timeout_val = strtoul(optarg, NULL, 0);
8419 if (pp_timeout_val > 15) {
8420 warnx("%s: invalid partial pathway timeout "
8421 "value %u, need a value less than 16",
8422 __func__, pp_timeout_val);
8426 set_pp_timeout_val = 1;
8434 warnx("%s: a PHY (-p phy) argument is required",__func__);
8439 if (((dev_name_set != 0)
8440 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8441 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8442 && (dev_name_set == 0))) {
8443 warnx("%s: -d name and -o setdevname arguments both "
8444 "required to set device name", __func__);
8449 request = malloc(sizeof(*request));
8450 if (request == NULL) {
8451 warn("%s: unable to allocate %zd bytes", __func__,
8457 response = malloc(sizeof(*response));
8458 if (response == NULL) {
8459 warn("%s: unable to allocate %zd bytes", __func__,
8465 smp_phy_control(&ccb->smpio,
8470 (uint8_t *)response,
8473 /*expected_exp_change_count*/ 0,
8476 (set_pp_timeout_val != 0) ? 1 : 0,
8484 if (((retval = cam_send_ccb(device, ccb)) < 0)
8485 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8486 const char warnstr[] = "error sending command";
8493 if (arglist & CAM_ARG_VERBOSE) {
8495 * Use CAM_EPF_NORMAL so we only get one line of
8496 * SMP command decoding.
8498 cam_error_print(device, ccb, CAM_ESF_ALL,
8499 CAM_EPF_NORMAL, stderr);
8505 /* XXX KDM print out something here for success? */
8510 if (request != NULL)
8513 if (response != NULL)
8520 smpmaninfo(struct cam_device *device, int argc, char **argv,
8521 char *combinedopt, int retry_count, int timeout)
8524 struct smp_report_manuf_info_request request;
8525 struct smp_report_manuf_info_response response;
8526 struct sbuf *sb = NULL;
8527 int long_response = 0;
8532 * Note that at the moment we don't support sending SMP CCBs to
8533 * devices that aren't probed by CAM.
8535 ccb = cam_getccb(device);
8537 warnx("%s: error allocating CCB", __func__);
8541 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8543 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8552 bzero(&request, sizeof(request));
8553 bzero(&response, sizeof(response));
8555 smp_report_manuf_info(&ccb->smpio,
8560 (uint8_t *)&response,
8565 if (((retval = cam_send_ccb(device, ccb)) < 0)
8566 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8567 const char warnstr[] = "error sending command";
8574 if (arglist & CAM_ARG_VERBOSE) {
8575 cam_error_print(device, ccb, CAM_ESF_ALL,
8576 CAM_EPF_ALL, stderr);
8582 sb = sbuf_new_auto();
8584 warnx("%s: error allocating sbuf", __func__);
8588 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8590 if (sbuf_finish(sb) != 0) {
8591 warnx("%s: sbuf_finish", __func__);
8595 printf("%s", sbuf_data(sb));
8609 getdevid(struct cam_devitem *item)
8612 union ccb *ccb = NULL;
8614 struct cam_device *dev;
8616 dev = cam_open_btl(item->dev_match.path_id,
8617 item->dev_match.target_id,
8618 item->dev_match.target_lun, O_RDWR, NULL);
8621 warnx("%s", cam_errbuf);
8626 item->device_id_len = 0;
8628 ccb = cam_getccb(dev);
8630 warnx("%s: error allocating CCB", __func__);
8635 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8638 * On the first try, we just probe for the size of the data, and
8639 * then allocate that much memory and try again.
8642 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8643 ccb->ccb_h.flags = CAM_DIR_IN;
8644 ccb->cdai.flags = CDAI_FLAG_NONE;
8645 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8646 ccb->cdai.bufsiz = item->device_id_len;
8647 if (item->device_id_len != 0)
8648 ccb->cdai.buf = (uint8_t *)item->device_id;
8650 if (cam_send_ccb(dev, ccb) < 0) {
8651 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8656 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8657 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8662 if (item->device_id_len == 0) {
8664 * This is our first time through. Allocate the buffer,
8665 * and then go back to get the data.
8667 if (ccb->cdai.provsiz == 0) {
8668 warnx("%s: invalid .provsiz field returned with "
8669 "XPT_GDEV_ADVINFO CCB", __func__);
8673 item->device_id_len = ccb->cdai.provsiz;
8674 item->device_id = malloc(item->device_id_len);
8675 if (item->device_id == NULL) {
8676 warn("%s: unable to allocate %d bytes", __func__,
8677 item->device_id_len);
8681 ccb->ccb_h.status = CAM_REQ_INPROG;
8687 cam_close_device(dev);
8696 * XXX KDM merge this code with getdevtree()?
8699 buildbusdevlist(struct cam_devlist *devlist)
8702 int bufsize, fd = -1;
8703 struct dev_match_pattern *patterns;
8704 struct cam_devitem *item = NULL;
8705 int skip_device = 0;
8708 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8709 warn("couldn't open %s", XPT_DEVICE);
8713 bzero(&ccb, sizeof(union ccb));
8715 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8716 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8717 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8719 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8720 bufsize = sizeof(struct dev_match_result) * 100;
8721 ccb.cdm.match_buf_len = bufsize;
8722 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8723 if (ccb.cdm.matches == NULL) {
8724 warnx("can't malloc memory for matches");
8728 ccb.cdm.num_matches = 0;
8729 ccb.cdm.num_patterns = 2;
8730 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8731 ccb.cdm.num_patterns;
8733 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8734 if (patterns == NULL) {
8735 warnx("can't malloc memory for patterns");
8740 ccb.cdm.patterns = patterns;
8741 bzero(patterns, ccb.cdm.pattern_buf_len);
8743 patterns[0].type = DEV_MATCH_DEVICE;
8744 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8745 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8746 patterns[1].type = DEV_MATCH_PERIPH;
8747 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8748 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8751 * We do the ioctl multiple times if necessary, in case there are
8752 * more than 100 nodes in the EDT.
8757 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8758 warn("error sending CAMIOCOMMAND ioctl");
8763 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8764 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8765 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8766 warnx("got CAM error %#x, CDM error %d\n",
8767 ccb.ccb_h.status, ccb.cdm.status);
8772 for (i = 0; i < ccb.cdm.num_matches; i++) {
8773 switch (ccb.cdm.matches[i].type) {
8774 case DEV_MATCH_DEVICE: {
8775 struct device_match_result *dev_result;
8778 &ccb.cdm.matches[i].result.device_result;
8780 if (dev_result->flags &
8781 DEV_RESULT_UNCONFIGURED) {
8787 item = malloc(sizeof(*item));
8789 warn("%s: unable to allocate %zd bytes",
8790 __func__, sizeof(*item));
8794 bzero(item, sizeof(*item));
8795 bcopy(dev_result, &item->dev_match,
8796 sizeof(*dev_result));
8797 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8800 if (getdevid(item) != 0) {
8806 case DEV_MATCH_PERIPH: {
8807 struct periph_match_result *periph_result;
8810 &ccb.cdm.matches[i].result.periph_result;
8812 if (skip_device != 0)
8814 item->num_periphs++;
8815 item->periph_matches = realloc(
8816 item->periph_matches,
8818 sizeof(struct periph_match_result));
8819 if (item->periph_matches == NULL) {
8820 warn("%s: error allocating periph "
8825 bcopy(periph_result, &item->periph_matches[
8826 item->num_periphs - 1],
8827 sizeof(*periph_result));
8831 fprintf(stderr, "%s: unexpected match "
8832 "type %d\n", __func__,
8833 ccb.cdm.matches[i].type);
8836 break; /*NOTREACHED*/
8839 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8840 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8848 free(ccb.cdm.matches);
8851 freebusdevlist(devlist);
8857 freebusdevlist(struct cam_devlist *devlist)
8859 struct cam_devitem *item, *item2;
8861 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8862 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8864 free(item->device_id);
8865 free(item->periph_matches);
8870 static struct cam_devitem *
8871 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8873 struct cam_devitem *item;
8875 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8876 struct scsi_vpd_id_descriptor *idd;
8879 * XXX KDM look for LUN IDs as well?
8881 idd = scsi_get_devid(item->device_id,
8882 item->device_id_len,
8883 scsi_devid_is_sas_target);
8887 if (scsi_8btou64(idd->identifier) == sasaddr)
8895 smpphylist(struct cam_device *device, int argc, char **argv,
8896 char *combinedopt, int retry_count, int timeout)
8898 struct smp_report_general_request *rgrequest = NULL;
8899 struct smp_report_general_response *rgresponse = NULL;
8900 struct smp_discover_request *disrequest = NULL;
8901 struct smp_discover_response *disresponse = NULL;
8902 struct cam_devlist devlist;
8904 int long_response = 0;
8911 * Note that at the moment we don't support sending SMP CCBs to
8912 * devices that aren't probed by CAM.
8914 ccb = cam_getccb(device);
8916 warnx("%s: error allocating CCB", __func__);
8920 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8921 STAILQ_INIT(&devlist.dev_queue);
8923 rgrequest = malloc(sizeof(*rgrequest));
8924 if (rgrequest == NULL) {
8925 warn("%s: unable to allocate %zd bytes", __func__,
8926 sizeof(*rgrequest));
8931 rgresponse = malloc(sizeof(*rgresponse));
8932 if (rgresponse == NULL) {
8933 warn("%s: unable to allocate %zd bytes", __func__,
8934 sizeof(*rgresponse));
8939 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8952 smp_report_general(&ccb->smpio,
8956 /*request_len*/ sizeof(*rgrequest),
8957 (uint8_t *)rgresponse,
8958 /*response_len*/ sizeof(*rgresponse),
8959 /*long_response*/ long_response,
8962 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8964 if (((retval = cam_send_ccb(device, ccb)) < 0)
8965 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8966 const char warnstr[] = "error sending command";
8973 if (arglist & CAM_ARG_VERBOSE) {
8974 cam_error_print(device, ccb, CAM_ESF_ALL,
8975 CAM_EPF_ALL, stderr);
8981 num_phys = rgresponse->num_phys;
8983 if (num_phys == 0) {
8985 fprintf(stdout, "%s: No Phys reported\n", __func__);
8990 devlist.path_id = device->path_id;
8992 retval = buildbusdevlist(&devlist);
8997 fprintf(stdout, "%d PHYs:\n", num_phys);
8998 fprintf(stdout, "PHY Attached SAS Address\n");
9001 disrequest = malloc(sizeof(*disrequest));
9002 if (disrequest == NULL) {
9003 warn("%s: unable to allocate %zd bytes", __func__,
9004 sizeof(*disrequest));
9009 disresponse = malloc(sizeof(*disresponse));
9010 if (disresponse == NULL) {
9011 warn("%s: unable to allocate %zd bytes", __func__,
9012 sizeof(*disresponse));
9017 for (i = 0; i < num_phys; i++) {
9018 struct cam_devitem *item;
9019 struct device_match_result *dev_match;
9020 char vendor[16], product[48], revision[16];
9024 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
9026 ccb->ccb_h.status = CAM_REQ_INPROG;
9027 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9029 smp_discover(&ccb->smpio,
9033 sizeof(*disrequest),
9034 (uint8_t *)disresponse,
9035 sizeof(*disresponse),
9037 /*ignore_zone_group*/ 0,
9041 if (((retval = cam_send_ccb(device, ccb)) < 0)
9042 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
9043 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
9044 const char warnstr[] = "error sending command";
9051 if (arglist & CAM_ARG_VERBOSE) {
9052 cam_error_print(device, ccb, CAM_ESF_ALL,
9053 CAM_EPF_ALL, stderr);
9059 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
9061 fprintf(stdout, "%3d <vacant>\n", i);
9065 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
9068 item = findsasdevice(&devlist,
9069 scsi_8btou64(disresponse->attached_sas_address));
9073 || (item != NULL)) {
9074 fprintf(stdout, "%3d 0x%016jx", i,
9075 (uintmax_t)scsi_8btou64(
9076 disresponse->attached_sas_address));
9078 fprintf(stdout, "\n");
9081 } else if (quiet != 0)
9084 dev_match = &item->dev_match;
9086 if (dev_match->protocol == PROTO_SCSI) {
9087 cam_strvis(vendor, dev_match->inq_data.vendor,
9088 sizeof(dev_match->inq_data.vendor),
9090 cam_strvis(product, dev_match->inq_data.product,
9091 sizeof(dev_match->inq_data.product),
9093 cam_strvis(revision, dev_match->inq_data.revision,
9094 sizeof(dev_match->inq_data.revision),
9096 sprintf(tmpstr, "<%s %s %s>", vendor, product,
9098 } else if ((dev_match->protocol == PROTO_ATA)
9099 || (dev_match->protocol == PROTO_SATAPM)) {
9100 cam_strvis(product, dev_match->ident_data.model,
9101 sizeof(dev_match->ident_data.model),
9103 cam_strvis(revision, dev_match->ident_data.revision,
9104 sizeof(dev_match->ident_data.revision),
9106 sprintf(tmpstr, "<%s %s>", product, revision);
9108 sprintf(tmpstr, "<>");
9110 fprintf(stdout, " %-33s ", tmpstr);
9113 * If we have 0 periphs, that's a bug...
9115 if (item->num_periphs == 0) {
9116 fprintf(stdout, "\n");
9120 fprintf(stdout, "(");
9121 for (j = 0; j < item->num_periphs; j++) {
9123 fprintf(stdout, ",");
9125 fprintf(stdout, "%s%d",
9126 item->periph_matches[j].periph_name,
9127 item->periph_matches[j].unit_number);
9130 fprintf(stdout, ")\n");
9144 freebusdevlist(&devlist);
9150 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
9152 uint8_t error = 0, ata_device = 0, status = 0;
9157 retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
9160 if (arglist & CAM_ARG_VERBOSE) {
9161 cam_error_print(device, ccb, CAM_ESF_ALL,
9162 CAM_EPF_ALL, stderr);
9164 warnx("Can't get ATA command status");
9168 if (status & ATA_STATUS_ERROR) {
9169 cam_error_print(device, ccb, CAM_ESF_ALL,
9170 CAM_EPF_ALL, stderr);
9174 printf("%s%d: ", device->device_name, device->dev_unit_num);
9177 printf("Standby mode\n");
9180 printf("Standby_y mode\n");
9183 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
9186 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
9189 printf("Idle mode\n");
9192 printf("Idle_a mode\n");
9195 printf("Idle_b mode\n");
9198 printf("Idle_c mode\n");
9201 printf("Active or Idle mode\n");
9204 printf("Unknown mode 0x%02x\n", count);
9212 atapm(struct cam_device *device, int argc, char **argv,
9213 char *combinedopt, int retry_count, int timeout)
9219 u_int8_t ata_flags = 0;
9222 ccb = cam_getccb(device);
9225 warnx("%s: error allocating ccb", __func__);
9229 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9238 if (strcmp(argv[1], "idle") == 0) {
9240 cmd = ATA_IDLE_IMMEDIATE;
9243 } else if (strcmp(argv[1], "standby") == 0) {
9245 cmd = ATA_STANDBY_IMMEDIATE;
9247 cmd = ATA_STANDBY_CMD;
9248 } else if (strcmp(argv[1], "powermode") == 0) {
9249 cmd = ATA_CHECK_POWER_MODE;
9250 ata_flags = AP_FLAG_CHK_COND;
9259 else if (t <= (240 * 5))
9261 else if (t <= (252 * 5))
9262 /* special encoding for 21 minutes */
9264 else if (t <= (11 * 30 * 60))
9265 sc = (t - 1) / (30 * 60) + 241;
9269 retval = ata_do_cmd(device,
9271 /*retries*/retry_count,
9272 /*flags*/CAM_DIR_NONE,
9273 /*protocol*/AP_PROTO_NON_DATA,
9274 /*ata_flags*/ata_flags,
9275 /*tag_action*/MSG_SIMPLE_Q_TAG,
9282 /*timeout*/timeout ? timeout : 30 * 1000,
9287 if (retval || cmd != ATA_CHECK_POWER_MODE)
9290 return (atapm_proc_resp(device, ccb));
9294 ataaxm(struct cam_device *device, int argc, char **argv,
9295 char *combinedopt, int retry_count, int timeout)
9303 ccb = cam_getccb(device);
9306 warnx("%s: error allocating ccb", __func__);
9310 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9320 if (strcmp(argv[1], "apm") == 0) {
9336 retval = ata_do_cmd(device,
9338 /*retries*/retry_count,
9339 /*flags*/CAM_DIR_NONE,
9340 /*protocol*/AP_PROTO_NON_DATA,
9342 /*tag_action*/MSG_SIMPLE_Q_TAG,
9343 /*command*/ATA_SETFEATURES,
9349 /*timeout*/timeout ? timeout : 30 * 1000,
9357 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9358 int show_sa_errors, int sa_set, int service_action,
9359 int timeout_desc, int task_attr, int retry_count, int timeout,
9360 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9362 union ccb *ccb = NULL;
9363 uint8_t *buf = NULL;
9364 uint32_t alloc_len = 0, num_opcodes;
9365 uint32_t valid_len = 0;
9366 uint32_t avail_len = 0;
9367 struct scsi_report_supported_opcodes_all *all_hdr;
9368 struct scsi_report_supported_opcodes_one *one;
9373 * Make it clear that we haven't yet allocated or filled anything.
9378 ccb = cam_getccb(device);
9380 warnx("couldn't allocate CCB");
9385 /* cam_getccb cleans up the header, caller has to zero the payload */
9386 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9388 if (opcode_set != 0) {
9389 options |= RSO_OPTIONS_OC;
9391 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9394 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9395 sizeof(struct scsi_report_supported_opcodes_descr));
9398 if (timeout_desc != 0) {
9399 options |= RSO_RCTD;
9400 alloc_len += num_opcodes *
9401 sizeof(struct scsi_report_supported_opcodes_timeout);
9405 options |= RSO_OPTIONS_OC_SA;
9406 if (show_sa_errors != 0)
9407 options &= ~RSO_OPTIONS_OC;
9416 buf = malloc(alloc_len);
9418 warn("Unable to allocate %u bytes", alloc_len);
9422 bzero(buf, alloc_len);
9424 scsi_report_supported_opcodes(&ccb->csio,
9425 /*retries*/ retry_count,
9427 /*tag_action*/ task_attr,
9428 /*options*/ options,
9429 /*req_opcode*/ opcode,
9430 /*req_service_action*/ service_action,
9432 /*dxfer_len*/ alloc_len,
9433 /*sense_len*/ SSD_FULL_SIZE,
9434 /*timeout*/ timeout ? timeout : 10000);
9436 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9438 if (retry_count != 0)
9439 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9441 if (cam_send_ccb(device, ccb) < 0) {
9442 warn("error sending REPORT SUPPORTED OPERATION CODES command");
9447 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9448 if (verbosemode != 0)
9449 cam_error_print(device, ccb, CAM_ESF_ALL,
9450 CAM_EPF_ALL, stderr);
9455 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9457 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9458 && (valid_len >= sizeof(*all_hdr))) {
9459 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9460 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9461 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9462 && (valid_len >= sizeof(*one))) {
9463 uint32_t cdb_length;
9465 one = (struct scsi_report_supported_opcodes_one *)buf;
9466 cdb_length = scsi_2btoul(one->cdb_length);
9467 avail_len = sizeof(*one) + cdb_length;
9468 if (one->support & RSO_ONE_CTDP) {
9469 struct scsi_report_supported_opcodes_timeout *td;
9471 td = (struct scsi_report_supported_opcodes_timeout *)
9473 if (valid_len >= (avail_len + sizeof(td->length))) {
9474 avail_len += scsi_2btoul(td->length) +
9477 avail_len += sizeof(*td);
9483 * avail_len could be zero if we didn't get enough data back from
9484 * thet target to determine
9486 if ((avail_len != 0)
9487 && (avail_len > valid_len)) {
9488 alloc_len = avail_len;
9492 *fill_len = valid_len;
9504 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9505 int req_sa, uint8_t *buf, uint32_t valid_len)
9507 struct scsi_report_supported_opcodes_one *one;
9508 struct scsi_report_supported_opcodes_timeout *td;
9509 uint32_t cdb_len = 0, td_len = 0;
9510 const char *op_desc = NULL;
9514 one = (struct scsi_report_supported_opcodes_one *)buf;
9517 * If we don't have the full single opcode descriptor, no point in
9520 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9522 warnx("Only %u bytes returned, not enough to verify support",
9528 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9530 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9533 printf(", SA 0x%x", req_sa);
9536 switch (one->support & RSO_ONE_SUP_MASK) {
9537 case RSO_ONE_SUP_UNAVAIL:
9538 printf("No command support information currently available\n");
9540 case RSO_ONE_SUP_NOT_SUP:
9541 printf("Command not supported\n");
9544 break; /*NOTREACHED*/
9545 case RSO_ONE_SUP_AVAIL:
9546 printf("Command is supported, complies with a SCSI standard\n");
9548 case RSO_ONE_SUP_VENDOR:
9549 printf("Command is supported, vendor-specific "
9550 "implementation\n");
9553 printf("Unknown command support flags 0x%#x\n",
9554 one->support & RSO_ONE_SUP_MASK);
9559 * If we don't have the CDB length, it isn't exactly an error, the
9560 * command probably isn't supported.
9562 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9566 cdb_len = scsi_2btoul(one->cdb_length);
9569 * If our valid data doesn't include the full reported length,
9570 * return. The caller should have detected this and adjusted his
9571 * allocation length to get all of the available data.
9573 if (valid_len < sizeof(*one) + cdb_len) {
9579 * If all we have is the opcode, there is no point in printing out
9587 printf("CDB usage bitmap:");
9588 for (i = 0; i < cdb_len; i++) {
9589 printf(" %02x", one->cdb_usage[i]);
9594 * If we don't have a timeout descriptor, we're done.
9596 if ((one->support & RSO_ONE_CTDP) == 0)
9600 * If we don't have enough valid length to include the timeout
9601 * descriptor length, we're done.
9603 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9606 td = (struct scsi_report_supported_opcodes_timeout *)
9607 &buf[sizeof(*one) + cdb_len];
9608 td_len = scsi_2btoul(td->length);
9609 td_len += sizeof(td->length);
9612 * If we don't have the full timeout descriptor, we're done.
9614 if (td_len < sizeof(*td))
9618 * If we don't have enough valid length to contain the full timeout
9619 * descriptor, we're done.
9621 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9624 printf("Timeout information:\n");
9625 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9626 printf("Nominal timeout: %u seconds\n",
9627 scsi_4btoul(td->nominal_time));
9628 printf("Recommended timeout: %u seconds\n",
9629 scsi_4btoul(td->recommended_time));
9636 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9639 struct scsi_report_supported_opcodes_all *hdr;
9640 struct scsi_report_supported_opcodes_descr *desc;
9641 uint32_t avail_len = 0, used_len = 0;
9645 if (valid_len < sizeof(*hdr)) {
9646 warnx("%s: not enough returned data (%u bytes) opcode list",
9647 __func__, valid_len);
9651 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9652 avail_len = scsi_4btoul(hdr->length);
9653 avail_len += sizeof(hdr->length);
9655 * Take the lesser of the amount of data the drive claims is
9656 * available, and the amount of data the HBA says was returned.
9658 avail_len = MIN(avail_len, valid_len);
9660 used_len = sizeof(hdr->length);
9662 printf("%-6s %4s %8s ",
9663 "Opcode", "SA", "CDB len" );
9666 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9667 printf(" Description\n");
9669 while ((avail_len - used_len) > sizeof(*desc)) {
9670 struct scsi_report_supported_opcodes_timeout *td;
9672 const char *op_desc = NULL;
9674 cur_ptr = &buf[used_len];
9675 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9677 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9678 if (op_desc == NULL)
9679 op_desc = "UNKNOWN";
9681 printf("0x%02x %#4x %8u ", desc->opcode,
9682 scsi_2btoul(desc->service_action),
9683 scsi_2btoul(desc->cdb_length));
9685 used_len += sizeof(*desc);
9687 if ((desc->flags & RSO_CTDP) == 0) {
9688 printf(" %s\n", op_desc);
9693 * If we don't have enough space to fit a timeout
9694 * descriptor, then we're done.
9696 if (avail_len - used_len < sizeof(*td)) {
9697 used_len = avail_len;
9698 printf(" %s\n", op_desc);
9701 cur_ptr = &buf[used_len];
9702 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9703 td_len = scsi_2btoul(td->length);
9704 td_len += sizeof(td->length);
9708 * If the given timeout descriptor length is less than what
9709 * we understand, skip it.
9711 if (td_len < sizeof(*td)) {
9712 printf(" %s\n", op_desc);
9716 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9717 scsi_4btoul(td->nominal_time),
9718 scsi_4btoul(td->recommended_time), op_desc);
9725 scsiopcodes(struct cam_device *device, int argc, char **argv,
9726 char *combinedopt, int task_attr, int retry_count, int timeout,
9730 uint32_t opcode = 0, service_action = 0;
9731 int td_set = 0, opcode_set = 0, sa_set = 0;
9732 int show_sa_errors = 1;
9733 uint32_t valid_len = 0;
9734 uint8_t *buf = NULL;
9738 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9744 opcode = strtoul(optarg, &endptr, 0);
9745 if (*endptr != '\0') {
9746 warnx("Invalid opcode \"%s\", must be a number",
9751 if (opcode > 0xff) {
9752 warnx("Invalid opcode 0x%#x, must be between"
9753 "0 and 0xff inclusive", opcode);
9760 service_action = strtoul(optarg, &endptr, 0);
9761 if (*endptr != '\0') {
9762 warnx("Invalid service action \"%s\", must "
9763 "be a number", optarg);
9767 if (service_action > 0xffff) {
9768 warnx("Invalid service action 0x%#x, must "
9769 "be between 0 and 0xffff inclusive",
9784 && (opcode_set == 0)) {
9785 warnx("You must specify an opcode with -o if a service "
9790 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9791 sa_set, service_action, td_set, task_attr,
9792 retry_count, timeout, verbosemode, &valid_len,
9797 if ((opcode_set != 0)
9799 retval = scsiprintoneopcode(device, opcode, sa_set,
9800 service_action, buf, valid_len);
9802 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9811 #endif /* MINIMALISTIC */
9814 reprobe(struct cam_device *device)
9819 ccb = cam_getccb(device);
9822 warnx("%s: error allocating ccb", __func__);
9826 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
9828 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9830 if (cam_send_ccb(device, ccb) < 0) {
9831 warn("error sending XPT_REPROBE_LUN CCB");
9836 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9837 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9849 usage(int printlong)
9852 fprintf(printlong ? stdout : stderr,
9853 "usage: camcontrol <command> [device id][generic args][command args]\n"
9854 " camcontrol devlist [-b] [-v]\n"
9855 #ifndef MINIMALISTIC
9856 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9857 " camcontrol tur [dev_id][generic args]\n"
9858 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9859 " camcontrol identify [dev_id][generic args] [-v]\n"
9860 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9861 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9863 " camcontrol start [dev_id][generic args]\n"
9864 " camcontrol stop [dev_id][generic args]\n"
9865 " camcontrol load [dev_id][generic args]\n"
9866 " camcontrol eject [dev_id][generic args]\n"
9867 " camcontrol reprobe [dev_id][generic args]\n"
9868 #endif /* MINIMALISTIC */
9869 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9870 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9871 #ifndef MINIMALISTIC
9872 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9873 " [-q][-s][-S offset][-X]\n"
9874 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9875 " [-P pagectl][-e | -b][-d]\n"
9876 " camcontrol cmd [dev_id][generic args]\n"
9877 " <-a cmd [args] | -c cmd [args]>\n"
9878 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9879 " camcontrol smpcmd [dev_id][generic args]\n"
9880 " <-r len fmt [args]> <-R len fmt [args]>\n"
9881 " camcontrol smprg [dev_id][generic args][-l]\n"
9882 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9883 " [-o operation][-d name][-m rate][-M rate]\n"
9884 " [-T pp_timeout][-a enable|disable]\n"
9885 " [-A enable|disable][-s enable|disable]\n"
9886 " [-S enable|disable]\n"
9887 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9888 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9889 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9890 " <all|dev_id|bus[:target[:lun]]|off>\n"
9891 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9892 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9893 " [-D <enable|disable>][-M mode][-O offset]\n"
9894 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9895 " [-U][-W bus_width]\n"
9896 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9897 " camcontrol sanitize [dev_id][generic args]\n"
9898 " [-a overwrite|block|crypto|exitfailure]\n"
9899 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9901 " camcontrol idle [dev_id][generic args][-t time]\n"
9902 " camcontrol standby [dev_id][generic args][-t time]\n"
9903 " camcontrol sleep [dev_id][generic args]\n"
9904 " camcontrol powermode [dev_id][generic args]\n"
9905 " camcontrol apm [dev_id][generic args][-l level]\n"
9906 " camcontrol aam [dev_id][generic args][-l level]\n"
9907 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9909 " camcontrol security [dev_id][generic args]\n"
9910 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9911 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9912 " [-U <user|master>] [-y]\n"
9913 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9914 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9915 " camcontrol ama [dev_id][generic args] [-f] [-q] [-s max_sectors]\n"
9916 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9917 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9918 " [-s scope][-S][-T type][-U]\n"
9919 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9920 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9921 " [-p part][-s start][-T type][-V vol]\n"
9922 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9924 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9925 " [-o rep_opts] [-P print_opts]\n"
9926 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9927 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9928 " [-S power_src] [-T timer]\n"
9929 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9930 " <-s <-f format -T time | -U >>\n"
9931 " camcontrol devtype [dev_id]\n"
9933 #endif /* MINIMALISTIC */
9934 " camcontrol help\n");
9937 #ifndef MINIMALISTIC
9939 "Specify one of the following options:\n"
9940 "devlist list all CAM devices\n"
9941 "periphlist list all CAM peripheral drivers attached to a device\n"
9942 "tur send a test unit ready to the named device\n"
9943 "inquiry send a SCSI inquiry command to the named device\n"
9944 "identify send a ATA identify command to the named device\n"
9945 "reportluns send a SCSI report luns command to the device\n"
9946 "readcap send a SCSI read capacity command to the device\n"
9947 "start send a Start Unit command to the device\n"
9948 "stop send a Stop Unit command to the device\n"
9949 "load send a Start Unit command to the device with the load bit set\n"
9950 "eject send a Stop Unit command to the device with the eject bit set\n"
9951 "reprobe update capacity information of the given device\n"
9952 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9953 "reset reset all buses, the given bus, bus:target:lun or device\n"
9954 "defects read the defect list of the specified device\n"
9955 "modepage display or edit (-e) the given mode page\n"
9956 "cmd send the given SCSI command, may need -i or -o as well\n"
9957 "smpcmd send the given SMP command, requires -o and -i\n"
9958 "smprg send the SMP Report General command\n"
9959 "smppc send the SMP PHY Control command, requires -p\n"
9960 "smpphylist display phys attached to a SAS expander\n"
9961 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9962 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9963 "tags report or set the number of transaction slots for a device\n"
9964 "negotiate report or set device negotiation parameters\n"
9965 "format send the SCSI FORMAT UNIT command to the named device\n"
9966 "sanitize send the SCSI SANITIZE command to the named device\n"
9967 "idle send the ATA IDLE command to the named device\n"
9968 "standby send the ATA STANDBY command to the named device\n"
9969 "sleep send the ATA SLEEP command to the named device\n"
9970 "powermode send the ATA CHECK POWER MODE command to the named device\n"
9971 "fwdownload program firmware of the named device with the given image\n"
9972 "security report or send ATA security commands to the named device\n"
9973 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9974 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9975 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9976 "zone manage Zoned Block (Shingled) devices\n"
9977 "epc send ATA Extended Power Conditions commands\n"
9978 "timestamp report or set the device's timestamp\n"
9979 "devtype report the type of device\n"
9980 "help this message\n"
9981 "Device Identifiers:\n"
9982 "bus:target specify the bus and target, lun defaults to 0\n"
9983 "bus:target:lun specify the bus, target and lun\n"
9984 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
9985 "Generic arguments:\n"
9986 "-v be verbose, print out sense information\n"
9987 "-t timeout command timeout in seconds, overrides default timeout\n"
9988 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
9989 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
9990 "-E have the kernel attempt to perform SCSI error recovery\n"
9991 "-C count specify the SCSI command retry count (needs -E to work)\n"
9992 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
9993 "modepage arguments:\n"
9994 "-l list all available mode pages\n"
9995 "-m page specify the mode page to view or edit\n"
9996 "-e edit the specified mode page\n"
9997 "-b force view to binary mode\n"
9998 "-d disable block descriptors for mode sense\n"
9999 "-P pgctl page control field 0-3\n"
10000 "defects arguments:\n"
10001 "-f format specify defect list format (block, bfi or phys)\n"
10002 "-G get the grown defect list\n"
10003 "-P get the permanent defect list\n"
10004 "inquiry arguments:\n"
10005 "-D get the standard inquiry data\n"
10006 "-S get the serial number\n"
10007 "-R get the transfer rate, etc.\n"
10008 "reportluns arguments:\n"
10009 "-c only report a count of available LUNs\n"
10010 "-l only print out luns, and not a count\n"
10011 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
10012 "readcap arguments\n"
10013 "-b only report the blocksize\n"
10014 "-h human readable device size, base 2\n"
10015 "-H human readable device size, base 10\n"
10016 "-N print the number of blocks instead of last block\n"
10017 "-q quiet, print numbers only\n"
10018 "-s only report the last block/device size\n"
10020 "-c cdb [args] specify the SCSI CDB\n"
10021 "-i len fmt specify input data and input data format\n"
10022 "-o len fmt [args] specify output data and output data fmt\n"
10023 "smpcmd arguments:\n"
10024 "-r len fmt [args] specify the SMP command to be sent\n"
10025 "-R len fmt [args] specify SMP response format\n"
10026 "smprg arguments:\n"
10027 "-l specify the long response format\n"
10028 "smppc arguments:\n"
10029 "-p phy specify the PHY to operate on\n"
10030 "-l specify the long request/response format\n"
10031 "-o operation specify the phy control operation\n"
10032 "-d name set the attached device name\n"
10033 "-m rate set the minimum physical link rate\n"
10034 "-M rate set the maximum physical link rate\n"
10035 "-T pp_timeout set the partial pathway timeout value\n"
10036 "-a enable|disable enable or disable SATA slumber\n"
10037 "-A enable|disable enable or disable SATA partial phy power\n"
10038 "-s enable|disable enable or disable SAS slumber\n"
10039 "-S enable|disable enable or disable SAS partial phy power\n"
10040 "smpphylist arguments:\n"
10041 "-l specify the long response format\n"
10042 "-q only print phys with attached devices\n"
10043 "smpmaninfo arguments:\n"
10044 "-l specify the long response format\n"
10045 "debug arguments:\n"
10046 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
10047 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
10048 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
10049 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
10050 "tags arguments:\n"
10051 "-N tags specify the number of tags to use for this device\n"
10052 "-q be quiet, don't report the number of tags\n"
10053 "-v report a number of tag-related parameters\n"
10054 "negotiate arguments:\n"
10055 "-a send a test unit ready after negotiation\n"
10056 "-c report/set current negotiation settings\n"
10057 "-D <arg> \"enable\" or \"disable\" disconnection\n"
10058 "-M mode set ATA mode\n"
10059 "-O offset set command delay offset\n"
10060 "-q be quiet, don't report anything\n"
10061 "-R syncrate synchronization rate in MHz\n"
10062 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
10063 "-U report/set user negotiation settings\n"
10064 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
10065 "-v also print a Path Inquiry CCB for the controller\n"
10066 "format arguments:\n"
10067 "-q be quiet, don't print status messages\n"
10068 "-r run in report only mode\n"
10069 "-w don't send immediate format command\n"
10070 "-y don't ask any questions\n"
10071 "sanitize arguments:\n"
10072 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
10073 "-c passes overwrite passes to perform (1 to 31)\n"
10074 "-I invert overwrite pattern after each pass\n"
10075 "-P pattern path to overwrite pattern file\n"
10076 "-q be quiet, don't print status messages\n"
10077 "-r run in report only mode\n"
10078 "-U run operation in unrestricted completion exit mode\n"
10079 "-w don't send immediate sanitize command\n"
10080 "-y don't ask any questions\n"
10081 "idle/standby arguments:\n"
10082 "-t <arg> number of seconds before respective state.\n"
10083 "fwdownload arguments:\n"
10084 "-f fw_image path to firmware image file\n"
10085 "-q don't print informational messages, only errors\n"
10086 "-s run in simulation mode\n"
10087 "-v print info for every firmware segment sent to device\n"
10088 "-y don't ask any questions\n"
10089 "security arguments:\n"
10090 "-d pwd disable security using the given password for the selected\n"
10092 "-e pwd erase the device using the given pwd for the selected user\n"
10093 "-f freeze the security configuration of the specified device\n"
10094 "-h pwd enhanced erase the device using the given pwd for the\n"
10096 "-k pwd unlock the device using the given pwd for the selected\n"
10098 "-l <high|maximum> specifies which security level to set: high or maximum\n"
10099 "-q be quiet, do not print any status messages\n"
10100 "-s pwd password the device (enable security) using the given\n"
10101 " pwd for the selected user\n"
10102 "-T timeout overrides the timeout (seconds) used for erase operation\n"
10103 "-U <user|master> specifies which user to set: user or master\n"
10104 "-y don't ask any questions\n"
10106 "-f freeze the HPA configuration of the device\n"
10107 "-l lock the HPA configuration of the device\n"
10108 "-P make the HPA max sectors persist\n"
10109 "-p pwd Set the HPA configuration password required for unlock\n"
10111 "-q be quiet, do not print any status messages\n"
10112 "-s sectors configures the maximum user accessible sectors of the\n"
10114 "-U pwd unlock the HPA configuration of the device\n"
10115 "-y don't ask any questions\n"
10117 "-f freeze the AMA configuration of the device\n"
10118 "-q be quiet, do not print any status messages\n"
10119 "-s sectors configures the maximum user accessible sectors of the\n"
10121 "persist arguments:\n"
10122 "-i action specify read_keys, read_reservation, report_cap, or\n"
10123 " read_full_status\n"
10124 "-o action specify register, register_ignore, reserve, release,\n"
10125 " clear, preempt, preempt_abort, register_move, replace_lost\n"
10126 "-a set the All Target Ports (ALL_TG_PT) bit\n"
10127 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
10128 "-k key specify the Reservation Key\n"
10129 "-K sa_key specify the Service Action Reservation Key\n"
10130 "-p set the Activate Persist Through Power Loss bit\n"
10131 "-R rtp specify the Relative Target Port\n"
10132 "-s scope specify the scope: lun, extent, element or a number\n"
10133 "-S specify Transport ID for register, requires -I\n"
10134 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
10135 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
10136 "-U unregister the current initiator for register_move\n"
10137 "attrib arguments:\n"
10138 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
10140 "-w attr specify an attribute to write, one -w argument per attr\n"
10141 "-a attr_num only display this attribute number\n"
10142 "-c get cached attributes\n"
10143 "-e elem_addr request attributes for the given element in a changer\n"
10144 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
10145 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
10146 " field_none, field_desc, field_num, field_size, field_rw\n"
10147 "-p partition request attributes for the given partition\n"
10148 "-s start_attr request attributes starting at the given number\n"
10149 "-T elem_type specify the element type (used with -e)\n"
10150 "-V logical_vol specify the logical volume ID\n"
10151 "opcodes arguments:\n"
10152 "-o opcode specify the individual opcode to list\n"
10153 "-s service_action specify the service action for the opcode\n"
10154 "-N do not return SCSI error for unsupported SA\n"
10155 "-T request nominal and recommended timeout values\n"
10156 "zone arguments:\n"
10157 "-c cmd required: rz, open, close, finish, or rwp\n"
10158 "-a apply the action to all zones\n"
10159 "-l LBA specify the zone starting LBA\n"
10160 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
10161 " closed, full, ro, offline, reset, nonseq, nonwp\n"
10162 "-P print_opt report zones printing: normal, summary, script\n"
10164 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
10165 " source, status, list\n"
10166 "-d disable power mode (timer, state)\n"
10167 "-D delayed entry (goto)\n"
10168 "-e enable power mode (timer, state)\n"
10169 "-H hold power mode (goto)\n"
10170 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
10172 "-P only display power mode (status)\n"
10173 "-r rst_src restore settings from: default, saved (restore)\n"
10174 "-s save mode (timer, state, restore)\n"
10175 "-S power_src set power source: battery, nonbattery (source)\n"
10176 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
10177 "timestamp arguments:\n"
10178 "-r report the timestamp of the device\n"
10179 "-f format report the timestamp of the device with the given\n"
10180 " strftime(3) format string\n"
10181 "-m report the timestamp of the device as milliseconds since\n"
10182 " January 1st, 1970\n"
10183 "-U report the time with UTC instead of the local time zone\n"
10184 "-s set the timestamp of the device\n"
10185 "-f format the format of the time string passed into strptime(3)\n"
10186 "-T time the time value passed into strptime(3)\n"
10187 "-U set the timestamp of the device to UTC time\n"
10189 #endif /* MINIMALISTIC */
10193 main(int argc, char **argv)
10196 char *device = NULL;
10198 struct cam_device *cam_dev = NULL;
10199 int timeout = 0, retry_count = 1;
10200 camcontrol_optret optreturn;
10202 const char *mainopt = "C:En:Q:t:u:v";
10203 const char *subopt = NULL;
10204 char combinedopt[256];
10205 int error = 0, optstart = 2;
10206 int task_attr = MSG_SIMPLE_Q_TAG;
10208 #ifndef MINIMALISTIC
10210 target_id_t target;
10212 #endif /* MINIMALISTIC */
10214 cmdlist = CAM_CMD_NONE;
10215 arglist = CAM_ARG_NONE;
10223 * Get the base option.
10225 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
10227 if (optreturn == CC_OR_AMBIGUOUS) {
10228 warnx("ambiguous option %s", argv[1]);
10231 } else if (optreturn == CC_OR_NOT_FOUND) {
10232 warnx("option %s not found", argv[1]);
10238 * Ahh, getopt(3) is a pain.
10240 * This is a gross hack. There really aren't many other good
10241 * options (excuse the pun) for parsing options in a situation like
10242 * this. getopt is kinda braindead, so you end up having to run
10243 * through the options twice, and give each invocation of getopt
10244 * the option string for the other invocation.
10246 * You would think that you could just have two groups of options.
10247 * The first group would get parsed by the first invocation of
10248 * getopt, and the second group would get parsed by the second
10249 * invocation of getopt. It doesn't quite work out that way. When
10250 * the first invocation of getopt finishes, it leaves optind pointing
10251 * to the argument _after_ the first argument in the second group.
10252 * So when the second invocation of getopt comes around, it doesn't
10253 * recognize the first argument it gets and then bails out.
10255 * A nice alternative would be to have a flag for getopt that says
10256 * "just keep parsing arguments even when you encounter an unknown
10257 * argument", but there isn't one. So there's no real clean way to
10258 * easily parse two sets of arguments without having one invocation
10259 * of getopt know about the other.
10261 * Without this hack, the first invocation of getopt would work as
10262 * long as the generic arguments are first, but the second invocation
10263 * (in the subfunction) would fail in one of two ways. In the case
10264 * where you don't set optreset, it would fail because optind may be
10265 * pointing to the argument after the one it should be pointing at.
10266 * In the case where you do set optreset, and reset optind, it would
10267 * fail because getopt would run into the first set of options, which
10268 * it doesn't understand.
10270 * All of this would "sort of" work if you could somehow figure out
10271 * whether optind had been incremented one option too far. The
10272 * mechanics of that, however, are more daunting than just giving
10273 * both invocations all of the expect options for either invocation.
10275 * Needless to say, I wouldn't mind if someone invented a better
10276 * (non-GPL!) command line parsing interface than getopt. I
10277 * wouldn't mind if someone added more knobs to getopt to make it
10278 * work better. Who knows, I may talk myself into doing it someday,
10279 * if the standards weenies let me. As it is, it just leads to
10280 * hackery like this and causes people to avoid it in some cases.
10282 * KDM, September 8th, 1998
10284 if (subopt != NULL)
10285 sprintf(combinedopt, "%s%s", mainopt, subopt);
10287 sprintf(combinedopt, "%s", mainopt);
10290 * For these options we do not parse optional device arguments and
10291 * we do not open a passthrough device.
10293 if ((cmdlist == CAM_CMD_RESCAN)
10294 || (cmdlist == CAM_CMD_RESET)
10295 || (cmdlist == CAM_CMD_DEVTREE)
10296 || (cmdlist == CAM_CMD_USAGE)
10297 || (cmdlist == CAM_CMD_DEBUG))
10300 #ifndef MINIMALISTIC
10302 && (argc > 2 && argv[2][0] != '-')) {
10306 if (isdigit(argv[2][0])) {
10307 /* device specified as bus:target[:lun] */
10308 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10310 errx(1, "numeric device specification must "
10311 "be either bus:target, or "
10313 /* default to 0 if lun was not specified */
10314 if ((arglist & CAM_ARG_LUN) == 0) {
10316 arglist |= CAM_ARG_LUN;
10320 if (cam_get_device(argv[2], name, sizeof name, &unit)
10322 errx(1, "%s", cam_errbuf);
10323 device = strdup(name);
10324 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10328 #endif /* MINIMALISTIC */
10330 * Start getopt processing at argv[2/3], since we've already
10331 * accepted argv[1..2] as the command name, and as a possible
10337 * Now we run through the argument list looking for generic
10338 * options, and ignoring options that possibly belong to
10341 while ((c = getopt(argc, argv, combinedopt))!= -1){
10344 retry_count = strtol(optarg, NULL, 0);
10345 if (retry_count < 0)
10346 errx(1, "retry count %d is < 0",
10348 arglist |= CAM_ARG_RETRIES;
10351 arglist |= CAM_ARG_ERR_RECOVER;
10354 arglist |= CAM_ARG_DEVICE;
10356 while (isspace(*tstr) && (*tstr != '\0'))
10358 device = (char *)strdup(tstr);
10362 int table_entry = 0;
10365 while (isspace(*tstr) && (*tstr != '\0'))
10367 if (isdigit(*tstr)) {
10368 task_attr = strtol(tstr, &endptr, 0);
10369 if (*endptr != '\0') {
10370 errx(1, "Invalid queue option "
10375 scsi_nv_status status;
10377 table_size = sizeof(task_attrs) /
10378 sizeof(task_attrs[0]);
10379 status = scsi_get_nv(task_attrs,
10380 table_size, tstr, &table_entry,
10381 SCSI_NV_FLAG_IG_CASE);
10382 if (status == SCSI_NV_FOUND)
10383 task_attr = task_attrs[
10384 table_entry].value;
10386 errx(1, "%s option %s",
10387 (status == SCSI_NV_AMBIGUOUS)?
10388 "ambiguous" : "invalid",
10395 timeout = strtol(optarg, NULL, 0);
10397 errx(1, "invalid timeout %d", timeout);
10398 /* Convert the timeout from seconds to ms */
10400 arglist |= CAM_ARG_TIMEOUT;
10403 arglist |= CAM_ARG_UNIT;
10404 unit = strtol(optarg, NULL, 0);
10407 arglist |= CAM_ARG_VERBOSE;
10414 #ifndef MINIMALISTIC
10416 * For most commands we'll want to open the passthrough device
10417 * associated with the specified device. In the case of the rescan
10418 * commands, we don't use a passthrough device at all, just the
10419 * transport layer device.
10421 if (devopen == 1) {
10422 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10423 && (((arglist & CAM_ARG_DEVICE) == 0)
10424 || ((arglist & CAM_ARG_UNIT) == 0))) {
10425 errx(1, "subcommand \"%s\" requires a valid device "
10426 "identifier", argv[1]);
10429 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10430 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10431 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10433 errx(1,"%s", cam_errbuf);
10435 #endif /* MINIMALISTIC */
10438 * Reset optind to 2, and reset getopt, so these routines can parse
10439 * the arguments again.
10445 #ifndef MINIMALISTIC
10446 case CAM_CMD_DEVLIST:
10447 error = getdevlist(cam_dev);
10450 error = atahpa(cam_dev, retry_count, timeout,
10451 argc, argv, combinedopt);
10454 error = ataama(cam_dev, retry_count, timeout,
10455 argc, argv, combinedopt);
10457 #endif /* MINIMALISTIC */
10458 case CAM_CMD_DEVTREE:
10459 error = getdevtree(argc, argv, combinedopt);
10461 case CAM_CMD_DEVTYPE:
10462 error = getdevtype(cam_dev);
10464 #ifndef MINIMALISTIC
10466 error = testunitready(cam_dev, task_attr, retry_count,
10469 case CAM_CMD_INQUIRY:
10470 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10471 task_attr, retry_count, timeout);
10473 case CAM_CMD_IDENTIFY:
10474 error = identify(cam_dev, retry_count, timeout);
10476 case CAM_CMD_STARTSTOP:
10477 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10478 arglist & CAM_ARG_EJECT, task_attr,
10479 retry_count, timeout);
10481 #endif /* MINIMALISTIC */
10482 case CAM_CMD_RESCAN:
10483 error = dorescan_or_reset(argc, argv, 1);
10485 case CAM_CMD_RESET:
10486 error = dorescan_or_reset(argc, argv, 0);
10488 #ifndef MINIMALISTIC
10489 case CAM_CMD_READ_DEFECTS:
10490 error = readdefects(cam_dev, argc, argv, combinedopt,
10491 task_attr, retry_count, timeout);
10493 case CAM_CMD_MODE_PAGE:
10494 modepage(cam_dev, argc, argv, combinedopt,
10495 task_attr, retry_count, timeout);
10497 case CAM_CMD_SCSI_CMD:
10498 error = scsicmd(cam_dev, argc, argv, combinedopt,
10499 task_attr, retry_count, timeout);
10501 case CAM_CMD_MMCSD_CMD:
10502 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10503 retry_count, timeout);
10505 case CAM_CMD_SMP_CMD:
10506 error = smpcmd(cam_dev, argc, argv, combinedopt,
10507 retry_count, timeout);
10509 case CAM_CMD_SMP_RG:
10510 error = smpreportgeneral(cam_dev, argc, argv,
10511 combinedopt, retry_count,
10514 case CAM_CMD_SMP_PC:
10515 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10516 retry_count, timeout);
10518 case CAM_CMD_SMP_PHYLIST:
10519 error = smpphylist(cam_dev, argc, argv, combinedopt,
10520 retry_count, timeout);
10522 case CAM_CMD_SMP_MANINFO:
10523 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10524 retry_count, timeout);
10526 case CAM_CMD_DEBUG:
10527 error = camdebug(argc, argv, combinedopt);
10530 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10533 error = ratecontrol(cam_dev, task_attr, retry_count,
10534 timeout, argc, argv, combinedopt);
10536 case CAM_CMD_FORMAT:
10537 error = scsiformat(cam_dev, argc, argv,
10538 combinedopt, task_attr, retry_count,
10541 case CAM_CMD_REPORTLUNS:
10542 error = scsireportluns(cam_dev, argc, argv,
10543 combinedopt, task_attr,
10544 retry_count, timeout);
10546 case CAM_CMD_READCAP:
10547 error = scsireadcapacity(cam_dev, argc, argv,
10548 combinedopt, task_attr,
10549 retry_count, timeout);
10552 case CAM_CMD_STANDBY:
10553 case CAM_CMD_SLEEP:
10554 case CAM_CMD_POWER_MODE:
10555 error = atapm(cam_dev, argc, argv,
10556 combinedopt, retry_count, timeout);
10560 error = ataaxm(cam_dev, argc, argv,
10561 combinedopt, retry_count, timeout);
10563 case CAM_CMD_SECURITY:
10564 error = atasecurity(cam_dev, retry_count, timeout,
10565 argc, argv, combinedopt);
10567 case CAM_CMD_DOWNLOAD_FW:
10568 error = fwdownload(cam_dev, argc, argv, combinedopt,
10569 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10572 case CAM_CMD_SANITIZE:
10573 error = sanitize(cam_dev, argc, argv, combinedopt, task_attr,
10574 retry_count, timeout);
10576 case CAM_CMD_PERSIST:
10577 error = scsipersist(cam_dev, argc, argv, combinedopt,
10578 task_attr, retry_count, timeout,
10579 arglist & CAM_ARG_VERBOSE,
10580 arglist & CAM_ARG_ERR_RECOVER);
10582 case CAM_CMD_ATTRIB:
10583 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10584 task_attr, retry_count, timeout,
10585 arglist & CAM_ARG_VERBOSE,
10586 arglist & CAM_ARG_ERR_RECOVER);
10588 case CAM_CMD_OPCODES:
10589 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10590 task_attr, retry_count, timeout,
10591 arglist & CAM_ARG_VERBOSE);
10593 case CAM_CMD_REPROBE:
10594 error = reprobe(cam_dev);
10597 error = zone(cam_dev, argc, argv, combinedopt,
10598 task_attr, retry_count, timeout,
10599 arglist & CAM_ARG_VERBOSE);
10602 error = epc(cam_dev, argc, argv, combinedopt,
10603 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10605 case CAM_CMD_TIMESTAMP:
10606 error = timestamp(cam_dev, argc, argv, combinedopt,
10607 task_attr, retry_count, timeout,
10608 arglist & CAM_ARG_VERBOSE);
10610 #endif /* MINIMALISTIC */
10611 case CAM_CMD_USAGE:
10620 if (cam_dev != NULL)
10621 cam_close_device(cam_dev);