2 * Copyright (c) 1997-2007 Kenneth D. Merry
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/ioctl.h>
33 #include <sys/stdint.h>
34 #include <sys/types.h>
36 #include <sys/endian.h>
53 #include <cam/cam_debug.h>
54 #include <cam/cam_ccb.h>
55 #include <cam/scsi/scsi_all.h>
56 #include <cam/scsi/scsi_da.h>
57 #include <cam/scsi/scsi_pass.h>
58 #include <cam/scsi/scsi_message.h>
59 #include <cam/scsi/smp_all.h>
60 #include <cam/ata/ata_all.h>
61 #include <cam/mmc/mmc_all.h>
63 #include "camcontrol.h"
65 #include "nvmecontrol_ext.h"
69 CAM_CMD_NONE = 0x00000000,
70 CAM_CMD_DEVLIST = 0x00000001,
71 CAM_CMD_TUR = 0x00000002,
72 CAM_CMD_INQUIRY = 0x00000003,
73 CAM_CMD_STARTSTOP = 0x00000004,
74 CAM_CMD_RESCAN = 0x00000005,
75 CAM_CMD_READ_DEFECTS = 0x00000006,
76 CAM_CMD_MODE_PAGE = 0x00000007,
77 CAM_CMD_SCSI_CMD = 0x00000008,
78 CAM_CMD_DEVTREE = 0x00000009,
79 CAM_CMD_USAGE = 0x0000000a,
80 CAM_CMD_DEBUG = 0x0000000b,
81 CAM_CMD_RESET = 0x0000000c,
82 CAM_CMD_FORMAT = 0x0000000d,
83 CAM_CMD_TAG = 0x0000000e,
84 CAM_CMD_RATE = 0x0000000f,
85 CAM_CMD_DETACH = 0x00000010,
86 CAM_CMD_REPORTLUNS = 0x00000011,
87 CAM_CMD_READCAP = 0x00000012,
88 CAM_CMD_IDENTIFY = 0x00000013,
89 CAM_CMD_IDLE = 0x00000014,
90 CAM_CMD_STANDBY = 0x00000015,
91 CAM_CMD_SLEEP = 0x00000016,
92 CAM_CMD_SMP_CMD = 0x00000017,
93 CAM_CMD_SMP_RG = 0x00000018,
94 CAM_CMD_SMP_PC = 0x00000019,
95 CAM_CMD_SMP_PHYLIST = 0x0000001a,
96 CAM_CMD_SMP_MANINFO = 0x0000001b,
97 CAM_CMD_DOWNLOAD_FW = 0x0000001c,
98 CAM_CMD_SECURITY = 0x0000001d,
99 CAM_CMD_HPA = 0x0000001e,
100 CAM_CMD_SANITIZE = 0x0000001f,
101 CAM_CMD_PERSIST = 0x00000020,
102 CAM_CMD_APM = 0x00000021,
103 CAM_CMD_AAM = 0x00000022,
104 CAM_CMD_ATTRIB = 0x00000023,
105 CAM_CMD_OPCODES = 0x00000024,
106 CAM_CMD_REPROBE = 0x00000025,
107 CAM_CMD_ZONE = 0x00000026,
108 CAM_CMD_EPC = 0x00000027,
109 CAM_CMD_TIMESTAMP = 0x00000028,
110 CAM_CMD_MMCSD_CMD = 0x00000029,
111 CAM_CMD_POWER_MODE = 0x0000002a,
112 CAM_CMD_DEVTYPE = 0x0000002b,
113 CAM_CMD_AMA = 0x0000002c,
117 CAM_ARG_NONE = 0x00000000,
118 CAM_ARG_VERBOSE = 0x00000001,
119 CAM_ARG_DEVICE = 0x00000002,
120 CAM_ARG_BUS = 0x00000004,
121 CAM_ARG_TARGET = 0x00000008,
122 CAM_ARG_LUN = 0x00000010,
123 CAM_ARG_EJECT = 0x00000020,
124 CAM_ARG_UNIT = 0x00000040,
125 CAM_ARG_FORMAT_BLOCK = 0x00000080,
126 CAM_ARG_FORMAT_BFI = 0x00000100,
127 CAM_ARG_FORMAT_PHYS = 0x00000200,
128 CAM_ARG_PLIST = 0x00000400,
129 CAM_ARG_GLIST = 0x00000800,
130 CAM_ARG_GET_SERIAL = 0x00001000,
131 CAM_ARG_GET_STDINQ = 0x00002000,
132 CAM_ARG_GET_XFERRATE = 0x00004000,
133 CAM_ARG_INQ_MASK = 0x00007000,
134 CAM_ARG_TIMEOUT = 0x00020000,
135 CAM_ARG_CMD_IN = 0x00040000,
136 CAM_ARG_CMD_OUT = 0x00080000,
137 CAM_ARG_ERR_RECOVER = 0x00200000,
138 CAM_ARG_RETRIES = 0x00400000,
139 CAM_ARG_START_UNIT = 0x00800000,
140 CAM_ARG_DEBUG_INFO = 0x01000000,
141 CAM_ARG_DEBUG_TRACE = 0x02000000,
142 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
143 CAM_ARG_DEBUG_CDB = 0x08000000,
144 CAM_ARG_DEBUG_XPT = 0x10000000,
145 CAM_ARG_DEBUG_PERIPH = 0x20000000,
146 CAM_ARG_DEBUG_PROBE = 0x40000000,
149 struct camcontrol_opts {
156 struct ata_set_max_pwd
159 u_int8_t password[32];
160 u_int16_t reserved2[239];
163 static struct scsi_nv task_attrs[] = {
164 { "simple", MSG_SIMPLE_Q_TAG },
165 { "head", MSG_HEAD_OF_Q_TAG },
166 { "ordered", MSG_ORDERED_Q_TAG },
167 { "iwr", MSG_IGN_WIDE_RESIDUE },
168 { "aca", MSG_ACA_TASK }
171 static const char scsicmd_opts[] = "a:c:dfi:o:r";
172 static const char readdefect_opts[] = "f:GPqsS:X";
173 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
174 static const char smprg_opts[] = "l";
175 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
176 static const char smpphylist_opts[] = "lq";
179 static struct camcontrol_opts option_table[] = {
180 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
181 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
182 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
183 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
184 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
185 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
186 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
187 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
188 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHlNqs"},
189 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
190 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
191 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
192 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
193 {"mmcsdcmd", CAM_CMD_MMCSD_CMD, CAM_ARG_NONE, "c:a:f:Wb:l:41S:I"},
194 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
195 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
196 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
197 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
198 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
199 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
200 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
201 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
202 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
203 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
204 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
205 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
206 {"devtype", CAM_CMD_DEVTYPE, CAM_ARG_NONE, ""},
207 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
208 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "6bdelm:DLP:"},
209 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
210 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
211 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
212 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
213 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
214 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
215 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
216 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
217 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
218 {"powermode", CAM_CMD_POWER_MODE, CAM_ARG_NONE, ""},
219 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
220 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
221 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
222 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
223 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
224 {"ama", CAM_CMD_AMA, CAM_ARG_NONE, "fqs:"},
225 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
226 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
227 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
228 {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
229 {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
230 {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
231 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
232 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
233 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
238 struct device_match_result dev_match;
240 struct periph_match_result *periph_matches;
241 struct scsi_vpd_device_id *device_id;
243 STAILQ_ENTRY(cam_devitem) links;
247 STAILQ_HEAD(, cam_devitem) dev_queue;
251 static cam_cmdmask cmdlist;
252 static cam_argmask arglist;
254 static const char *devtype_names[] = {
264 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
265 uint32_t *cmdnum, cam_argmask *argnum,
266 const char **subopt);
267 static int getdevlist(struct cam_device *device);
268 static int getdevtree(int argc, char **argv, char *combinedopt);
269 static int getdevtype(struct cam_device *device);
270 static int print_dev_scsi(struct device_match_result *dev_result, char *tmpstr);
271 static int print_dev_ata(struct device_match_result *dev_result, char *tmpstr);
272 static int print_dev_semb(struct device_match_result *dev_result, char *tmpstr);
273 static int print_dev_mmcsd(struct device_match_result *dev_result,
276 static int print_dev_nvme(struct device_match_result *dev_result, char *tmpstr);
278 static int testunitready(struct cam_device *device, int task_attr,
279 int retry_count, int timeout, int quiet);
280 static int scsistart(struct cam_device *device, int startstop, int loadeject,
281 int task_attr, int retry_count, int timeout);
282 static int scsiinquiry(struct cam_device *device, int task_attr,
283 int retry_count, int timeout);
284 static int scsiserial(struct cam_device *device, int task_attr,
285 int retry_count, int timeout);
286 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
287 lun_id_t *lun, cam_argmask *arglst);
288 static int reprobe(struct cam_device *device);
289 static int dorescan_or_reset(int argc, char **argv, int rescan);
290 static int rescan_or_reset_bus(path_id_t bus, int rescan);
291 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
292 lun_id_t lun, int scan);
293 static int readdefects(struct cam_device *device, int argc, char **argv,
294 char *combinedopt, int task_attr, int retry_count,
296 static void modepage(struct cam_device *device, int argc, char **argv,
297 char *combinedopt, int task_attr, int retry_count,
299 static int scsicmd(struct cam_device *device, int argc, char **argv,
300 char *combinedopt, int task_attr, int retry_count,
302 static int smpcmd(struct cam_device *device, int argc, char **argv,
303 char *combinedopt, int retry_count, int timeout);
304 static int mmcsdcmd(struct cam_device *device, int argc, char **argv,
305 char *combinedopt, int retry_count, int timeout);
306 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
307 char *combinedopt, int retry_count, int timeout);
308 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
309 char *combinedopt, int retry_count, int timeout);
310 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
311 char *combinedopt, int retry_count, int timeout);
312 static int getdevid(struct cam_devitem *item);
313 static int buildbusdevlist(struct cam_devlist *devlist);
314 static void freebusdevlist(struct cam_devlist *devlist);
315 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
317 static int smpphylist(struct cam_device *device, int argc, char **argv,
318 char *combinedopt, int retry_count, int timeout);
319 static int tagcontrol(struct cam_device *device, int argc, char **argv,
321 static void cts_print(struct cam_device *device,
322 struct ccb_trans_settings *cts);
323 static void cpi_print(struct ccb_pathinq *cpi);
324 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
325 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
326 static int get_print_cts(struct cam_device *device, int user_settings,
327 int quiet, struct ccb_trans_settings *cts);
328 static int ratecontrol(struct cam_device *device, int task_attr,
329 int retry_count, int timeout, int argc, char **argv,
331 static int scsiformat(struct cam_device *device, int argc, char **argv,
332 char *combinedopt, int task_attr, int retry_count,
334 static int sanitize(struct cam_device *device, int argc, char **argv,
335 char *combinedopt, int task_attr, int retry_count,
337 static int scsireportluns(struct cam_device *device, int argc, char **argv,
338 char *combinedopt, int task_attr, int retry_count,
340 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
341 char *combinedopt, int task_attr, int retry_count,
343 static int atapm(struct cam_device *device, int argc, char **argv,
344 char *combinedopt, int retry_count, int timeout);
345 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
346 int argc, char **argv, char *combinedopt);
347 static int atahpa(struct cam_device *device, int retry_count, int timeout,
348 int argc, char **argv, char *combinedopt);
349 static int ataama(struct cam_device *device, int retry_count, int timeout,
350 int argc, char **argv, char *combinedopt);
351 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
352 int sa_set, int req_sa, uint8_t *buf,
354 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
356 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
357 char *combinedopt, int task_attr, int retry_count,
358 int timeout, int verbose);
361 #define min(a,b) (((a)<(b))?(a):(b))
364 #define max(a,b) (((a)>(b))?(a):(b))
368 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
369 cam_argmask *argnum, const char **subopt)
371 struct camcontrol_opts *opts;
374 for (opts = table; (opts != NULL) && (opts->optname != NULL);
376 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
377 *cmdnum = opts->cmdnum;
378 *argnum = opts->argnum;
379 *subopt = opts->subopt;
380 if (++num_matches > 1)
381 return (CC_OR_AMBIGUOUS);
386 return (CC_OR_FOUND);
388 return (CC_OR_NOT_FOUND);
392 getdevlist(struct cam_device *device)
398 ccb = cam_getccb(device);
400 ccb->ccb_h.func_code = XPT_GDEVLIST;
401 ccb->ccb_h.flags = CAM_DIR_NONE;
402 ccb->ccb_h.retry_count = 1;
404 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
405 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
406 if (cam_send_ccb(device, ccb) < 0) {
407 warn("error getting device list");
414 switch (ccb->cgdl.status) {
415 case CAM_GDEVLIST_MORE_DEVS:
416 strcpy(status, "MORE");
418 case CAM_GDEVLIST_LAST_DEVICE:
419 strcpy(status, "LAST");
421 case CAM_GDEVLIST_LIST_CHANGED:
422 strcpy(status, "CHANGED");
424 case CAM_GDEVLIST_ERROR:
425 strcpy(status, "ERROR");
430 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
431 ccb->cgdl.periph_name,
432 ccb->cgdl.unit_number,
433 ccb->cgdl.generation,
438 * If the list has changed, we need to start over from the
441 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
451 getdevtree(int argc, char **argv, char *combinedopt)
462 while ((c = getopt(argc, argv, combinedopt)) != -1) {
465 if ((arglist & CAM_ARG_VERBOSE) == 0)
473 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
474 warn("couldn't open %s", XPT_DEVICE);
478 bzero(&ccb, sizeof(union ccb));
480 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
481 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
482 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
484 ccb.ccb_h.func_code = XPT_DEV_MATCH;
485 bufsize = sizeof(struct dev_match_result) * 100;
486 ccb.cdm.match_buf_len = bufsize;
487 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
488 if (ccb.cdm.matches == NULL) {
489 warnx("can't malloc memory for matches");
493 ccb.cdm.num_matches = 0;
496 * We fetch all nodes, since we display most of them in the default
497 * case, and all in the verbose case.
499 ccb.cdm.num_patterns = 0;
500 ccb.cdm.pattern_buf_len = 0;
503 * We do the ioctl multiple times if necessary, in case there are
504 * more than 100 nodes in the EDT.
507 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
508 warn("error sending CAMIOCOMMAND ioctl");
513 if ((ccb.ccb_h.status != CAM_REQ_CMP)
514 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
515 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
516 warnx("got CAM error %#x, CDM error %d\n",
517 ccb.ccb_h.status, ccb.cdm.status);
522 for (i = 0; i < ccb.cdm.num_matches; i++) {
523 switch (ccb.cdm.matches[i].type) {
524 case DEV_MATCH_BUS: {
525 struct bus_match_result *bus_result;
528 * Only print the bus information if the
529 * user turns on the verbose flag.
531 if ((busonly == 0) &&
532 (arglist & CAM_ARG_VERBOSE) == 0)
536 &ccb.cdm.matches[i].result.bus_result;
539 fprintf(stdout, ")\n");
543 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
545 bus_result->dev_name,
546 bus_result->unit_number,
548 (busonly ? "" : ":"));
551 case DEV_MATCH_DEVICE: {
552 struct device_match_result *dev_result;
559 &ccb.cdm.matches[i].result.device_result;
561 if ((dev_result->flags
562 & DEV_RESULT_UNCONFIGURED)
563 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
569 if (dev_result->protocol == PROTO_SCSI) {
570 if (print_dev_scsi(dev_result,
575 } else if (dev_result->protocol == PROTO_ATA ||
576 dev_result->protocol == PROTO_SATAPM) {
577 if (print_dev_ata(dev_result,
582 } else if (dev_result->protocol == PROTO_MMCSD){
583 if (print_dev_mmcsd(dev_result,
588 } else if (dev_result->protocol == PROTO_SEMB) {
589 if (print_dev_semb(dev_result,
595 } else if (dev_result->protocol == PROTO_NVME) {
596 if (print_dev_nvme(dev_result,
603 sprintf(tmpstr, "<>");
606 fprintf(stdout, ")\n");
610 fprintf(stdout, "%-33s at scbus%d "
611 "target %d lun %jx (",
614 dev_result->target_id,
615 (uintmax_t)dev_result->target_lun);
621 case DEV_MATCH_PERIPH: {
622 struct periph_match_result *periph_result;
625 &ccb.cdm.matches[i].result.periph_result;
627 if (busonly || skip_device != 0)
631 fprintf(stdout, ",");
633 fprintf(stdout, "%s%d",
634 periph_result->periph_name,
635 periph_result->unit_number);
641 fprintf(stdout, "unknown match type\n");
646 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
647 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
650 fprintf(stdout, ")\n");
658 getdevtype(struct cam_device *cam_dev)
660 camcontrol_devtype dt;
664 * Get the device type and report it, request no I/O be done to do this.
666 error = get_device_type(cam_dev, -1, 0, 0, &dt);
667 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
668 fprintf(stdout, "illegal\n");
671 fprintf(stdout, "%s\n", devtype_names[dt]);
676 print_dev_scsi(struct device_match_result *dev_result, char *tmpstr)
678 char vendor[16], product[48], revision[16];
680 cam_strvis(vendor, dev_result->inq_data.vendor,
681 sizeof(dev_result->inq_data.vendor), sizeof(vendor));
682 cam_strvis(product, dev_result->inq_data.product,
683 sizeof(dev_result->inq_data.product), sizeof(product));
684 cam_strvis(revision, dev_result->inq_data.revision,
685 sizeof(dev_result->inq_data.revision), sizeof(revision));
686 sprintf(tmpstr, "<%s %s %s>", vendor, product, revision);
692 print_dev_ata(struct device_match_result *dev_result, char *tmpstr)
694 char product[48], revision[16];
696 cam_strvis(product, dev_result->ident_data.model,
697 sizeof(dev_result->ident_data.model), sizeof(product));
698 cam_strvis(revision, dev_result->ident_data.revision,
699 sizeof(dev_result->ident_data.revision), sizeof(revision));
700 sprintf(tmpstr, "<%s %s>", product, revision);
706 print_dev_semb(struct device_match_result *dev_result, char *tmpstr)
708 struct sep_identify_data *sid;
709 char vendor[16], product[48], revision[16], fw[5];
711 sid = (struct sep_identify_data *)&dev_result->ident_data;
712 cam_strvis(vendor, sid->vendor_id,
713 sizeof(sid->vendor_id), sizeof(vendor));
714 cam_strvis(product, sid->product_id,
715 sizeof(sid->product_id), sizeof(product));
716 cam_strvis(revision, sid->product_rev,
717 sizeof(sid->product_rev), sizeof(revision));
718 cam_strvis(fw, sid->firmware_rev,
719 sizeof(sid->firmware_rev), sizeof(fw));
720 sprintf(tmpstr, "<%s %s %s %s>", vendor, product, revision, fw);
726 print_dev_mmcsd(struct device_match_result *dev_result, char *tmpstr)
729 struct ccb_dev_advinfo *advi;
730 struct cam_device *dev;
731 struct mmc_params mmc_ident_data;
733 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
734 dev_result->target_lun, O_RDWR, NULL);
736 warnx("%s", cam_errbuf);
740 ccb = cam_getccb(dev);
742 warnx("couldn't allocate CCB");
743 cam_close_device(dev);
748 advi->ccb_h.flags = CAM_DIR_IN;
749 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
750 advi->flags = CDAI_FLAG_NONE;
751 advi->buftype = CDAI_TYPE_MMC_PARAMS;
752 advi->bufsiz = sizeof(struct mmc_params);
753 advi->buf = (uint8_t *)&mmc_ident_data;
755 if (cam_send_ccb(dev, ccb) < 0) {
756 warn("error sending XPT_DEV_ADVINFO CCB");
758 cam_close_device(dev);
762 if (strlen(mmc_ident_data.model) > 0) {
763 sprintf(tmpstr, "<%s>", mmc_ident_data.model);
765 sprintf(tmpstr, "<%s card>",
766 mmc_ident_data.card_features &
767 CARD_FEATURE_SDIO ? "SDIO" : "unknown");
771 cam_close_device(dev);
777 nvme_get_cdata(struct cam_device *dev, struct nvme_controller_data *cdata)
780 struct ccb_dev_advinfo *advi;
782 ccb = cam_getccb(dev);
784 warnx("couldn't allocate CCB");
785 cam_close_device(dev);
790 advi->ccb_h.flags = CAM_DIR_IN;
791 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
792 advi->flags = CDAI_FLAG_NONE;
793 advi->buftype = CDAI_TYPE_NVME_CNTRL;
794 advi->bufsiz = sizeof(struct nvme_controller_data);
795 advi->buf = (uint8_t *)cdata;
797 if (cam_send_ccb(dev, ccb) < 0) {
798 warn("error sending XPT_DEV_ADVINFO CCB");
800 cam_close_device(dev);
803 if (advi->ccb_h.status != CAM_REQ_CMP) {
804 warnx("got CAM error %#x", advi->ccb_h.status);
806 cam_close_device(dev);
814 print_dev_nvme(struct device_match_result *dev_result, char *tmpstr)
816 struct cam_device *dev;
817 struct nvme_controller_data cdata;
818 char vendor[64], product[64];
820 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
821 dev_result->target_lun, O_RDWR, NULL);
823 warnx("%s", cam_errbuf);
827 if (nvme_get_cdata(dev, &cdata))
830 cam_strvis(vendor, cdata.mn, sizeof(cdata.mn), sizeof(vendor));
831 cam_strvis(product, cdata.fr, sizeof(cdata.fr), sizeof(product));
832 sprintf(tmpstr, "<%s %s>", vendor, product);
834 cam_close_device(dev);
840 testunitready(struct cam_device *device, int task_attr, int retry_count,
841 int timeout, int quiet)
846 ccb = cam_getccb(device);
848 scsi_test_unit_ready(&ccb->csio,
849 /* retries */ retry_count,
851 /* tag_action */ task_attr,
852 /* sense_len */ SSD_FULL_SIZE,
853 /* timeout */ timeout ? timeout : 5000);
855 /* Disable freezing the device queue */
856 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
858 if (arglist & CAM_ARG_ERR_RECOVER)
859 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
861 if (cam_send_ccb(device, ccb) < 0) {
863 warn("error sending TEST UNIT READY command");
868 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
870 fprintf(stdout, "Unit is ready\n");
873 fprintf(stdout, "Unit is not ready\n");
876 if (arglist & CAM_ARG_VERBOSE) {
877 cam_error_print(device, ccb, CAM_ESF_ALL,
878 CAM_EPF_ALL, stderr);
888 scsistart(struct cam_device *device, int startstop, int loadeject,
889 int task_attr, int retry_count, int timeout)
894 ccb = cam_getccb(device);
897 * If we're stopping, send an ordered tag so the drive in question
898 * will finish any previously queued writes before stopping. If
899 * the device isn't capable of tagged queueing, or if tagged
900 * queueing is turned off, the tag action is a no-op. We override
901 * the default simple tag, although this also has the effect of
902 * overriding the user's wishes if he wanted to specify a simple
906 && (task_attr == MSG_SIMPLE_Q_TAG))
907 task_attr = MSG_ORDERED_Q_TAG;
909 scsi_start_stop(&ccb->csio,
910 /* retries */ retry_count,
912 /* tag_action */ task_attr,
913 /* start/stop */ startstop,
914 /* load_eject */ loadeject,
916 /* sense_len */ SSD_FULL_SIZE,
917 /* timeout */ timeout ? timeout : 120000);
919 /* Disable freezing the device queue */
920 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
922 if (arglist & CAM_ARG_ERR_RECOVER)
923 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
925 if (cam_send_ccb(device, ccb) < 0) {
926 warn("error sending START STOP UNIT command");
931 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
933 fprintf(stdout, "Unit started successfully");
935 fprintf(stdout,", Media loaded\n");
937 fprintf(stdout,"\n");
939 fprintf(stdout, "Unit stopped successfully");
941 fprintf(stdout, ", Media ejected\n");
943 fprintf(stdout, "\n");
949 "Error received from start unit command\n");
952 "Error received from stop unit command\n");
954 if (arglist & CAM_ARG_VERBOSE) {
955 cam_error_print(device, ccb, CAM_ESF_ALL,
956 CAM_EPF_ALL, stderr);
966 scsidoinquiry(struct cam_device *device, int argc, char **argv,
967 char *combinedopt, int task_attr, int retry_count, int timeout)
972 while ((c = getopt(argc, argv, combinedopt)) != -1) {
975 arglist |= CAM_ARG_GET_STDINQ;
978 arglist |= CAM_ARG_GET_XFERRATE;
981 arglist |= CAM_ARG_GET_SERIAL;
989 * If the user didn't specify any inquiry options, he wants all of
992 if ((arglist & CAM_ARG_INQ_MASK) == 0)
993 arglist |= CAM_ARG_INQ_MASK;
995 if (arglist & CAM_ARG_GET_STDINQ)
996 error = scsiinquiry(device, task_attr, retry_count, timeout);
1001 if (arglist & CAM_ARG_GET_SERIAL)
1002 scsiserial(device, task_attr, retry_count, timeout);
1004 if (arglist & CAM_ARG_GET_XFERRATE)
1005 error = camxferrate(device);
1011 scsiinquiry(struct cam_device *device, int task_attr, int retry_count,
1015 struct scsi_inquiry_data *inq_buf;
1018 ccb = cam_getccb(device);
1021 warnx("couldn't allocate CCB");
1025 /* cam_getccb cleans up the header, caller has to zero the payload */
1026 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1028 inq_buf = (struct scsi_inquiry_data *)malloc(
1029 sizeof(struct scsi_inquiry_data));
1031 if (inq_buf == NULL) {
1033 warnx("can't malloc memory for inquiry\n");
1036 bzero(inq_buf, sizeof(*inq_buf));
1039 * Note that although the size of the inquiry buffer is the full
1040 * 256 bytes specified in the SCSI spec, we only tell the device
1041 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
1042 * two reasons for this:
1044 * - The SCSI spec says that when a length field is only 1 byte,
1045 * a value of 0 will be interpreted as 256. Therefore
1046 * scsi_inquiry() will convert an inq_len (which is passed in as
1047 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
1048 * to 0. Evidently, very few devices meet the spec in that
1049 * regard. Some devices, like many Seagate disks, take the 0 as
1050 * 0, and don't return any data. One Pioneer DVD-R drive
1051 * returns more data than the command asked for.
1053 * So, since there are numerous devices that just don't work
1054 * right with the full inquiry size, we don't send the full size.
1056 * - The second reason not to use the full inquiry data length is
1057 * that we don't need it here. The only reason we issue a
1058 * standard inquiry is to get the vendor name, device name,
1059 * and revision so scsi_print_inquiry() can print them.
1061 * If, at some point in the future, more inquiry data is needed for
1062 * some reason, this code should use a procedure similar to the
1063 * probe code. i.e., issue a short inquiry, and determine from
1064 * the additional length passed back from the device how much
1065 * inquiry data the device supports. Once the amount the device
1066 * supports is determined, issue an inquiry for that amount and no
1071 scsi_inquiry(&ccb->csio,
1072 /* retries */ retry_count,
1074 /* tag_action */ task_attr,
1075 /* inq_buf */ (u_int8_t *)inq_buf,
1076 /* inq_len */ SHORT_INQUIRY_LENGTH,
1079 /* sense_len */ SSD_FULL_SIZE,
1080 /* timeout */ timeout ? timeout : 5000);
1082 /* Disable freezing the device queue */
1083 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1085 if (arglist & CAM_ARG_ERR_RECOVER)
1086 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1088 if (cam_send_ccb(device, ccb) < 0) {
1089 warn("error sending INQUIRY command");
1094 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1097 if (arglist & CAM_ARG_VERBOSE) {
1098 cam_error_print(device, ccb, CAM_ESF_ALL,
1099 CAM_EPF_ALL, stderr);
1110 fprintf(stdout, "%s%d: ", device->device_name,
1111 device->dev_unit_num);
1112 scsi_print_inquiry(inq_buf);
1120 scsiserial(struct cam_device *device, int task_attr, int retry_count,
1124 struct scsi_vpd_unit_serial_number *serial_buf;
1125 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
1128 ccb = cam_getccb(device);
1131 warnx("couldn't allocate CCB");
1135 /* cam_getccb cleans up the header, caller has to zero the payload */
1136 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1138 serial_buf = (struct scsi_vpd_unit_serial_number *)
1139 malloc(sizeof(*serial_buf));
1141 if (serial_buf == NULL) {
1143 warnx("can't malloc memory for serial number");
1147 scsi_inquiry(&ccb->csio,
1148 /*retries*/ retry_count,
1150 /* tag_action */ task_attr,
1151 /* inq_buf */ (u_int8_t *)serial_buf,
1152 /* inq_len */ sizeof(*serial_buf),
1154 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
1155 /* sense_len */ SSD_FULL_SIZE,
1156 /* timeout */ timeout ? timeout : 5000);
1158 /* Disable freezing the device queue */
1159 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1161 if (arglist & CAM_ARG_ERR_RECOVER)
1162 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1164 if (cam_send_ccb(device, ccb) < 0) {
1165 warn("error sending INQUIRY command");
1171 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1174 if (arglist & CAM_ARG_VERBOSE) {
1175 cam_error_print(device, ccb, CAM_ESF_ALL,
1176 CAM_EPF_ALL, stderr);
1187 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1188 serial_num[serial_buf->length] = '\0';
1190 if ((arglist & CAM_ARG_GET_STDINQ)
1191 || (arglist & CAM_ARG_GET_XFERRATE))
1192 fprintf(stdout, "%s%d: Serial Number ",
1193 device->device_name, device->dev_unit_num);
1195 fprintf(stdout, "%.60s\n", serial_num);
1203 camxferrate(struct cam_device *device)
1205 struct ccb_pathinq cpi;
1207 u_int32_t speed = 0;
1212 if ((retval = get_cpi(device, &cpi)) != 0)
1215 ccb = cam_getccb(device);
1218 warnx("couldn't allocate CCB");
1222 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
1224 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1225 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1227 if (((retval = cam_send_ccb(device, ccb)) < 0)
1228 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1229 const char error_string[] = "error getting transfer settings";
1234 warnx(error_string);
1236 if (arglist & CAM_ARG_VERBOSE)
1237 cam_error_print(device, ccb, CAM_ESF_ALL,
1238 CAM_EPF_ALL, stderr);
1242 goto xferrate_bailout;
1246 speed = cpi.base_transfer_speed;
1248 if (ccb->cts.transport == XPORT_SPI) {
1249 struct ccb_trans_settings_spi *spi =
1250 &ccb->cts.xport_specific.spi;
1252 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1253 freq = scsi_calc_syncsrate(spi->sync_period);
1256 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1257 speed *= (0x01 << spi->bus_width);
1259 } else if (ccb->cts.transport == XPORT_FC) {
1260 struct ccb_trans_settings_fc *fc =
1261 &ccb->cts.xport_specific.fc;
1263 if (fc->valid & CTS_FC_VALID_SPEED)
1264 speed = fc->bitrate;
1265 } else if (ccb->cts.transport == XPORT_SAS) {
1266 struct ccb_trans_settings_sas *sas =
1267 &ccb->cts.xport_specific.sas;
1269 if (sas->valid & CTS_SAS_VALID_SPEED)
1270 speed = sas->bitrate;
1271 } else if (ccb->cts.transport == XPORT_ATA) {
1272 struct ccb_trans_settings_pata *pata =
1273 &ccb->cts.xport_specific.ata;
1275 if (pata->valid & CTS_ATA_VALID_MODE)
1276 speed = ata_mode2speed(pata->mode);
1277 } else if (ccb->cts.transport == XPORT_SATA) {
1278 struct ccb_trans_settings_sata *sata =
1279 &ccb->cts.xport_specific.sata;
1281 if (sata->valid & CTS_SATA_VALID_REVISION)
1282 speed = ata_revision2speed(sata->revision);
1287 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1288 device->device_name, device->dev_unit_num,
1291 fprintf(stdout, "%s%d: %dKB/s transfers",
1292 device->device_name, device->dev_unit_num,
1296 if (ccb->cts.transport == XPORT_SPI) {
1297 struct ccb_trans_settings_spi *spi =
1298 &ccb->cts.xport_specific.spi;
1300 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1301 && (spi->sync_offset != 0))
1302 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1303 freq % 1000, spi->sync_offset);
1305 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1306 && (spi->bus_width > 0)) {
1307 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1308 && (spi->sync_offset != 0)) {
1309 fprintf(stdout, ", ");
1311 fprintf(stdout, " (");
1313 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1314 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1315 && (spi->sync_offset != 0)) {
1316 fprintf(stdout, ")");
1318 } else if (ccb->cts.transport == XPORT_ATA) {
1319 struct ccb_trans_settings_pata *pata =
1320 &ccb->cts.xport_specific.ata;
1323 if (pata->valid & CTS_ATA_VALID_MODE)
1324 printf("%s, ", ata_mode2string(pata->mode));
1325 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1326 printf("ATAPI %dbytes, ", pata->atapi);
1327 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1328 printf("PIO %dbytes", pata->bytecount);
1330 } else if (ccb->cts.transport == XPORT_SATA) {
1331 struct ccb_trans_settings_sata *sata =
1332 &ccb->cts.xport_specific.sata;
1335 if (sata->valid & CTS_SATA_VALID_REVISION)
1336 printf("SATA %d.x, ", sata->revision);
1339 if (sata->valid & CTS_SATA_VALID_MODE)
1340 printf("%s, ", ata_mode2string(sata->mode));
1341 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1342 printf("ATAPI %dbytes, ", sata->atapi);
1343 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1344 printf("PIO %dbytes", sata->bytecount);
1348 if (ccb->cts.protocol == PROTO_SCSI) {
1349 struct ccb_trans_settings_scsi *scsi =
1350 &ccb->cts.proto_specific.scsi;
1351 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1352 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1353 fprintf(stdout, ", Command Queueing Enabled");
1358 fprintf(stdout, "\n");
1368 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1370 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1371 ((u_int32_t)parm->lba_size_2 << 16);
1373 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1374 ((u_int64_t)parm->lba_size48_2 << 16) |
1375 ((u_int64_t)parm->lba_size48_3 << 32) |
1376 ((u_int64_t)parm->lba_size48_4 << 48);
1380 "Support Enabled Value\n");
1383 printf("Host Protected Area (HPA) ");
1384 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1385 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1386 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1389 printf("HPA - Security ");
1390 if (parm->support.command2 & ATA_SUPPORT_MAXSECURITY)
1391 printf("yes %s\n", (parm->enabled.command2 &
1392 ATA_SUPPORT_MAXSECURITY) ? "yes" : "no ");
1401 ataama_print(struct ata_params *parm, u_int64_t nativesize, int header)
1403 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1404 ((u_int32_t)parm->lba_size_2 << 16);
1406 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1407 ((u_int64_t)parm->lba_size48_2 << 16) |
1408 ((u_int64_t)parm->lba_size48_3 << 32) |
1409 ((u_int64_t)parm->lba_size48_4 << 48);
1413 "Support Enabled Value\n");
1416 printf("Accessible Max Address Config ");
1417 if (parm->support2 & ATA_SUPPORT_AMAX_ADDR) {
1418 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1419 printf("yes %s %ju/%ju\n",
1420 (nativesize > lba) ? "yes" : "no ", lba, nativesize);
1427 atasata(struct ata_params *parm)
1431 if (parm->satacapabilities != 0xffff &&
1432 parm->satacapabilities != 0x0000)
1439 atacapprint(struct ata_params *parm)
1442 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1443 ((u_int32_t)parm->lba_size_2 << 16);
1445 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1446 ((u_int64_t)parm->lba_size48_2 << 16) |
1447 ((u_int64_t)parm->lba_size48_3 << 32) |
1448 ((u_int64_t)parm->lba_size48_4 << 48);
1451 printf("protocol ");
1452 proto = (parm->config == ATA_PROTO_CFA) ? "CFA" :
1453 (parm->config & ATA_PROTO_ATAPI) ? "ATAPI" : "ATA";
1454 if (ata_version(parm->version_major) == 0) {
1455 printf("%s", proto);
1456 } else if (ata_version(parm->version_major) <= 7) {
1457 printf("%s-%d", proto,
1458 ata_version(parm->version_major));
1459 } else if (ata_version(parm->version_major) == 8) {
1460 printf("%s8-ACS", proto);
1463 ata_version(parm->version_major) - 7, proto);
1465 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1466 if (parm->satacapabilities & ATA_SATA_GEN3)
1467 printf(" SATA 3.x\n");
1468 else if (parm->satacapabilities & ATA_SATA_GEN2)
1469 printf(" SATA 2.x\n");
1470 else if (parm->satacapabilities & ATA_SATA_GEN1)
1471 printf(" SATA 1.x\n");
1477 printf("device model %.40s\n", parm->model);
1478 printf("firmware revision %.8s\n", parm->revision);
1479 printf("serial number %.20s\n", parm->serial);
1480 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1481 printf("WWN %04x%04x%04x%04x\n",
1482 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1484 printf("additional product id %.8s\n", parm->product_id);
1485 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1486 printf("media serial number %.30s\n",
1487 parm->media_serial);
1490 printf("cylinders %d\n", parm->cylinders);
1491 printf("heads %d\n", parm->heads);
1492 printf("sectors/track %d\n", parm->sectors);
1493 printf("sector size logical %u, physical %lu, offset %lu\n",
1494 ata_logical_sector_size(parm),
1495 (unsigned long)ata_physical_sector_size(parm),
1496 (unsigned long)ata_logical_sector_offset(parm));
1498 if (parm->config == ATA_PROTO_CFA ||
1499 (parm->support.command2 & ATA_SUPPORT_CFA))
1500 printf("CFA supported\n");
1502 printf("LBA%ssupported ",
1503 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1505 printf("%d sectors\n", lbasize);
1509 printf("LBA48%ssupported ",
1510 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1512 printf("%ju sectors\n", (uintmax_t)lbasize48);
1516 printf("PIO supported PIO");
1517 switch (ata_max_pmode(parm)) {
1533 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1534 printf(" w/o IORDY");
1537 printf("DMA%ssupported ",
1538 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1539 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1540 if (parm->mwdmamodes & 0xff) {
1542 if (parm->mwdmamodes & 0x04)
1544 else if (parm->mwdmamodes & 0x02)
1546 else if (parm->mwdmamodes & 0x01)
1550 if ((parm->atavalid & ATA_FLAG_88) &&
1551 (parm->udmamodes & 0xff)) {
1553 if (parm->udmamodes & 0x40)
1555 else if (parm->udmamodes & 0x20)
1557 else if (parm->udmamodes & 0x10)
1559 else if (parm->udmamodes & 0x08)
1561 else if (parm->udmamodes & 0x04)
1563 else if (parm->udmamodes & 0x02)
1565 else if (parm->udmamodes & 0x01)
1572 if (parm->media_rotation_rate == 1) {
1573 printf("media RPM non-rotating\n");
1574 } else if (parm->media_rotation_rate >= 0x0401 &&
1575 parm->media_rotation_rate <= 0xFFFE) {
1576 printf("media RPM %d\n",
1577 parm->media_rotation_rate);
1580 printf("Zoned-Device Commands ");
1581 switch (parm->support3 & ATA_SUPPORT_ZONE_MASK) {
1582 case ATA_SUPPORT_ZONE_DEV_MANAGED:
1583 printf("device managed\n");
1585 case ATA_SUPPORT_ZONE_HOST_AWARE:
1586 printf("host aware\n");
1593 "Support Enabled Value Vendor\n");
1594 printf("read ahead %s %s\n",
1595 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1596 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1597 printf("write cache %s %s\n",
1598 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1599 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1600 printf("flush cache %s %s\n",
1601 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1602 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1603 printf("Native Command Queuing (NCQ) ");
1604 if (atasata(parm) && (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1605 printf("yes %d tags\n",
1606 ATA_QUEUE_LEN(parm->queue) + 1);
1607 printf("NCQ Priority Information %s\n",
1608 parm->satacapabilities & ATA_SUPPORT_NCQ_PRIO ?
1610 printf("NCQ Non-Data Command %s\n",
1611 parm->satacapabilities2 & ATA_SUPPORT_NCQ_NON_DATA ?
1613 printf("NCQ Streaming %s\n",
1614 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1616 printf("Receive & Send FPDMA Queued %s\n",
1617 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1619 printf("NCQ Autosense %s\n",
1620 parm->satasupport & ATA_SUPPORT_NCQ_AUTOSENSE ?
1625 printf("SMART %s %s\n",
1626 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1627 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1628 printf("security %s %s\n",
1629 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1630 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1631 printf("power management %s %s\n",
1632 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1633 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1634 printf("microcode download %s %s\n",
1635 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1636 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1637 printf("advanced power management %s %s",
1638 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1639 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1640 if (parm->support.command2 & ATA_SUPPORT_APM) {
1641 printf(" %d/0x%02X\n",
1642 parm->apm_value & 0xff, parm->apm_value & 0xff);
1645 printf("automatic acoustic management %s %s",
1646 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1647 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1648 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1649 printf(" %d/0x%02X %d/0x%02X\n",
1650 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1651 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1652 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1653 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1656 printf("media status notification %s %s\n",
1657 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1658 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1659 printf("power-up in Standby %s %s\n",
1660 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1661 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1662 printf("write-read-verify %s %s",
1663 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1664 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1665 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1666 printf(" %d/0x%x\n",
1667 parm->wrv_mode, parm->wrv_mode);
1670 printf("unload %s %s\n",
1671 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1672 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1673 printf("general purpose logging %s %s\n",
1674 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1675 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1676 printf("free-fall %s %s\n",
1677 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1678 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1679 printf("sense data reporting %s %s\n",
1680 parm->support2 & ATA_SUPPORT_SENSE_REPORT ? "yes" : "no",
1681 parm->enabled2 & ATA_SUPPORT_SENSE_REPORT ? "yes" : "no");
1682 printf("extended power conditions %s %s\n",
1683 parm->support2 & ATA_SUPPORT_EPC ? "yes" : "no",
1684 parm->enabled2 & ATA_SUPPORT_EPC ? "yes" : "no");
1685 printf("device statistics notification %s %s\n",
1686 parm->support2 & ATA_SUPPORT_DSN ? "yes" : "no",
1687 parm->enabled2 & ATA_SUPPORT_DSN ? "yes" : "no");
1688 printf("Data Set Management (DSM/TRIM) ");
1689 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1691 printf("DSM - max 512byte blocks ");
1692 if (parm->max_dsm_blocks == 0x00)
1693 printf("yes not specified\n");
1696 parm->max_dsm_blocks);
1698 printf("DSM - deterministic read ");
1699 if (parm->support3 & ATA_SUPPORT_DRAT) {
1700 if (parm->support3 & ATA_SUPPORT_RZAT)
1701 printf("yes zeroed\n");
1703 printf("yes any value\n");
1710 printf("Trusted Computing %s\n",
1711 ((parm->tcg & 0xc000) == 0x4000) && (parm->tcg & ATA_SUPPORT_TCG) ?
1713 printf("encrypts all user data %s\n",
1714 parm->support3 & ATA_ENCRYPTS_ALL_USER_DATA ? "yes" : "no");
1715 printf("Sanitize ");
1716 if (parm->multi & ATA_SUPPORT_SANITIZE) {
1717 printf("yes\t\t%s%s%s\n",
1718 parm->multi & ATA_SUPPORT_BLOCK_ERASE_EXT ? "block, " : "",
1719 parm->multi & ATA_SUPPORT_OVERWRITE_EXT ? "overwrite, " : "",
1720 parm->multi & ATA_SUPPORT_CRYPTO_SCRAMBLE_EXT ? "crypto" : "");
1721 printf("Sanitize - commands allowed %s\n",
1722 parm->multi & ATA_SUPPORT_SANITIZE_ALLOWED ? "yes" : "no");
1723 printf("Sanitize - antifreeze lock %s\n",
1724 parm->multi & ATA_SUPPORT_ANTIFREEZE_LOCK_EXT ? "yes" : "no");
1731 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb)
1733 struct ata_pass_16 *ata_pass_16;
1734 struct ata_cmd ata_cmd;
1736 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1737 ata_cmd.command = ata_pass_16->command;
1738 ata_cmd.control = ata_pass_16->control;
1739 ata_cmd.features = ata_pass_16->features;
1741 if (arglist & CAM_ARG_VERBOSE) {
1742 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1743 ata_op_string(&ata_cmd),
1744 ccb->csio.ccb_h.timeout);
1747 /* Disable freezing the device queue */
1748 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1750 if (arglist & CAM_ARG_ERR_RECOVER)
1751 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1753 if (cam_send_ccb(device, ccb) < 0) {
1754 warn("error sending ATA %s via pass_16", ata_op_string(&ata_cmd));
1759 * Consider any non-CAM_REQ_CMP status as error and report it here,
1760 * unless caller set AP_FLAG_CHK_COND, in which case it is reponsible.
1762 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1763 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1764 warnx("ATA %s via pass_16 failed", ata_op_string(&ata_cmd));
1765 if (arglist & CAM_ARG_VERBOSE) {
1766 cam_error_print(device, ccb, CAM_ESF_ALL,
1767 CAM_EPF_ALL, stderr);
1777 ata_cam_send(struct cam_device *device, union ccb *ccb)
1779 if (arglist & CAM_ARG_VERBOSE) {
1780 warnx("sending ATA %s with timeout of %u msecs",
1781 ata_op_string(&(ccb->ataio.cmd)),
1782 ccb->ataio.ccb_h.timeout);
1785 /* Disable freezing the device queue */
1786 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1788 if (arglist & CAM_ARG_ERR_RECOVER)
1789 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1791 if (cam_send_ccb(device, ccb) < 0) {
1792 warn("error sending ATA %s", ata_op_string(&(ccb->ataio.cmd)));
1797 * Consider any non-CAM_REQ_CMP status as error and report it here,
1798 * unless caller set AP_FLAG_CHK_COND, in which case it is reponsible.
1800 if (!(ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT) &&
1801 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1802 warnx("ATA %s failed", ata_op_string(&(ccb->ataio.cmd)));
1803 if (arglist & CAM_ARG_VERBOSE) {
1804 cam_error_print(device, ccb, CAM_ESF_ALL,
1805 CAM_EPF_ALL, stderr);
1814 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1815 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1816 u_int8_t tag_action, u_int8_t command, u_int16_t features,
1817 u_int64_t lba, u_int16_t sector_count, u_int8_t *data_ptr,
1818 u_int16_t dxfer_len, int timeout)
1820 if (data_ptr != NULL) {
1821 if (flags & CAM_DIR_OUT)
1822 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1824 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1826 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1829 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1831 scsi_ata_pass_16(&ccb->csio,
1845 /*sense_len*/SSD_FULL_SIZE,
1848 return scsi_cam_pass_16_send(device, ccb);
1852 ata_try_pass_16(struct cam_device *device)
1854 struct ccb_pathinq cpi;
1856 if (get_cpi(device, &cpi) != 0) {
1857 warnx("couldn't get CPI");
1861 if (cpi.protocol == PROTO_SCSI) {
1862 /* possibly compatible with pass_16 */
1866 /* likely not compatible with pass_16 */
1871 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1872 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1873 u_int8_t tag_action, u_int8_t command, u_int16_t features,
1874 u_int64_t lba, u_int16_t sector_count, u_int8_t *data_ptr,
1875 u_int16_t dxfer_len, int timeout, int force48bit)
1879 retval = ata_try_pass_16(device);
1884 return (ata_do_pass_16(device, ccb, retries, flags, protocol,
1885 ata_flags, tag_action, command, features,
1886 lba, sector_count, data_ptr, dxfer_len,
1890 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1891 cam_fill_ataio(&ccb->ataio,
1900 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1901 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1903 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1905 if (ata_flags & AP_FLAG_CHK_COND)
1906 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1908 return ata_cam_send(device, ccb);
1912 dump_data(uint16_t *ptr, uint32_t len)
1916 for (i = 0; i < len / 2; i++) {
1918 printf(" %3d: ", i);
1919 printf("%04hx ", ptr[i]);
1928 atahpa_proc_resp(struct cam_device *device, union ccb *ccb, u_int64_t *hpasize)
1930 uint8_t error = 0, ata_device = 0, status = 0;
1935 retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
1938 if (arglist & CAM_ARG_VERBOSE) {
1939 cam_error_print(device, ccb, CAM_ESF_ALL,
1940 CAM_EPF_ALL, stderr);
1942 warnx("Can't get ATA command status");
1946 if (status & ATA_STATUS_ERROR) {
1947 if (arglist & CAM_ARG_VERBOSE) {
1948 cam_error_print(device, ccb, CAM_ESF_ALL,
1949 CAM_EPF_ALL, stderr);
1952 if (error & ATA_ERROR_ID_NOT_FOUND) {
1953 warnx("Max address has already been set since "
1954 "last power-on or hardware reset");
1955 } else if (hpasize == NULL)
1956 warnx("Command failed with ATA error");
1961 if (hpasize != NULL) {
1962 if (retval == 2 || retval == 6)
1971 ata_read_native_max(struct cam_device *device, int retry_count,
1972 u_int32_t timeout, union ccb *ccb,
1973 struct ata_params *parm, u_int64_t *hpasize)
1979 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1980 protocol = AP_PROTO_NON_DATA;
1983 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1984 protocol |= AP_EXTEND;
1986 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1989 error = ata_do_cmd(device,
1992 /*flags*/CAM_DIR_NONE,
1993 /*protocol*/protocol,
1994 /*ata_flags*/AP_FLAG_CHK_COND,
1995 /*tag_action*/MSG_SIMPLE_Q_TAG,
2002 timeout ? timeout : 5000,
2008 return atahpa_proc_resp(device, ccb, hpasize);
2012 atahpa_set_max(struct cam_device *device, int retry_count,
2013 u_int32_t timeout, union ccb *ccb,
2014 int is48bit, u_int64_t maxsize, int persist)
2020 protocol = AP_PROTO_NON_DATA;
2023 cmd = ATA_SET_MAX_ADDRESS48;
2024 protocol |= AP_EXTEND;
2026 cmd = ATA_SET_MAX_ADDRESS;
2029 /* lba's are zero indexed so the max lba is requested max - 1 */
2033 error = ata_do_cmd(device,
2036 /*flags*/CAM_DIR_NONE,
2037 /*protocol*/protocol,
2038 /*ata_flags*/AP_FLAG_CHK_COND,
2039 /*tag_action*/MSG_SIMPLE_Q_TAG,
2041 /*features*/ATA_HPA_FEAT_MAX_ADDR,
2043 /*sector_count*/persist,
2046 timeout ? timeout : 1000,
2052 return atahpa_proc_resp(device, ccb, NULL);
2056 atahpa_password(struct cam_device *device, int retry_count,
2057 u_int32_t timeout, union ccb *ccb,
2058 int is48bit, struct ata_set_max_pwd *pwd)
2063 protocol = AP_PROTO_PIO_OUT;
2064 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2066 return (ata_do_cmd(device,
2069 /*flags*/CAM_DIR_OUT,
2070 /*protocol*/protocol,
2071 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2072 AP_FLAG_TLEN_SECT_CNT,
2073 /*tag_action*/MSG_SIMPLE_Q_TAG,
2075 /*features*/ATA_HPA_FEAT_SET_PWD,
2077 /*sector_count*/sizeof(*pwd) / 512,
2078 /*data_ptr*/(u_int8_t*)pwd,
2079 /*dxfer_len*/sizeof(*pwd),
2080 timeout ? timeout : 1000,
2085 atahpa_lock(struct cam_device *device, int retry_count,
2086 u_int32_t timeout, union ccb *ccb, int is48bit)
2091 protocol = AP_PROTO_NON_DATA;
2092 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2094 return (ata_do_cmd(device,
2097 /*flags*/CAM_DIR_NONE,
2098 /*protocol*/protocol,
2100 /*tag_action*/MSG_SIMPLE_Q_TAG,
2102 /*features*/ATA_HPA_FEAT_LOCK,
2107 timeout ? timeout : 1000,
2112 atahpa_unlock(struct cam_device *device, int retry_count,
2113 u_int32_t timeout, union ccb *ccb,
2114 int is48bit, struct ata_set_max_pwd *pwd)
2119 protocol = AP_PROTO_PIO_OUT;
2120 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2122 return (ata_do_cmd(device,
2125 /*flags*/CAM_DIR_OUT,
2126 /*protocol*/protocol,
2127 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2128 AP_FLAG_TLEN_SECT_CNT,
2129 /*tag_action*/MSG_SIMPLE_Q_TAG,
2131 /*features*/ATA_HPA_FEAT_UNLOCK,
2133 /*sector_count*/sizeof(*pwd) / 512,
2134 /*data_ptr*/(u_int8_t*)pwd,
2135 /*dxfer_len*/sizeof(*pwd),
2136 timeout ? timeout : 1000,
2141 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2142 u_int32_t timeout, union ccb *ccb, int is48bit)
2147 protocol = AP_PROTO_NON_DATA;
2148 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2150 return (ata_do_cmd(device,
2153 /*flags*/CAM_DIR_NONE,
2154 /*protocol*/protocol,
2156 /*tag_action*/MSG_SIMPLE_Q_TAG,
2158 /*features*/ATA_HPA_FEAT_FREEZE,
2163 timeout ? timeout : 1000,
2168 ata_get_native_max(struct cam_device *device, int retry_count,
2169 u_int32_t timeout, union ccb *ccb,
2170 u_int64_t *nativesize)
2174 error = ata_do_cmd(device,
2177 /*flags*/CAM_DIR_NONE,
2178 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2179 /*ata_flags*/AP_FLAG_CHK_COND,
2180 /*tag_action*/MSG_SIMPLE_Q_TAG,
2181 /*command*/ATA_AMAX_ADDR,
2182 /*features*/ATA_AMAX_ADDR_GET,
2187 timeout ? timeout : 30 * 1000,
2193 return atahpa_proc_resp(device, ccb, nativesize);
2197 ataama_set(struct cam_device *device, int retry_count,
2198 u_int32_t timeout, union ccb *ccb, u_int64_t maxsize)
2202 /* lba's are zero indexed so the max lba is requested max - 1 */
2206 error = ata_do_cmd(device,
2209 /*flags*/CAM_DIR_NONE,
2210 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2211 /*ata_flags*/AP_FLAG_CHK_COND,
2212 /*tag_action*/MSG_SIMPLE_Q_TAG,
2213 /*command*/ATA_AMAX_ADDR,
2214 /*features*/ATA_AMAX_ADDR_SET,
2219 timeout ? timeout : 30 * 1000,
2225 return atahpa_proc_resp(device, ccb, NULL);
2229 ataama_freeze(struct cam_device *device, int retry_count,
2230 u_int32_t timeout, union ccb *ccb)
2233 return (ata_do_cmd(device,
2236 /*flags*/CAM_DIR_NONE,
2237 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2239 /*tag_action*/MSG_SIMPLE_Q_TAG,
2240 /*command*/ATA_AMAX_ADDR,
2241 /*features*/ATA_AMAX_ADDR_FREEZE,
2246 timeout ? timeout : 30 * 1000,
2251 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2252 union ccb *ccb, struct ata_params** ident_bufp)
2254 struct ata_params *ident_buf;
2255 struct ccb_pathinq cpi;
2256 struct ccb_getdev cgd;
2259 u_int8_t command, retry_command;
2261 if (get_cpi(device, &cpi) != 0) {
2262 warnx("couldn't get CPI");
2266 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2267 if (cpi.protocol == PROTO_ATA) {
2268 if (get_cgd(device, &cgd) != 0) {
2269 warnx("couldn't get CGD");
2273 command = (cgd.protocol == PROTO_ATA) ?
2274 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2277 /* We don't know which for sure so try both */
2278 command = ATA_ATA_IDENTIFY;
2279 retry_command = ATA_ATAPI_IDENTIFY;
2282 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2284 warnx("can't calloc memory for identify\n");
2289 error = ata_do_cmd(device,
2291 /*retries*/retry_count,
2292 /*flags*/CAM_DIR_IN,
2293 /*protocol*/AP_PROTO_PIO_IN,
2294 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2295 AP_FLAG_TLEN_SECT_CNT,
2296 /*tag_action*/MSG_SIMPLE_Q_TAG,
2300 /*sector_count*/sizeof(struct ata_params) / 512,
2301 /*data_ptr*/(u_int8_t *)ptr,
2302 /*dxfer_len*/sizeof(struct ata_params),
2303 /*timeout*/timeout ? timeout : 30 * 1000,
2307 if (retry_command != 0) {
2308 command = retry_command;
2316 ident_buf = (struct ata_params *)ptr;
2317 ata_param_fixup(ident_buf);
2320 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2325 /* check for invalid (all zero) response */
2327 warnx("Invalid identify response detected");
2332 *ident_bufp = ident_buf;
2339 ataidentify(struct cam_device *device, int retry_count, int timeout)
2342 struct ata_params *ident_buf;
2343 u_int64_t hpasize = 0, nativesize = 0;
2345 if ((ccb = cam_getccb(device)) == NULL) {
2346 warnx("couldn't allocate CCB");
2350 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2355 if (arglist & CAM_ARG_VERBOSE) {
2356 printf("%s%d: Raw identify data:\n",
2357 device->device_name, device->dev_unit_num);
2358 dump_data((void*)ident_buf, sizeof(struct ata_params));
2361 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2362 ata_read_native_max(device, retry_count, timeout, ccb,
2363 ident_buf, &hpasize);
2365 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR) {
2366 ata_get_native_max(device, retry_count, timeout, ccb,
2370 printf("%s%d: ", device->device_name, device->dev_unit_num);
2371 ata_print_ident(ident_buf);
2372 camxferrate(device);
2373 atacapprint(ident_buf);
2374 atahpa_print(ident_buf, hpasize, 0);
2375 ataama_print(ident_buf, nativesize, 0);
2385 nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused)
2387 struct nvme_controller_data cdata;
2389 if (nvme_get_cdata(device, &cdata))
2391 nvme_print_controller(&cdata);
2398 identify(struct cam_device *device, int retry_count, int timeout)
2401 struct ccb_pathinq cpi;
2403 if (get_cpi(device, &cpi) != 0) {
2404 warnx("couldn't get CPI");
2408 if (cpi.protocol == PROTO_NVME) {
2409 return (nvmeidentify(device, retry_count, timeout));
2412 return (ataidentify(device, retry_count, timeout));
2417 ATA_SECURITY_ACTION_PRINT,
2418 ATA_SECURITY_ACTION_FREEZE,
2419 ATA_SECURITY_ACTION_UNLOCK,
2420 ATA_SECURITY_ACTION_DISABLE,
2421 ATA_SECURITY_ACTION_ERASE,
2422 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2423 ATA_SECURITY_ACTION_SET_PASSWORD
2427 atasecurity_print_time(u_int16_t tw)
2431 printf("unspecified");
2433 printf("> 508 min");
2435 printf("%i min", 2 * tw);
2439 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2443 return 2 * 3600 * 1000; /* default: two hours */
2444 else if (timeout > 255)
2445 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2447 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2452 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2456 bzero(&cmd, sizeof(cmd));
2457 cmd.command = command;
2458 printf("Issuing %s", ata_op_string(&cmd));
2461 char pass[sizeof(pwd->password)+1];
2463 /* pwd->password may not be null terminated */
2464 pass[sizeof(pwd->password)] = '\0';
2465 strncpy(pass, pwd->password, sizeof(pwd->password));
2466 printf(" password='%s', user='%s'",
2468 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2471 if (command == ATA_SECURITY_SET_PASSWORD) {
2472 printf(", mode='%s'",
2473 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2474 "maximum" : "high");
2482 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2483 int retry_count, u_int32_t timeout, int quiet)
2487 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2489 return ata_do_cmd(device,
2492 /*flags*/CAM_DIR_NONE,
2493 /*protocol*/AP_PROTO_NON_DATA,
2495 /*tag_action*/MSG_SIMPLE_Q_TAG,
2496 /*command*/ATA_SECURITY_FREEZE_LOCK,
2507 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2508 int retry_count, u_int32_t timeout,
2509 struct ata_security_password *pwd, int quiet)
2513 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2515 return ata_do_cmd(device,
2518 /*flags*/CAM_DIR_OUT,
2519 /*protocol*/AP_PROTO_PIO_OUT,
2520 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2521 AP_FLAG_TLEN_SECT_CNT,
2522 /*tag_action*/MSG_SIMPLE_Q_TAG,
2523 /*command*/ATA_SECURITY_UNLOCK,
2526 /*sector_count*/sizeof(*pwd) / 512,
2527 /*data_ptr*/(u_int8_t *)pwd,
2528 /*dxfer_len*/sizeof(*pwd),
2534 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2535 int retry_count, u_int32_t timeout,
2536 struct ata_security_password *pwd, int quiet)
2540 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2541 return ata_do_cmd(device,
2544 /*flags*/CAM_DIR_OUT,
2545 /*protocol*/AP_PROTO_PIO_OUT,
2546 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2547 AP_FLAG_TLEN_SECT_CNT,
2548 /*tag_action*/MSG_SIMPLE_Q_TAG,
2549 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2552 /*sector_count*/sizeof(*pwd) / 512,
2553 /*data_ptr*/(u_int8_t *)pwd,
2554 /*dxfer_len*/sizeof(*pwd),
2561 atasecurity_erase_confirm(struct cam_device *device,
2562 struct ata_params* ident_buf)
2565 printf("\nYou are about to ERASE ALL DATA from the following"
2566 " device:\n%s%d,%s%d: ", device->device_name,
2567 device->dev_unit_num, device->given_dev_name,
2568 device->given_unit_number);
2569 ata_print_ident(ident_buf);
2573 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2575 if (fgets(str, sizeof(str), stdin) != NULL) {
2576 if (strncasecmp(str, "yes", 3) == 0) {
2578 } else if (strncasecmp(str, "no", 2) == 0) {
2581 printf("Please answer \"yes\" or "
2592 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2593 int retry_count, u_int32_t timeout,
2594 u_int32_t erase_timeout,
2595 struct ata_security_password *pwd, int quiet)
2600 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2602 error = ata_do_cmd(device,
2605 /*flags*/CAM_DIR_NONE,
2606 /*protocol*/AP_PROTO_NON_DATA,
2608 /*tag_action*/MSG_SIMPLE_Q_TAG,
2609 /*command*/ATA_SECURITY_ERASE_PREPARE,
2622 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2624 error = ata_do_cmd(device,
2627 /*flags*/CAM_DIR_OUT,
2628 /*protocol*/AP_PROTO_PIO_OUT,
2629 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2630 AP_FLAG_TLEN_SECT_CNT,
2631 /*tag_action*/MSG_SIMPLE_Q_TAG,
2632 /*command*/ATA_SECURITY_ERASE_UNIT,
2635 /*sector_count*/sizeof(*pwd) / 512,
2636 /*data_ptr*/(u_int8_t *)pwd,
2637 /*dxfer_len*/sizeof(*pwd),
2638 /*timeout*/erase_timeout,
2641 if (error == 0 && quiet == 0)
2642 printf("\nErase Complete\n");
2648 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2649 int retry_count, u_int32_t timeout,
2650 struct ata_security_password *pwd, int quiet)
2654 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2656 return ata_do_cmd(device,
2659 /*flags*/CAM_DIR_OUT,
2660 /*protocol*/AP_PROTO_PIO_OUT,
2661 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2662 AP_FLAG_TLEN_SECT_CNT,
2663 /*tag_action*/MSG_SIMPLE_Q_TAG,
2664 /*command*/ATA_SECURITY_SET_PASSWORD,
2667 /*sector_count*/sizeof(*pwd) / 512,
2668 /*data_ptr*/(u_int8_t *)pwd,
2669 /*dxfer_len*/sizeof(*pwd),
2675 atasecurity_print(struct ata_params *parm)
2678 printf("\nSecurity Option Value\n");
2679 if (arglist & CAM_ARG_VERBOSE) {
2680 printf("status %04x\n",
2681 parm->security_status);
2683 printf("supported %s\n",
2684 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2685 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2687 printf("enabled %s\n",
2688 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2689 printf("drive locked %s\n",
2690 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2691 printf("security config frozen %s\n",
2692 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2693 printf("count expired %s\n",
2694 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2695 printf("security level %s\n",
2696 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2697 printf("enhanced erase supported %s\n",
2698 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2699 printf("erase time ");
2700 atasecurity_print_time(parm->erase_time);
2702 printf("enhanced erase time ");
2703 atasecurity_print_time(parm->enhanced_erase_time);
2705 printf("master password rev %04x%s\n",
2706 parm->master_passwd_revision,
2707 parm->master_passwd_revision == 0x0000 ||
2708 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2712 * Validates and copies the password in optarg to the passed buffer.
2713 * If the password in optarg is the same length as the buffer then
2714 * the data will still be copied but no null termination will occur.
2717 ata_getpwd(u_int8_t *passwd, int max, char opt)
2721 len = strlen(optarg);
2723 warnx("-%c password is too long", opt);
2725 } else if (len == 0) {
2726 warnx("-%c password is missing", opt);
2728 } else if (optarg[0] == '-'){
2729 warnx("-%c password starts with '-' (generic arg?)", opt);
2731 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2732 warnx("-%c password conflicts with existing password from -%c",
2737 /* Callers pass in a buffer which does NOT need to be terminated */
2738 strncpy(passwd, optarg, max);
2745 ATA_HPA_ACTION_PRINT,
2746 ATA_HPA_ACTION_SET_MAX,
2747 ATA_HPA_ACTION_SET_PWD,
2748 ATA_HPA_ACTION_LOCK,
2749 ATA_HPA_ACTION_UNLOCK,
2750 ATA_HPA_ACTION_FREEZE_LOCK
2754 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2755 u_int64_t maxsize, int persist)
2757 printf("\nYou are about to configure HPA to limit the user accessible\n"
2758 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2759 persist ? "persistently" : "temporarily",
2760 device->device_name, device->dev_unit_num,
2761 device->given_dev_name, device->given_unit_number);
2762 ata_print_ident(ident_buf);
2766 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2768 if (NULL != fgets(str, sizeof(str), stdin)) {
2769 if (0 == strncasecmp(str, "yes", 3)) {
2771 } else if (0 == strncasecmp(str, "no", 2)) {
2774 printf("Please answer \"yes\" or "
2785 atahpa(struct cam_device *device, int retry_count, int timeout,
2786 int argc, char **argv, char *combinedopt)
2789 struct ata_params *ident_buf;
2790 struct ccb_getdev cgd;
2791 struct ata_set_max_pwd pwd;
2792 int error, confirm, quiet, c, action, actions, persist;
2793 int security, is48bit, pwdsize;
2794 u_int64_t hpasize, maxsize;
2803 memset(&pwd, 0, sizeof(pwd));
2805 /* default action is to print hpa information */
2806 action = ATA_HPA_ACTION_PRINT;
2807 pwdsize = sizeof(pwd.password);
2809 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2812 action = ATA_HPA_ACTION_SET_MAX;
2813 maxsize = strtoumax(optarg, NULL, 0);
2818 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2820 action = ATA_HPA_ACTION_SET_PWD;
2826 action = ATA_HPA_ACTION_LOCK;
2832 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2834 action = ATA_HPA_ACTION_UNLOCK;
2840 action = ATA_HPA_ACTION_FREEZE_LOCK;
2860 warnx("too many hpa actions specified");
2864 if (get_cgd(device, &cgd) != 0) {
2865 warnx("couldn't get CGD");
2869 ccb = cam_getccb(device);
2871 warnx("couldn't allocate CCB");
2875 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2882 printf("%s%d: ", device->device_name, device->dev_unit_num);
2883 ata_print_ident(ident_buf);
2884 camxferrate(device);
2887 if (action == ATA_HPA_ACTION_PRINT) {
2889 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)
2890 ata_read_native_max(device, retry_count, timeout, ccb,
2891 ident_buf, &hpasize);
2892 atahpa_print(ident_buf, hpasize, 1);
2899 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2900 warnx("HPA is not supported by this device");
2906 if (security && !(ident_buf->support.command2 & ATA_SUPPORT_MAXSECURITY)) {
2907 warnx("HPA Security is not supported by this device");
2913 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2916 * The ATA spec requires:
2917 * 1. Read native max addr is called directly before set max addr
2918 * 2. Read native max addr is NOT called before any other set max call
2921 case ATA_HPA_ACTION_SET_MAX:
2923 atahpa_set_confirm(device, ident_buf, maxsize,
2930 error = ata_read_native_max(device, retry_count, timeout,
2931 ccb, ident_buf, &hpasize);
2933 error = atahpa_set_max(device, retry_count, timeout,
2934 ccb, is48bit, maxsize, persist);
2937 /* redo identify to get new values */
2938 error = ata_do_identify(device,
2939 retry_count, timeout, ccb,
2941 atahpa_print(ident_buf, hpasize, 1);
2943 /* Hint CAM to reprobe the device. */
2949 case ATA_HPA_ACTION_SET_PWD:
2950 error = atahpa_password(device, retry_count, timeout,
2951 ccb, is48bit, &pwd);
2952 if (error == 0 && quiet == 0)
2953 printf("HPA password has been set\n");
2956 case ATA_HPA_ACTION_LOCK:
2957 error = atahpa_lock(device, retry_count, timeout,
2959 if (error == 0 && quiet == 0)
2960 printf("HPA has been locked\n");
2963 case ATA_HPA_ACTION_UNLOCK:
2964 error = atahpa_unlock(device, retry_count, timeout,
2965 ccb, is48bit, &pwd);
2966 if (error == 0 && quiet == 0)
2967 printf("HPA has been unlocked\n");
2970 case ATA_HPA_ACTION_FREEZE_LOCK:
2971 error = atahpa_freeze_lock(device, retry_count, timeout,
2973 if (error == 0 && quiet == 0)
2974 printf("HPA has been frozen\n");
2978 errx(1, "Option currently not supported");
2988 ATA_AMA_ACTION_PRINT,
2989 ATA_AMA_ACTION_SET_MAX,
2990 ATA_AMA_ACTION_FREEZE_LOCK
2994 ataama(struct cam_device *device, int retry_count, int timeout,
2995 int argc, char **argv, char *combinedopt)
2998 struct ata_params *ident_buf;
2999 struct ccb_getdev cgd;
3000 int error, quiet, c, action, actions;
3001 u_int64_t nativesize, maxsize;
3007 /* default action is to print AMA information */
3008 action = ATA_AMA_ACTION_PRINT;
3010 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3013 action = ATA_AMA_ACTION_SET_MAX;
3014 maxsize = strtoumax(optarg, NULL, 0);
3019 action = ATA_AMA_ACTION_FREEZE_LOCK;
3030 warnx("too many AMA actions specified");
3034 if (get_cgd(device, &cgd) != 0) {
3035 warnx("couldn't get CGD");
3039 ccb = cam_getccb(device);
3041 warnx("couldn't allocate CCB");
3045 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3052 printf("%s%d: ", device->device_name, device->dev_unit_num);
3053 ata_print_ident(ident_buf);
3054 camxferrate(device);
3057 if (action == ATA_AMA_ACTION_PRINT) {
3059 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)
3060 ata_get_native_max(device, retry_count, timeout, ccb,
3062 ataama_print(ident_buf, nativesize, 1);
3069 if (!(ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)) {
3070 warnx("Accessible Max Address is not supported by this device");
3077 case ATA_AMA_ACTION_SET_MAX:
3078 error = ata_get_native_max(device, retry_count, timeout, ccb,
3081 error = ataama_set(device, retry_count, timeout,
3085 /* redo identify to get new values */
3086 error = ata_do_identify(device,
3087 retry_count, timeout, ccb,
3089 ataama_print(ident_buf, nativesize, 1);
3091 /* Hint CAM to reprobe the device. */
3097 case ATA_AMA_ACTION_FREEZE_LOCK:
3098 error = ataama_freeze(device, retry_count, timeout,
3100 if (error == 0 && quiet == 0)
3101 printf("Accessible Max Address has been frozen\n");
3105 errx(1, "Option currently not supported");
3115 atasecurity(struct cam_device *device, int retry_count, int timeout,
3116 int argc, char **argv, char *combinedopt)
3119 struct ata_params *ident_buf;
3120 int error, confirm, quiet, c, action, actions, setpwd;
3121 int security_enabled, erase_timeout, pwdsize;
3122 struct ata_security_password pwd;
3130 memset(&pwd, 0, sizeof(pwd));
3132 /* default action is to print security information */
3133 action = ATA_SECURITY_ACTION_PRINT;
3135 /* user is master by default as its safer that way */
3136 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3137 pwdsize = sizeof(pwd.password);
3139 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3142 action = ATA_SECURITY_ACTION_FREEZE;
3147 if (strcasecmp(optarg, "user") == 0) {
3148 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
3149 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
3150 } else if (strcasecmp(optarg, "master") == 0) {
3151 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3152 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
3154 warnx("-U argument '%s' is invalid (must be "
3155 "'user' or 'master')", optarg);
3161 if (strcasecmp(optarg, "high") == 0) {
3162 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3163 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3164 } else if (strcasecmp(optarg, "maximum") == 0) {
3165 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3166 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3168 warnx("-l argument '%s' is unknown (must be "
3169 "'high' or 'maximum')", optarg);
3175 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3177 action = ATA_SECURITY_ACTION_UNLOCK;
3182 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3184 action = ATA_SECURITY_ACTION_DISABLE;
3189 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3191 action = ATA_SECURITY_ACTION_ERASE;
3196 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3198 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3199 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3204 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3207 if (action == ATA_SECURITY_ACTION_PRINT)
3208 action = ATA_SECURITY_ACTION_SET_PASSWORD;
3210 * Don't increment action as this can be combined
3211 * with other actions.
3224 erase_timeout = atoi(optarg) * 1000;
3230 warnx("too many security actions specified");
3234 if ((ccb = cam_getccb(device)) == NULL) {
3235 warnx("couldn't allocate CCB");
3239 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3246 printf("%s%d: ", device->device_name, device->dev_unit_num);
3247 ata_print_ident(ident_buf);
3248 camxferrate(device);
3251 if (action == ATA_SECURITY_ACTION_PRINT) {
3252 atasecurity_print(ident_buf);
3258 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3259 warnx("Security not supported");
3265 /* default timeout 15 seconds the same as linux hdparm */
3266 timeout = timeout ? timeout : 15 * 1000;
3268 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3270 /* first set the password if requested */
3272 /* confirm we can erase before setting the password if erasing */
3274 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3275 action == ATA_SECURITY_ACTION_ERASE) &&
3276 atasecurity_erase_confirm(device, ident_buf) == 0) {
3282 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3283 pwd.revision = ident_buf->master_passwd_revision;
3284 if (pwd.revision != 0 && pwd.revision != 0xfff &&
3285 --pwd.revision == 0) {
3286 pwd.revision = 0xfffe;
3289 error = atasecurity_set_password(device, ccb, retry_count,
3290 timeout, &pwd, quiet);
3296 security_enabled = 1;
3300 case ATA_SECURITY_ACTION_FREEZE:
3301 error = atasecurity_freeze(device, ccb, retry_count,
3305 case ATA_SECURITY_ACTION_UNLOCK:
3306 if (security_enabled) {
3307 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3308 error = atasecurity_unlock(device, ccb,
3309 retry_count, timeout, &pwd, quiet);
3311 warnx("Can't unlock, drive is not locked");
3315 warnx("Can't unlock, security is disabled");
3320 case ATA_SECURITY_ACTION_DISABLE:
3321 if (security_enabled) {
3322 /* First unlock the drive if its locked */
3323 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3324 error = atasecurity_unlock(device, ccb,
3332 error = atasecurity_disable(device,
3340 warnx("Can't disable security (already disabled)");
3345 case ATA_SECURITY_ACTION_ERASE:
3346 if (security_enabled) {
3347 if (erase_timeout == 0) {
3348 erase_timeout = atasecurity_erase_timeout_msecs(
3349 ident_buf->erase_time);
3352 error = atasecurity_erase(device, ccb, retry_count,
3353 timeout, erase_timeout, &pwd, quiet);
3355 warnx("Can't secure erase (security is disabled)");
3360 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3361 if (security_enabled) {
3362 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3363 if (erase_timeout == 0) {
3365 atasecurity_erase_timeout_msecs(
3366 ident_buf->enhanced_erase_time);
3369 error = atasecurity_erase(device, ccb,
3370 retry_count, timeout,
3371 erase_timeout, &pwd,
3374 warnx("Enhanced erase is not supported");
3378 warnx("Can't secure erase (enhanced), "
3379 "(security is disabled)");
3392 * Convert periph name into a bus, target and lun.
3394 * Returns the number of parsed components, or 0.
3397 parse_btl_name(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3398 cam_argmask *arglst)
3403 bzero(&ccb, sizeof(ccb));
3404 ccb.ccb_h.func_code = XPT_GDEVLIST;
3405 if (cam_get_device(tstr, ccb.cgdl.periph_name,
3406 sizeof(ccb.cgdl.periph_name), &ccb.cgdl.unit_number) == -1) {
3407 warnx("%s", cam_errbuf);
3412 * Attempt to get the passthrough device. This ioctl will
3413 * fail if the device name is null, if the device doesn't
3414 * exist, or if the passthrough driver isn't in the kernel.
3416 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3417 warn("Unable to open %s", XPT_DEVICE);
3420 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3421 warn("Unable to find bus:target:lun for device %s%d",
3422 ccb.cgdl.periph_name, ccb.cgdl.unit_number);
3427 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3428 const struct cam_status_entry *entry;
3430 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3431 warnx("Unable to find bus:target_lun for device %s%d, "
3432 "CAM status: %s (%#x)",
3433 ccb.cgdl.periph_name, ccb.cgdl.unit_number,
3434 entry ? entry->status_text : "Unknown",
3440 * The kernel fills in the bus/target/lun. We don't
3441 * need the passthrough device name and unit number since
3442 * we aren't going to open it.
3444 *bus = ccb.ccb_h.path_id;
3445 *target = ccb.ccb_h.target_id;
3446 *lun = ccb.ccb_h.target_lun;
3447 *arglst |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3452 * Parse out a bus, or a bus, target and lun in the following
3458 * Returns the number of parsed components, or 0.
3461 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3462 cam_argmask *arglst)
3467 *bus = CAM_BUS_WILDCARD;
3468 *target = CAM_TARGET_WILDCARD;
3469 *lun = CAM_LUN_WILDCARD;
3471 while (isspace(*tstr) && (*tstr != '\0'))
3474 if (strncasecmp(tstr, "all", strlen("all")) == 0) {
3475 arglist |= CAM_ARG_BUS;
3479 if (!isdigit(*tstr))
3480 return (parse_btl_name(tstr, bus, target, lun, arglst));
3482 tmpstr = strsep(&tstr, ":");
3483 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3484 *bus = strtol(tmpstr, &end, 0);
3487 *arglst |= CAM_ARG_BUS;
3489 tmpstr = strsep(&tstr, ":");
3490 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3491 *target = strtol(tmpstr, &end, 0);
3494 *arglst |= CAM_ARG_TARGET;
3496 tmpstr = strsep(&tstr, ":");
3497 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3498 *lun = strtoll(tmpstr, &end, 0);
3501 *arglst |= CAM_ARG_LUN;
3511 dorescan_or_reset(int argc, char **argv, int rescan)
3513 static const char must[] =
3514 "you must specify \"all\", a bus, a bus:target:lun or periph to %s";
3516 path_id_t bus = CAM_BUS_WILDCARD;
3517 target_id_t target = CAM_TARGET_WILDCARD;
3518 lun_id_t lun = CAM_LUN_WILDCARD;
3522 warnx(must, rescan? "rescan" : "reset");
3526 tstr = argv[optind];
3527 while (isspace(*tstr) && (*tstr != '\0'))
3529 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3530 arglist |= CAM_ARG_BUS;
3532 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3533 if (rv != 1 && rv != 3) {
3534 warnx(must, rescan ? "rescan" : "reset");
3539 if (arglist & CAM_ARG_LUN)
3540 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3542 error = rescan_or_reset_bus(bus, rescan);
3548 rescan_or_reset_bus(path_id_t bus, int rescan)
3550 union ccb *ccb = NULL, *matchccb = NULL;
3551 int fd = -1, retval;
3556 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3557 warnx("error opening transport layer device %s", XPT_DEVICE);
3558 warn("%s", XPT_DEVICE);
3562 ccb = malloc(sizeof(*ccb));
3564 warn("failed to allocate CCB");
3568 bzero(ccb, sizeof(*ccb));
3570 if (bus != CAM_BUS_WILDCARD) {
3571 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3572 ccb->ccb_h.path_id = bus;
3573 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3574 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3575 ccb->crcn.flags = CAM_FLAG_NONE;
3577 /* run this at a low priority */
3578 ccb->ccb_h.pinfo.priority = 5;
3580 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3581 warn("CAMIOCOMMAND ioctl failed");
3586 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3587 fprintf(stdout, "%s of bus %d was successful\n",
3588 rescan ? "Re-scan" : "Reset", bus);
3590 fprintf(stdout, "%s of bus %d returned error %#x\n",
3591 rescan ? "Re-scan" : "Reset", bus,
3592 ccb->ccb_h.status & CAM_STATUS_MASK);
3601 * The right way to handle this is to modify the xpt so that it can
3602 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3603 * that isn't implemented, so instead we enumerate the buses and
3604 * send the rescan or reset to those buses in the case where the
3605 * given bus is -1 (wildcard). We don't send a rescan or reset
3606 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3607 * no-op, sending a rescan to the xpt bus would result in a status of
3610 matchccb = malloc(sizeof(*matchccb));
3611 if (matchccb == NULL) {
3612 warn("failed to allocate CCB");
3616 bzero(matchccb, sizeof(*matchccb));
3617 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3618 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3619 bufsize = sizeof(struct dev_match_result) * 20;
3620 matchccb->cdm.match_buf_len = bufsize;
3621 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3622 if (matchccb->cdm.matches == NULL) {
3623 warnx("can't malloc memory for matches");
3627 matchccb->cdm.num_matches = 0;
3629 matchccb->cdm.num_patterns = 1;
3630 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3632 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3633 matchccb->cdm.pattern_buf_len);
3634 if (matchccb->cdm.patterns == NULL) {
3635 warnx("can't malloc memory for patterns");
3639 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3640 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3645 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3646 warn("CAMIOCOMMAND ioctl failed");
3651 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3652 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3653 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3654 warnx("got CAM error %#x, CDM error %d\n",
3655 matchccb->ccb_h.status, matchccb->cdm.status);
3660 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3661 struct bus_match_result *bus_result;
3663 /* This shouldn't happen. */
3664 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3667 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3670 * We don't want to rescan or reset the xpt bus.
3673 if (bus_result->path_id == CAM_XPT_PATH_ID)
3676 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3678 ccb->ccb_h.path_id = bus_result->path_id;
3679 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3680 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3681 ccb->crcn.flags = CAM_FLAG_NONE;
3683 /* run this at a low priority */
3684 ccb->ccb_h.pinfo.priority = 5;
3686 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3687 warn("CAMIOCOMMAND ioctl failed");
3692 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3693 fprintf(stdout, "%s of bus %d was successful\n",
3694 rescan? "Re-scan" : "Reset",
3695 bus_result->path_id);
3698 * Don't bail out just yet, maybe the other
3699 * rescan or reset commands will complete
3702 fprintf(stderr, "%s of bus %d returned error "
3703 "%#x\n", rescan? "Re-scan" : "Reset",
3704 bus_result->path_id,
3705 ccb->ccb_h.status & CAM_STATUS_MASK);
3709 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3710 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3717 if (matchccb != NULL) {
3718 free(matchccb->cdm.patterns);
3719 free(matchccb->cdm.matches);
3728 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3731 struct cam_device *device;
3736 if (bus == CAM_BUS_WILDCARD) {
3737 warnx("invalid bus number %d", bus);
3741 if (target == CAM_TARGET_WILDCARD) {
3742 warnx("invalid target number %d", target);
3746 if (lun == CAM_LUN_WILDCARD) {
3747 warnx("invalid lun number %jx", (uintmax_t)lun);
3753 bzero(&ccb, sizeof(union ccb));
3756 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3757 warnx("error opening transport layer device %s\n",
3759 warn("%s", XPT_DEVICE);
3763 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3764 if (device == NULL) {
3765 warnx("%s", cam_errbuf);
3770 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3771 ccb.ccb_h.path_id = bus;
3772 ccb.ccb_h.target_id = target;
3773 ccb.ccb_h.target_lun = lun;
3774 ccb.ccb_h.timeout = 5000;
3775 ccb.crcn.flags = CAM_FLAG_NONE;
3777 /* run this at a low priority */
3778 ccb.ccb_h.pinfo.priority = 5;
3781 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3782 warn("CAMIOCOMMAND ioctl failed");
3787 if (cam_send_ccb(device, &ccb) < 0) {
3788 warn("error sending XPT_RESET_DEV CCB");
3789 cam_close_device(device);
3797 cam_close_device(device);
3800 * An error code of CAM_BDR_SENT is normal for a BDR request.
3802 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3804 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3805 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3806 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3809 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3810 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3811 ccb.ccb_h.status & CAM_STATUS_MASK);
3817 static struct scsi_nv defect_list_type_map[] = {
3818 { "block", SRDD10_BLOCK_FORMAT },
3819 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3820 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3821 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3822 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3823 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3827 readdefects(struct cam_device *device, int argc, char **argv,
3828 char *combinedopt, int task_attr, int retry_count, int timeout)
3830 union ccb *ccb = NULL;
3831 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3832 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3833 size_t hdr_size = 0, entry_size = 0;
3836 u_int8_t *defect_list = NULL;
3837 u_int8_t list_format = 0;
3838 int list_type_set = 0;
3839 u_int32_t dlist_length = 0;
3840 u_int32_t returned_length = 0, valid_len = 0;
3841 u_int32_t num_returned = 0, num_valid = 0;
3842 u_int32_t max_possible_size = 0, hdr_max = 0;
3843 u_int32_t starting_offset = 0;
3844 u_int8_t returned_format, returned_type;
3846 int summary = 0, quiet = 0;
3848 int lists_specified = 0;
3849 int get_length = 1, first_pass = 1;
3852 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3856 scsi_nv_status status;
3859 status = scsi_get_nv(defect_list_type_map,
3860 sizeof(defect_list_type_map) /
3861 sizeof(defect_list_type_map[0]), optarg,
3862 &entry_num, SCSI_NV_FLAG_IG_CASE);
3864 if (status == SCSI_NV_FOUND) {
3865 list_format = defect_list_type_map[
3869 warnx("%s: %s %s option %s", __func__,
3870 (status == SCSI_NV_AMBIGUOUS) ?
3871 "ambiguous" : "invalid", "defect list type",
3874 goto defect_bailout;
3879 arglist |= CAM_ARG_GLIST;
3882 arglist |= CAM_ARG_PLIST;
3893 starting_offset = strtoul(optarg, &endptr, 0);
3894 if (*endptr != '\0') {
3896 warnx("invalid starting offset %s", optarg);
3897 goto defect_bailout;
3909 if (list_type_set == 0) {
3911 warnx("no defect list format specified");
3912 goto defect_bailout;
3915 if (arglist & CAM_ARG_PLIST) {
3916 list_format |= SRDD10_PLIST;
3920 if (arglist & CAM_ARG_GLIST) {
3921 list_format |= SRDD10_GLIST;
3926 * This implies a summary, and was the previous behavior.
3928 if (lists_specified == 0)
3931 ccb = cam_getccb(device);
3936 * We start off asking for just the header to determine how much
3937 * defect data is available. Some Hitachi drives return an error
3938 * if you ask for more data than the drive has. Once we know the
3939 * length, we retry the command with the returned length.
3941 if (use_12byte == 0)
3942 dlist_length = sizeof(*hdr10);
3944 dlist_length = sizeof(*hdr12);
3947 if (defect_list != NULL) {
3951 defect_list = malloc(dlist_length);
3952 if (defect_list == NULL) {
3953 warnx("can't malloc memory for defect list");
3955 goto defect_bailout;
3959 bzero(defect_list, dlist_length);
3962 * cam_getccb() zeros the CCB header only. So we need to zero the
3963 * payload portion of the ccb.
3965 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3967 scsi_read_defects(&ccb->csio,
3968 /*retries*/ retry_count,
3970 /*tag_action*/ task_attr,
3971 /*list_format*/ list_format,
3972 /*addr_desc_index*/ starting_offset,
3973 /*data_ptr*/ defect_list,
3974 /*dxfer_len*/ dlist_length,
3975 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3976 /*sense_len*/ SSD_FULL_SIZE,
3977 /*timeout*/ timeout ? timeout : 5000);
3979 /* Disable freezing the device queue */
3980 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3982 if (cam_send_ccb(device, ccb) < 0) {
3983 warn("error sending READ DEFECT DATA command");
3985 goto defect_bailout;
3988 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3990 if (use_12byte == 0) {
3991 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3992 hdr_size = sizeof(*hdr10);
3993 hdr_max = SRDDH10_MAX_LENGTH;
3995 if (valid_len >= hdr_size) {
3996 returned_length = scsi_2btoul(hdr10->length);
3997 returned_format = hdr10->format;
3999 returned_length = 0;
4000 returned_format = 0;
4003 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
4004 hdr_size = sizeof(*hdr12);
4005 hdr_max = SRDDH12_MAX_LENGTH;
4007 if (valid_len >= hdr_size) {
4008 returned_length = scsi_4btoul(hdr12->length);
4009 returned_format = hdr12->format;
4011 returned_length = 0;
4012 returned_format = 0;
4016 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
4017 switch (returned_type) {
4018 case SRDD10_BLOCK_FORMAT:
4019 entry_size = sizeof(struct scsi_defect_desc_block);
4021 case SRDD10_LONG_BLOCK_FORMAT:
4022 entry_size = sizeof(struct scsi_defect_desc_long_block);
4024 case SRDD10_EXT_PHYS_FORMAT:
4025 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4026 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
4028 case SRDD10_EXT_BFI_FORMAT:
4029 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4030 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
4033 warnx("Unknown defect format 0x%x\n", returned_type);
4035 goto defect_bailout;
4039 max_possible_size = (hdr_max / entry_size) * entry_size;
4040 num_returned = returned_length / entry_size;
4041 num_valid = min(returned_length, valid_len - hdr_size);
4042 num_valid /= entry_size;
4044 if (get_length != 0) {
4047 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
4048 CAM_SCSI_STATUS_ERROR) {
4049 struct scsi_sense_data *sense;
4050 int error_code, sense_key, asc, ascq;
4052 sense = &ccb->csio.sense_data;
4053 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4054 ccb->csio.sense_resid, &error_code, &sense_key,
4055 &asc, &ascq, /*show_errors*/ 1);
4058 * If the drive is reporting that it just doesn't
4059 * support the defect list format, go ahead and use
4060 * the length it reported. Otherwise, the length
4061 * may not be valid, so use the maximum.
4063 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4064 && (asc == 0x1c) && (ascq == 0x00)
4065 && (returned_length > 0)) {
4066 if ((use_12byte == 0)
4067 && (returned_length >= max_possible_size)) {
4072 dlist_length = returned_length + hdr_size;
4073 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4074 && (asc == 0x1f) && (ascq == 0x00)
4075 && (returned_length > 0)) {
4076 /* Partial defect list transfer */
4078 * Hitachi drives return this error
4079 * along with a partial defect list if they
4080 * have more defects than the 10 byte
4081 * command can support. Retry with the 12
4084 if (use_12byte == 0) {
4089 dlist_length = returned_length + hdr_size;
4090 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
4091 && (asc == 0x24) && (ascq == 0x00)) {
4092 /* Invalid field in CDB */
4094 * SBC-3 says that if the drive has more
4095 * defects than can be reported with the
4096 * 10 byte command, it should return this
4097 * error and no data. Retry with the 12
4100 if (use_12byte == 0) {
4105 dlist_length = returned_length + hdr_size;
4108 * If we got a SCSI error and no valid length,
4109 * just use the 10 byte maximum. The 12
4110 * byte maximum is too large.
4112 if (returned_length == 0)
4113 dlist_length = SRDD10_MAX_LENGTH;
4115 if ((use_12byte == 0)
4116 && (returned_length >=
4117 max_possible_size)) {
4122 dlist_length = returned_length +
4126 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4129 warnx("Error reading defect header");
4130 if (arglist & CAM_ARG_VERBOSE)
4131 cam_error_print(device, ccb, CAM_ESF_ALL,
4132 CAM_EPF_ALL, stderr);
4133 goto defect_bailout;
4135 if ((use_12byte == 0)
4136 && (returned_length >= max_possible_size)) {
4141 dlist_length = returned_length + hdr_size;
4144 fprintf(stdout, "%u", num_returned);
4146 fprintf(stdout, " defect%s",
4147 (num_returned != 1) ? "s" : "");
4149 fprintf(stdout, "\n");
4151 goto defect_bailout;
4155 * We always limit the list length to the 10-byte maximum
4156 * length (0xffff). The reason is that some controllers
4157 * can't handle larger I/Os, and we can transfer the entire
4158 * 10 byte list in one shot. For drives that support the 12
4159 * byte read defects command, we'll step through the list
4160 * by specifying a starting offset. For drives that don't
4161 * support the 12 byte command's starting offset, we'll
4162 * just display the first 64K.
4164 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4170 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4171 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4172 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4173 struct scsi_sense_data *sense;
4174 int error_code, sense_key, asc, ascq;
4176 sense = &ccb->csio.sense_data;
4177 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4178 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4179 &ascq, /*show_errors*/ 1);
4182 * According to the SCSI spec, if the disk doesn't support
4183 * the requested format, it will generally return a sense
4184 * key of RECOVERED ERROR, and an additional sense code
4185 * of "DEFECT LIST NOT FOUND". HGST drives also return
4186 * Primary/Grown defect list not found errors. So just
4187 * check for an ASC of 0x1c.
4189 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4191 const char *format_str;
4193 format_str = scsi_nv_to_str(defect_list_type_map,
4194 sizeof(defect_list_type_map) /
4195 sizeof(defect_list_type_map[0]),
4196 list_format & SRDD10_DLIST_FORMAT_MASK);
4197 warnx("requested defect format %s not available",
4198 format_str ? format_str : "unknown");
4200 format_str = scsi_nv_to_str(defect_list_type_map,
4201 sizeof(defect_list_type_map) /
4202 sizeof(defect_list_type_map[0]), returned_type);
4203 if (format_str != NULL) {
4204 warnx("Device returned %s format",
4208 warnx("Device returned unknown defect"
4209 " data format %#x", returned_type);
4210 goto defect_bailout;
4214 warnx("Error returned from read defect data command");
4215 if (arglist & CAM_ARG_VERBOSE)
4216 cam_error_print(device, ccb, CAM_ESF_ALL,
4217 CAM_EPF_ALL, stderr);
4218 goto defect_bailout;
4220 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4222 warnx("Error returned from read defect data command");
4223 if (arglist & CAM_ARG_VERBOSE)
4224 cam_error_print(device, ccb, CAM_ESF_ALL,
4225 CAM_EPF_ALL, stderr);
4226 goto defect_bailout;
4229 if (first_pass != 0) {
4230 fprintf(stderr, "Got %d defect", num_returned);
4232 if ((lists_specified == 0) || (num_returned == 0)) {
4233 fprintf(stderr, "s.\n");
4234 goto defect_bailout;
4235 } else if (num_returned == 1)
4236 fprintf(stderr, ":\n");
4238 fprintf(stderr, "s:\n");
4244 * XXX KDM I should probably clean up the printout format for the
4247 switch (returned_type) {
4248 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4249 case SRDD10_EXT_PHYS_FORMAT:
4251 struct scsi_defect_desc_phys_sector *dlist;
4253 dlist = (struct scsi_defect_desc_phys_sector *)
4254 (defect_list + hdr_size);
4256 for (i = 0; i < num_valid; i++) {
4259 sector = scsi_4btoul(dlist[i].sector);
4260 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4261 mads = (sector & SDD_EXT_PHYS_MADS) ?
4263 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4265 if (hex_format == 0)
4266 fprintf(stdout, "%d:%d:%d%s",
4267 scsi_3btoul(dlist[i].cylinder),
4269 scsi_4btoul(dlist[i].sector),
4270 mads ? " - " : "\n");
4272 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4273 scsi_3btoul(dlist[i].cylinder),
4275 scsi_4btoul(dlist[i].sector),
4276 mads ? " - " : "\n");
4279 if (num_valid < num_returned) {
4280 starting_offset += num_valid;
4285 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4286 case SRDD10_EXT_BFI_FORMAT:
4288 struct scsi_defect_desc_bytes_from_index *dlist;
4290 dlist = (struct scsi_defect_desc_bytes_from_index *)
4291 (defect_list + hdr_size);
4293 for (i = 0; i < num_valid; i++) {
4296 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4297 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4298 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4299 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4301 if (hex_format == 0)
4302 fprintf(stdout, "%d:%d:%d%s",
4303 scsi_3btoul(dlist[i].cylinder),
4305 scsi_4btoul(dlist[i].bytes_from_index),
4306 mads ? " - " : "\n");
4308 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4309 scsi_3btoul(dlist[i].cylinder),
4311 scsi_4btoul(dlist[i].bytes_from_index),
4312 mads ? " - " : "\n");
4316 if (num_valid < num_returned) {
4317 starting_offset += num_valid;
4322 case SRDDH10_BLOCK_FORMAT:
4324 struct scsi_defect_desc_block *dlist;
4326 dlist = (struct scsi_defect_desc_block *)
4327 (defect_list + hdr_size);
4329 for (i = 0; i < num_valid; i++) {
4330 if (hex_format == 0)
4331 fprintf(stdout, "%u\n",
4332 scsi_4btoul(dlist[i].address));
4334 fprintf(stdout, "0x%x\n",
4335 scsi_4btoul(dlist[i].address));
4338 if (num_valid < num_returned) {
4339 starting_offset += num_valid;
4345 case SRDD10_LONG_BLOCK_FORMAT:
4347 struct scsi_defect_desc_long_block *dlist;
4349 dlist = (struct scsi_defect_desc_long_block *)
4350 (defect_list + hdr_size);
4352 for (i = 0; i < num_valid; i++) {
4353 if (hex_format == 0)
4354 fprintf(stdout, "%ju\n",
4355 (uintmax_t)scsi_8btou64(
4358 fprintf(stdout, "0x%jx\n",
4359 (uintmax_t)scsi_8btou64(
4363 if (num_valid < num_returned) {
4364 starting_offset += num_valid;
4370 fprintf(stderr, "Unknown defect format 0x%x\n",
4377 if (defect_list != NULL)
4388 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4392 ccb = cam_getccb(device);
4399 mode_sense(struct cam_device *device, int *cdb_len, int dbd, int llbaa, int pc,
4400 int page, int subpage, int task_attr, int retry_count, int timeout,
4401 u_int8_t *data, int datalen)
4404 int error_code, sense_key, asc, ascq;
4406 ccb = cam_getccb(device);
4408 errx(1, "mode_sense: couldn't allocate CCB");
4412 * MODE SENSE(6) can't handle more then 255 bytes. If there are more,
4413 * device must return error, so we should not get trucated data.
4415 if (*cdb_len == 6 && datalen > 255)
4418 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4420 scsi_mode_sense_subpage(&ccb->csio,
4421 /* retries */ retry_count,
4423 /* tag_action */ task_attr,
4427 /* subpage */ subpage,
4428 /* param_buf */ data,
4429 /* param_len */ datalen,
4430 /* minimum_cmd_size */ *cdb_len,
4431 /* sense_len */ SSD_FULL_SIZE,
4432 /* timeout */ timeout ? timeout : 5000);
4433 if (llbaa && ccb->csio.cdb_len == 10) {
4434 struct scsi_mode_sense_10 *cdb =
4435 (struct scsi_mode_sense_10 *)ccb->csio.cdb_io.cdb_bytes;
4436 cdb->byte2 |= SMS10_LLBAA;
4439 /* Record what CDB size the above function really set. */
4440 *cdb_len = ccb->csio.cdb_len;
4442 if (arglist & CAM_ARG_ERR_RECOVER)
4443 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4445 /* Disable freezing the device queue */
4446 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4448 if (cam_send_ccb(device, ccb) < 0)
4449 err(1, "error sending mode sense command");
4451 /* In case of ILLEGEL REQUEST try to fall back to 6-byte command. */
4452 if (*cdb_len != 6 &&
4453 ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID ||
4454 (scsi_extract_sense_ccb(ccb, &error_code, &sense_key, &asc, &ascq)
4455 && sense_key == SSD_KEY_ILLEGAL_REQUEST))) {
4460 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4461 if (arglist & CAM_ARG_VERBOSE) {
4462 cam_error_print(device, ccb, CAM_ESF_ALL,
4463 CAM_EPF_ALL, stderr);
4466 cam_close_device(device);
4467 errx(1, "mode sense command returned error");
4474 mode_select(struct cam_device *device, int cdb_len, int save_pages,
4475 int task_attr, int retry_count, int timeout, u_int8_t *data, int datalen)
4480 ccb = cam_getccb(device);
4483 errx(1, "mode_select: couldn't allocate CCB");
4485 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4487 scsi_mode_select_len(&ccb->csio,
4488 /* retries */ retry_count,
4490 /* tag_action */ task_attr,
4491 /* scsi_page_fmt */ 1,
4492 /* save_pages */ save_pages,
4493 /* param_buf */ data,
4494 /* param_len */ datalen,
4495 /* minimum_cmd_size */ cdb_len,
4496 /* sense_len */ SSD_FULL_SIZE,
4497 /* timeout */ timeout ? timeout : 5000);
4499 if (arglist & CAM_ARG_ERR_RECOVER)
4500 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4502 /* Disable freezing the device queue */
4503 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4505 if (((retval = cam_send_ccb(device, ccb)) < 0)
4506 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4507 if (arglist & CAM_ARG_VERBOSE) {
4508 cam_error_print(device, ccb, CAM_ESF_ALL,
4509 CAM_EPF_ALL, stderr);
4512 cam_close_device(device);
4515 err(1, "error sending mode select command");
4517 errx(1, "error sending mode select command");
4525 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4526 int task_attr, int retry_count, int timeout)
4529 int c, page = -1, subpage = 0, pc = 0, llbaa = 0;
4530 int binary = 0, cdb_len = 10, dbd = 0, desc = 0, edit = 0, list = 0;
4532 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4550 str_subpage = optarg;
4551 strsep(&str_subpage, ",");
4552 page = strtol(optarg, NULL, 0);
4554 subpage = strtol(str_subpage, NULL, 0);
4555 if (page < 0 || page > 0x3f)
4556 errx(1, "invalid mode page %d", page);
4557 if (subpage < 0 || subpage > 0xff)
4558 errx(1, "invalid mode subpage %d", subpage);
4567 pc = strtol(optarg, NULL, 0);
4568 if ((pc < 0) || (pc > 3))
4569 errx(1, "invalid page control field %d", pc);
4576 if (desc && page == -1)
4577 page = SMS_ALL_PAGES_PAGE;
4579 if (page == -1 && list == 0)
4580 errx(1, "you must specify a mode page!");
4583 errx(1, "-d and -D are incompatible!");
4585 if (llbaa && cdb_len != 10)
4586 errx(1, "LLBAA bit is not present in MODE SENSE(6)!");
4589 mode_list(device, cdb_len, dbd, pc, list > 1, task_attr,
4590 retry_count, timeout);
4592 mode_edit(device, cdb_len, desc, dbd, llbaa, pc, page, subpage,
4593 edit, binary, task_attr, retry_count, timeout);
4598 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4599 int task_attr, int retry_count, int timeout)
4602 u_int32_t flags = CAM_DIR_NONE;
4603 u_int8_t *data_ptr = NULL;
4605 u_int8_t atacmd[12];
4606 struct get_hook hook;
4607 int c, data_bytes = 0, valid_bytes;
4613 char *datastr = NULL, *tstr, *resstr = NULL;
4615 int fd_data = 0, fd_res = 0;
4618 ccb = cam_getccb(device);
4621 warnx("scsicmd: error allocating ccb");
4625 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4627 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4631 while (isspace(*tstr) && (*tstr != '\0'))
4633 hook.argc = argc - optind;
4634 hook.argv = argv + optind;
4636 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4639 * Increment optind by the number of arguments the
4640 * encoding routine processed. After each call to
4641 * getopt(3), optind points to the argument that
4642 * getopt should process _next_. In this case,
4643 * that means it points to the first command string
4644 * argument, if there is one. Once we increment
4645 * this, it should point to either the next command
4646 * line argument, or it should be past the end of
4653 while (isspace(*tstr) && (*tstr != '\0'))
4655 hook.argc = argc - optind;
4656 hook.argv = argv + optind;
4658 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4661 * Increment optind by the number of arguments the
4662 * encoding routine processed. After each call to
4663 * getopt(3), optind points to the argument that
4664 * getopt should process _next_. In this case,
4665 * that means it points to the first command string
4666 * argument, if there is one. Once we increment
4667 * this, it should point to either the next command
4668 * line argument, or it should be past the end of
4680 if (arglist & CAM_ARG_CMD_OUT) {
4681 warnx("command must either be "
4682 "read or write, not both");
4684 goto scsicmd_bailout;
4686 arglist |= CAM_ARG_CMD_IN;
4688 data_bytes = strtol(optarg, NULL, 0);
4689 if (data_bytes <= 0) {
4690 warnx("invalid number of input bytes %d",
4693 goto scsicmd_bailout;
4695 hook.argc = argc - optind;
4696 hook.argv = argv + optind;
4699 datastr = cget(&hook, NULL);
4701 * If the user supplied "-" instead of a format, he
4702 * wants the data to be written to stdout.
4704 if ((datastr != NULL)
4705 && (datastr[0] == '-'))
4708 data_ptr = (u_int8_t *)malloc(data_bytes);
4709 if (data_ptr == NULL) {
4710 warnx("can't malloc memory for data_ptr");
4712 goto scsicmd_bailout;
4716 if (arglist & CAM_ARG_CMD_IN) {
4717 warnx("command must either be "
4718 "read or write, not both");
4720 goto scsicmd_bailout;
4722 arglist |= CAM_ARG_CMD_OUT;
4723 flags = CAM_DIR_OUT;
4724 data_bytes = strtol(optarg, NULL, 0);
4725 if (data_bytes <= 0) {
4726 warnx("invalid number of output bytes %d",
4729 goto scsicmd_bailout;
4731 hook.argc = argc - optind;
4732 hook.argv = argv + optind;
4734 datastr = cget(&hook, NULL);
4735 data_ptr = (u_int8_t *)malloc(data_bytes);
4736 if (data_ptr == NULL) {
4737 warnx("can't malloc memory for data_ptr");
4739 goto scsicmd_bailout;
4741 bzero(data_ptr, data_bytes);
4743 * If the user supplied "-" instead of a format, he
4744 * wants the data to be read from stdin.
4746 if ((datastr != NULL)
4747 && (datastr[0] == '-'))
4750 buff_encode_visit(data_ptr, data_bytes, datastr,
4756 hook.argc = argc - optind;
4757 hook.argv = argv + optind;
4759 resstr = cget(&hook, NULL);
4760 if ((resstr != NULL) && (resstr[0] == '-'))
4770 * If fd_data is set, and we're writing to the device, we need to
4771 * read the data the user wants written from stdin.
4773 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4775 int amt_to_read = data_bytes;
4776 u_int8_t *buf_ptr = data_ptr;
4778 for (amt_read = 0; amt_to_read > 0;
4779 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4780 if (amt_read == -1) {
4781 warn("error reading data from stdin");
4783 goto scsicmd_bailout;
4785 amt_to_read -= amt_read;
4786 buf_ptr += amt_read;
4790 if (arglist & CAM_ARG_ERR_RECOVER)
4791 flags |= CAM_PASS_ERR_RECOVER;
4793 /* Disable freezing the device queue */
4794 flags |= CAM_DEV_QFRZDIS;
4798 * This is taken from the SCSI-3 draft spec.
4799 * (T10/1157D revision 0.3)
4800 * The top 3 bits of an opcode are the group code.
4801 * The next 5 bits are the command code.
4802 * Group 0: six byte commands
4803 * Group 1: ten byte commands
4804 * Group 2: ten byte commands
4806 * Group 4: sixteen byte commands
4807 * Group 5: twelve byte commands
4808 * Group 6: vendor specific
4809 * Group 7: vendor specific
4811 switch((cdb[0] >> 5) & 0x7) {
4822 /* computed by buff_encode_visit */
4833 * We should probably use csio_build_visit or something like that
4834 * here, but it's easier to encode arguments as you go. The
4835 * alternative would be skipping the CDB argument and then encoding
4836 * it here, since we've got the data buffer argument by now.
4838 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4840 cam_fill_csio(&ccb->csio,
4841 /*retries*/ retry_count,
4844 /*tag_action*/ task_attr,
4845 /*data_ptr*/ data_ptr,
4846 /*dxfer_len*/ data_bytes,
4847 /*sense_len*/ SSD_FULL_SIZE,
4848 /*cdb_len*/ cdb_len,
4849 /*timeout*/ timeout ? timeout : 5000);
4852 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4854 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4856 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4858 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4860 cam_fill_ataio(&ccb->ataio,
4861 /*retries*/ retry_count,
4865 /*data_ptr*/ data_ptr,
4866 /*dxfer_len*/ data_bytes,
4867 /*timeout*/ timeout ? timeout : 5000);
4870 if (((retval = cam_send_ccb(device, ccb)) < 0)
4871 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4872 const char warnstr[] = "error sending command";
4879 if (arglist & CAM_ARG_VERBOSE) {
4880 cam_error_print(device, ccb, CAM_ESF_ALL,
4881 CAM_EPF_ALL, stderr);
4885 goto scsicmd_bailout;
4888 if (atacmd_len && need_res) {
4890 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4892 fprintf(stdout, "\n");
4895 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4896 ccb->ataio.res.status,
4897 ccb->ataio.res.error,
4898 ccb->ataio.res.lba_low,
4899 ccb->ataio.res.lba_mid,
4900 ccb->ataio.res.lba_high,
4901 ccb->ataio.res.device,
4902 ccb->ataio.res.lba_low_exp,
4903 ccb->ataio.res.lba_mid_exp,
4904 ccb->ataio.res.lba_high_exp,
4905 ccb->ataio.res.sector_count,
4906 ccb->ataio.res.sector_count_exp);
4912 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4914 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4915 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4916 && (arglist & CAM_ARG_CMD_IN)
4917 && (valid_bytes > 0)) {
4919 buff_decode_visit(data_ptr, valid_bytes, datastr,
4921 fprintf(stdout, "\n");
4923 ssize_t amt_written;
4924 int amt_to_write = valid_bytes;
4925 u_int8_t *buf_ptr = data_ptr;
4927 for (amt_written = 0; (amt_to_write > 0) &&
4928 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4929 amt_to_write -= amt_written;
4930 buf_ptr += amt_written;
4932 if (amt_written == -1) {
4933 warn("error writing data to stdout");
4935 goto scsicmd_bailout;
4936 } else if ((amt_written == 0)
4937 && (amt_to_write > 0)) {
4938 warnx("only wrote %u bytes out of %u",
4939 valid_bytes - amt_to_write, valid_bytes);
4946 if ((data_bytes > 0) && (data_ptr != NULL))
4955 camdebug(int argc, char **argv, char *combinedopt)
4958 path_id_t bus = CAM_BUS_WILDCARD;
4959 target_id_t target = CAM_TARGET_WILDCARD;
4960 lun_id_t lun = CAM_LUN_WILDCARD;
4965 bzero(&ccb, sizeof(union ccb));
4967 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4970 arglist |= CAM_ARG_DEBUG_INFO;
4971 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4974 arglist |= CAM_ARG_DEBUG_PERIPH;
4975 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4978 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4979 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4982 arglist |= CAM_ARG_DEBUG_TRACE;
4983 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4986 arglist |= CAM_ARG_DEBUG_XPT;
4987 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4990 arglist |= CAM_ARG_DEBUG_CDB;
4991 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4994 arglist |= CAM_ARG_DEBUG_PROBE;
4995 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
5006 warnx("you must specify \"off\", \"all\" or a bus,");
5007 warnx("bus:target, bus:target:lun or periph");
5012 while (isspace(*tstr) && (*tstr != '\0'))
5015 if (strncmp(tstr, "off", 3) == 0) {
5016 ccb.cdbg.flags = CAM_DEBUG_NONE;
5017 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
5018 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
5019 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
5021 rv = parse_btl(tstr, &bus, &target, &lun, &arglist);
5023 warnx("you must specify \"all\", \"off\", or a bus,");
5024 warnx("bus:target, bus:target:lun or periph to debug");
5029 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
5030 warnx("error opening transport layer device %s", XPT_DEVICE);
5031 warn("%s", XPT_DEVICE);
5035 ccb.ccb_h.func_code = XPT_DEBUG;
5036 ccb.ccb_h.path_id = bus;
5037 ccb.ccb_h.target_id = target;
5038 ccb.ccb_h.target_lun = lun;
5040 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
5041 warn("CAMIOCOMMAND ioctl failed");
5044 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
5045 CAM_FUNC_NOTAVAIL) {
5046 warnx("CAM debugging not available");
5047 warnx("you need to put options CAMDEBUG in"
5048 " your kernel config file!");
5050 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
5052 warnx("XPT_DEBUG CCB failed with status %#x",
5056 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
5058 "Debugging turned off\n");
5061 "Debugging enabled for "
5063 bus, target, (uintmax_t)lun);
5073 tagcontrol(struct cam_device *device, int argc, char **argv,
5083 ccb = cam_getccb(device);
5086 warnx("tagcontrol: error allocating ccb");
5090 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5093 numtags = strtol(optarg, NULL, 0);
5095 warnx("tag count %d is < 0", numtags);
5097 goto tagcontrol_bailout;
5108 cam_path_string(device, pathstr, sizeof(pathstr));
5111 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
5112 ccb->ccb_h.func_code = XPT_REL_SIMQ;
5113 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5114 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5115 ccb->crs.openings = numtags;
5118 if (cam_send_ccb(device, ccb) < 0) {
5119 warn("error sending XPT_REL_SIMQ CCB");
5121 goto tagcontrol_bailout;
5124 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5125 warnx("XPT_REL_SIMQ CCB failed");
5126 cam_error_print(device, ccb, CAM_ESF_ALL,
5127 CAM_EPF_ALL, stderr);
5129 goto tagcontrol_bailout;
5134 fprintf(stdout, "%stagged openings now %d\n",
5135 pathstr, ccb->crs.openings);
5138 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5140 ccb->ccb_h.func_code = XPT_GDEV_STATS;
5142 if (cam_send_ccb(device, ccb) < 0) {
5143 warn("error sending XPT_GDEV_STATS CCB");
5145 goto tagcontrol_bailout;
5148 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5149 warnx("XPT_GDEV_STATS CCB failed");
5150 cam_error_print(device, ccb, CAM_ESF_ALL,
5151 CAM_EPF_ALL, stderr);
5153 goto tagcontrol_bailout;
5156 if (arglist & CAM_ARG_VERBOSE) {
5157 fprintf(stdout, "%s", pathstr);
5158 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5159 fprintf(stdout, "%s", pathstr);
5160 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5161 fprintf(stdout, "%s", pathstr);
5162 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5163 fprintf(stdout, "%s", pathstr);
5164 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5165 fprintf(stdout, "%s", pathstr);
5166 fprintf(stdout, "held %d\n", ccb->cgds.held);
5167 fprintf(stdout, "%s", pathstr);
5168 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5169 fprintf(stdout, "%s", pathstr);
5170 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5173 fprintf(stdout, "%s", pathstr);
5174 fprintf(stdout, "device openings: ");
5176 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5177 ccb->cgds.dev_active);
5187 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5191 cam_path_string(device, pathstr, sizeof(pathstr));
5193 if (cts->transport == XPORT_SPI) {
5194 struct ccb_trans_settings_spi *spi =
5195 &cts->xport_specific.spi;
5197 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5199 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5202 if (spi->sync_offset != 0) {
5205 freq = scsi_calc_syncsrate(spi->sync_period);
5206 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5207 pathstr, freq / 1000, freq % 1000);
5211 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5212 fprintf(stdout, "%soffset: %d\n", pathstr,
5216 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5217 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5218 (0x01 << spi->bus_width) * 8);
5221 if (spi->valid & CTS_SPI_VALID_DISC) {
5222 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5223 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5224 "enabled" : "disabled");
5227 if (cts->transport == XPORT_FC) {
5228 struct ccb_trans_settings_fc *fc =
5229 &cts->xport_specific.fc;
5231 if (fc->valid & CTS_FC_VALID_WWNN)
5232 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5233 (long long) fc->wwnn);
5234 if (fc->valid & CTS_FC_VALID_WWPN)
5235 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5236 (long long) fc->wwpn);
5237 if (fc->valid & CTS_FC_VALID_PORT)
5238 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5239 if (fc->valid & CTS_FC_VALID_SPEED)
5240 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5241 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5243 if (cts->transport == XPORT_SAS) {
5244 struct ccb_trans_settings_sas *sas =
5245 &cts->xport_specific.sas;
5247 if (sas->valid & CTS_SAS_VALID_SPEED)
5248 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5249 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5251 if (cts->transport == XPORT_ATA) {
5252 struct ccb_trans_settings_pata *pata =
5253 &cts->xport_specific.ata;
5255 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5256 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5257 ata_mode2string(pata->mode));
5259 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5260 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5263 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5264 fprintf(stdout, "%sPIO transaction length: %d\n",
5265 pathstr, pata->bytecount);
5268 if (cts->transport == XPORT_SATA) {
5269 struct ccb_trans_settings_sata *sata =
5270 &cts->xport_specific.sata;
5272 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5273 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5276 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5277 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5278 ata_mode2string(sata->mode));
5280 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5281 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5284 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5285 fprintf(stdout, "%sPIO transaction length: %d\n",
5286 pathstr, sata->bytecount);
5288 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5289 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5292 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5293 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5296 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5297 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5301 if (cts->protocol == PROTO_ATA) {
5302 struct ccb_trans_settings_ata *ata=
5303 &cts->proto_specific.ata;
5305 if (ata->valid & CTS_ATA_VALID_TQ) {
5306 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5307 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5308 "enabled" : "disabled");
5311 if (cts->protocol == PROTO_SCSI) {
5312 struct ccb_trans_settings_scsi *scsi=
5313 &cts->proto_specific.scsi;
5315 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5316 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5317 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5318 "enabled" : "disabled");
5322 if (cts->protocol == PROTO_NVME) {
5323 struct ccb_trans_settings_nvme *nvmex =
5324 &cts->xport_specific.nvme;
5326 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5327 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5328 NVME_MAJOR(nvmex->spec),
5329 NVME_MINOR(nvmex->spec));
5331 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5332 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5333 nvmex->lanes, nvmex->max_lanes);
5334 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5335 nvmex->speed, nvmex->max_speed);
5342 * Get a path inquiry CCB for the specified device.
5345 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5350 ccb = cam_getccb(device);
5352 warnx("get_cpi: couldn't allocate CCB");
5355 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5356 ccb->ccb_h.func_code = XPT_PATH_INQ;
5357 if (cam_send_ccb(device, ccb) < 0) {
5358 warn("get_cpi: error sending Path Inquiry CCB");
5360 goto get_cpi_bailout;
5362 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5363 if (arglist & CAM_ARG_VERBOSE)
5364 cam_error_print(device, ccb, CAM_ESF_ALL,
5365 CAM_EPF_ALL, stderr);
5367 goto get_cpi_bailout;
5369 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5377 * Get a get device CCB for the specified device.
5380 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5385 ccb = cam_getccb(device);
5387 warnx("get_cgd: couldn't allocate CCB");
5390 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5391 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5392 if (cam_send_ccb(device, ccb) < 0) {
5393 warn("get_cgd: error sending Get type information CCB");
5395 goto get_cgd_bailout;
5397 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5398 if (arglist & CAM_ARG_VERBOSE)
5399 cam_error_print(device, ccb, CAM_ESF_ALL,
5400 CAM_EPF_ALL, stderr);
5402 goto get_cgd_bailout;
5404 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5412 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5416 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5417 int timeout, int verbosemode)
5419 union ccb *ccb = NULL;
5420 struct scsi_vpd_supported_page_list sup_pages;
5424 ccb = cam_getccb(dev);
5426 warn("Unable to allocate CCB");
5431 /* cam_getccb cleans up the header, caller has to zero the payload */
5432 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5434 bzero(&sup_pages, sizeof(sup_pages));
5436 scsi_inquiry(&ccb->csio,
5437 /*retries*/ retry_count,
5439 /* tag_action */ MSG_SIMPLE_Q_TAG,
5440 /* inq_buf */ (u_int8_t *)&sup_pages,
5441 /* inq_len */ sizeof(sup_pages),
5443 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5444 /* sense_len */ SSD_FULL_SIZE,
5445 /* timeout */ timeout ? timeout : 5000);
5447 /* Disable freezing the device queue */
5448 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5450 if (retry_count != 0)
5451 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5453 if (cam_send_ccb(dev, ccb) < 0) {
5460 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5461 if (verbosemode != 0)
5462 cam_error_print(dev, ccb, CAM_ESF_ALL,
5463 CAM_EPF_ALL, stderr);
5468 for (i = 0; i < sup_pages.length; i++) {
5469 if (sup_pages.list[i] == page_id) {
5482 * devtype is filled in with the type of device.
5483 * Returns 0 for success, non-zero for failure.
5486 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5487 int verbosemode, camcontrol_devtype *devtype)
5489 struct ccb_getdev cgd;
5492 retval = get_cgd(dev, &cgd);
5496 switch (cgd.protocol) {
5502 *devtype = CC_DT_ATA;
5504 break; /*NOTREACHED*/
5506 *devtype = CC_DT_NVME;
5508 break; /*NOTREACHED*/
5510 *devtype = CC_DT_MMCSD;
5512 break; /*NOTREACHED*/
5514 *devtype = CC_DT_UNKNOWN;
5516 break; /*NOTREACHED*/
5519 if (retry_count == -1) {
5521 * For a retry count of -1, used only the cached data to avoid
5522 * I/O to the drive. Sending the identify command to the drive
5523 * can cause issues for SATL attachaed drives since identify is
5524 * not an NCQ command.
5526 if (cgd.ident_data.config != 0)
5527 *devtype = CC_DT_SATL;
5529 *devtype = CC_DT_SCSI;
5532 * Check for the ATA Information VPD page (0x89). If this is an
5533 * ATA device behind a SCSI to ATA translation layer (SATL),
5534 * this VPD page should be present.
5536 * If that VPD page isn't present, or we get an error back from
5537 * the INQUIRY command, we'll just treat it as a normal SCSI
5540 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5541 timeout, verbosemode);
5543 *devtype = CC_DT_SATL;
5545 *devtype = CC_DT_SCSI;
5554 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5555 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5556 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5557 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5558 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5559 int is48bit, camcontrol_devtype devtype)
5563 if (devtype == CC_DT_ATA) {
5564 cam_fill_ataio(&ccb->ataio,
5565 /*retries*/ retry_count,
5568 /*tag_action*/ tag_action,
5569 /*data_ptr*/ data_ptr,
5570 /*dxfer_len*/ dxfer_len,
5571 /*timeout*/ timeout);
5572 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5573 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5576 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5579 if (auxiliary != 0) {
5580 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5581 ccb->ataio.aux = auxiliary;
5584 if (ata_flags & AP_FLAG_CHK_COND)
5585 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5587 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5588 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5589 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5590 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5592 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5593 protocol |= AP_EXTEND;
5595 retval = scsi_ata_pass(&ccb->csio,
5596 /*retries*/ retry_count,
5599 /*tag_action*/ tag_action,
5600 /*protocol*/ protocol,
5601 /*ata_flags*/ ata_flags,
5602 /*features*/ features,
5603 /*sector_count*/ sector_count,
5605 /*command*/ command,
5608 /*auxiliary*/ auxiliary,
5610 /*data_ptr*/ data_ptr,
5611 /*dxfer_len*/ dxfer_len,
5612 /*cdb_storage*/ cdb_storage,
5613 /*cdb_storage_len*/ cdb_storage_len,
5614 /*minimum_cmd_size*/ 0,
5615 /*sense_len*/ sense_len,
5616 /*timeout*/ timeout);
5623 * Returns: 0 -- success, 1 -- error, 2 -- lba truncated,
5624 * 4 -- count truncated, 6 -- lba and count truncated.
5627 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5628 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5632 switch (ccb->ccb_h.func_code) {
5635 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5639 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5640 * or 16 byte, and need to see what
5642 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5643 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5645 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5646 if ((opcode != ATA_PASS_12)
5647 && (opcode != ATA_PASS_16)) {
5648 warnx("%s: unsupported opcode %02x", __func__, opcode);
5652 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5654 /* Note: the _ccb() variant returns 0 for an error */
5658 sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
5659 switch (error_code) {
5660 case SSD_DESC_CURRENT_ERROR:
5661 case SSD_DESC_DEFERRED_ERROR: {
5662 struct scsi_sense_data_desc *sense;
5663 struct scsi_sense_ata_ret_desc *desc;
5666 sense = (struct scsi_sense_data_desc *)
5667 &ccb->csio.sense_data;
5669 desc_ptr = scsi_find_desc(sense, sense_len,
5671 if (desc_ptr == NULL) {
5672 cam_error_print(dev, ccb, CAM_ESF_ALL,
5673 CAM_EPF_ALL, stderr);
5676 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5678 *error = desc->error;
5679 *count = (desc->count_15_8 << 8) |
5681 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5682 ((uint64_t)desc->lba_39_32 << 32) |
5683 ((uint64_t)desc->lba_31_24 << 24) |
5684 (desc->lba_23_16 << 16) |
5685 (desc->lba_15_8 << 8) |
5687 *device = desc->device;
5688 *status = desc->status;
5691 * If the extend bit isn't set, the result is for a
5692 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5693 * command without the extend bit set. This means
5694 * that the device is supposed to return 28-bit
5695 * status. The count field is only 8 bits, and the
5696 * LBA field is only 8 bits.
5698 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5704 case SSD_CURRENT_ERROR:
5705 case SSD_DEFERRED_ERROR: {
5709 * In my understanding of SAT-5 specification, saying:
5710 * "without interpreting the contents of the STATUS",
5711 * this should not happen if CK_COND was set, but it
5712 * does at least for some devices, so try to revert.
5714 if ((sense_key == SSD_KEY_ABORTED_COMMAND) &&
5715 (asc == 0) && (ascq == 0)) {
5716 *status = ATA_STATUS_ERROR;
5717 *error = ATA_ERROR_ABORT;
5724 if ((sense_key != SSD_KEY_RECOVERED_ERROR) ||
5725 (asc != 0x00) || (ascq != 0x1d))
5729 scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5730 SSD_DESC_INFO, &val, NULL);
5731 *error = (val >> 24) & 0xff;
5732 *status = (val >> 16) & 0xff;
5733 *device = (val >> 8) & 0xff;
5734 *count = val & 0xff;
5737 scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5738 SSD_DESC_COMMAND, &val, NULL);
5739 *lba = ((val >> 16) & 0xff) | (val & 0xff00) |
5740 ((val & 0xff) << 16);
5742 /* Report UPPER NONZERO bits as errors 2, 4 and 6. */
5743 return ((val >> 28) & 0x06);
5752 struct ata_res *res;
5754 /* Only some statuses return ATA result register set. */
5755 if (cam_ccb_status(ccb) != CAM_REQ_CMP &&
5756 cam_ccb_status(ccb) != CAM_ATA_STATUS_ERROR)
5759 res = &ccb->ataio.res;
5760 *error = res->error;
5761 *status = res->status;
5762 *device = res->device;
5763 *count = res->sector_count;
5764 *lba = (res->lba_high << 16) |
5765 (res->lba_mid << 8) |
5767 if (ccb->ataio.cmd.flags & CAM_ATAIO_48BIT) {
5768 *count |= (res->sector_count_exp << 8);
5769 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5770 ((uint64_t)res->lba_mid_exp << 32) |
5771 ((uint64_t)res->lba_high_exp << 40);
5773 *lba |= (res->device & 0xf) << 24;
5784 cpi_print(struct ccb_pathinq *cpi)
5786 char adapter_str[1024];
5789 snprintf(adapter_str, sizeof(adapter_str),
5790 "%s%d:", cpi->dev_name, cpi->unit_number);
5792 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5795 for (i = 1; i < UINT8_MAX; i = i << 1) {
5798 if ((i & cpi->hba_inquiry) == 0)
5801 fprintf(stdout, "%s supports ", adapter_str);
5805 str = "MDP message";
5808 str = "32 bit wide SCSI";
5811 str = "16 bit wide SCSI";
5814 str = "SDTR message";
5817 str = "linked CDBs";
5820 str = "tag queue messages";
5823 str = "soft reset alternative";
5826 str = "SATA Port Multiplier";
5829 str = "unknown PI bit set";
5832 fprintf(stdout, "%s\n", str);
5835 for (i = 1; i < UINT32_MAX; i = i << 1) {
5838 if ((i & cpi->hba_misc) == 0)
5841 fprintf(stdout, "%s ", adapter_str);
5845 str = "can understand ata_ext requests";
5848 str = "64bit extended LUNs supported";
5851 str = "bus scans from high ID to low ID";
5854 str = "removable devices not included in scan";
5856 case PIM_NOINITIATOR:
5857 str = "initiator role not supported";
5859 case PIM_NOBUSRESET:
5860 str = "user has disabled initial BUS RESET or"
5861 " controller is in target/mixed mode";
5864 str = "do not send 6-byte commands";
5867 str = "scan bus sequentially";
5870 str = "unmapped I/O supported";
5873 str = "does its own scanning";
5876 str = "unknown PIM bit set";
5879 fprintf(stdout, "%s\n", str);
5882 for (i = 1; i < UINT16_MAX; i = i << 1) {
5885 if ((i & cpi->target_sprt) == 0)
5888 fprintf(stdout, "%s supports ", adapter_str);
5891 str = "target mode processor mode";
5894 str = "target mode phase cog. mode";
5896 case PIT_DISCONNECT:
5897 str = "disconnects in target mode";
5900 str = "terminate I/O message in target mode";
5903 str = "group 6 commands in target mode";
5906 str = "group 7 commands in target mode";
5909 str = "unknown PIT bit set";
5913 fprintf(stdout, "%s\n", str);
5915 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5917 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5919 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5921 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5922 adapter_str, cpi->hpath_id);
5923 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5925 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5926 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5927 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5928 adapter_str, cpi->hba_vendor);
5929 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5930 adapter_str, cpi->hba_device);
5931 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5932 adapter_str, cpi->hba_subvendor);
5933 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5934 adapter_str, cpi->hba_subdevice);
5935 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5936 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5937 if (cpi->base_transfer_speed > 1000)
5938 fprintf(stdout, "%d.%03dMB/sec\n",
5939 cpi->base_transfer_speed / 1000,
5940 cpi->base_transfer_speed % 1000);
5942 fprintf(stdout, "%dKB/sec\n",
5943 (cpi->base_transfer_speed % 1000) * 1000);
5944 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5945 adapter_str, cpi->maxio);
5949 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5950 struct ccb_trans_settings *cts)
5956 ccb = cam_getccb(device);
5959 warnx("get_print_cts: error allocating ccb");
5963 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5965 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5967 if (user_settings == 0)
5968 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5970 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5972 if (cam_send_ccb(device, ccb) < 0) {
5973 warn("error sending XPT_GET_TRAN_SETTINGS CCB");
5975 goto get_print_cts_bailout;
5978 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5979 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5980 if (arglist & CAM_ARG_VERBOSE)
5981 cam_error_print(device, ccb, CAM_ESF_ALL,
5982 CAM_EPF_ALL, stderr);
5984 goto get_print_cts_bailout;
5988 cts_print(device, &ccb->cts);
5991 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5993 get_print_cts_bailout:
6001 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
6002 int timeout, int argc, char **argv, char *combinedopt)
6006 int user_settings = 0;
6008 int disc_enable = -1, tag_enable = -1;
6011 double syncrate = -1;
6014 int change_settings = 0, send_tur = 0;
6015 struct ccb_pathinq cpi;
6017 ccb = cam_getccb(device);
6019 warnx("ratecontrol: error allocating ccb");
6022 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6031 if (strncasecmp(optarg, "enable", 6) == 0)
6033 else if (strncasecmp(optarg, "disable", 7) == 0)
6036 warnx("-D argument \"%s\" is unknown", optarg);
6038 goto ratecontrol_bailout;
6040 change_settings = 1;
6043 mode = ata_string2mode(optarg);
6045 warnx("unknown mode '%s'", optarg);
6047 goto ratecontrol_bailout;
6049 change_settings = 1;
6052 offset = strtol(optarg, NULL, 0);
6054 warnx("offset value %d is < 0", offset);
6056 goto ratecontrol_bailout;
6058 change_settings = 1;
6064 syncrate = atof(optarg);
6066 warnx("sync rate %f is < 0", syncrate);
6068 goto ratecontrol_bailout;
6070 change_settings = 1;
6073 if (strncasecmp(optarg, "enable", 6) == 0)
6075 else if (strncasecmp(optarg, "disable", 7) == 0)
6078 warnx("-T argument \"%s\" is unknown", optarg);
6080 goto ratecontrol_bailout;
6082 change_settings = 1;
6088 bus_width = strtol(optarg, NULL, 0);
6089 if (bus_width < 0) {
6090 warnx("bus width %d is < 0", bus_width);
6092 goto ratecontrol_bailout;
6094 change_settings = 1;
6101 * Grab path inquiry information, so we can determine whether
6102 * or not the initiator is capable of the things that the user
6105 if ((retval = get_cpi(device, &cpi)) != 0)
6106 goto ratecontrol_bailout;
6107 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
6109 fprintf(stdout, "%s parameters:\n",
6110 user_settings ? "User" : "Current");
6112 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
6114 goto ratecontrol_bailout;
6116 if (arglist & CAM_ARG_VERBOSE)
6119 if (change_settings) {
6120 int didsettings = 0;
6121 struct ccb_trans_settings_spi *spi = NULL;
6122 struct ccb_trans_settings_pata *pata = NULL;
6123 struct ccb_trans_settings_sata *sata = NULL;
6124 struct ccb_trans_settings_ata *ata = NULL;
6125 struct ccb_trans_settings_scsi *scsi = NULL;
6127 if (ccb->cts.transport == XPORT_SPI)
6128 spi = &ccb->cts.xport_specific.spi;
6129 if (ccb->cts.transport == XPORT_ATA)
6130 pata = &ccb->cts.xport_specific.ata;
6131 if (ccb->cts.transport == XPORT_SATA)
6132 sata = &ccb->cts.xport_specific.sata;
6133 if (ccb->cts.protocol == PROTO_ATA)
6134 ata = &ccb->cts.proto_specific.ata;
6135 if (ccb->cts.protocol == PROTO_SCSI)
6136 scsi = &ccb->cts.proto_specific.scsi;
6137 ccb->cts.xport_specific.valid = 0;
6138 ccb->cts.proto_specific.valid = 0;
6139 if (spi && disc_enable != -1) {
6140 spi->valid |= CTS_SPI_VALID_DISC;
6141 if (disc_enable == 0)
6142 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6144 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6147 if (tag_enable != -1) {
6148 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6149 warnx("HBA does not support tagged queueing, "
6150 "so you cannot modify tag settings");
6152 goto ratecontrol_bailout;
6155 ata->valid |= CTS_SCSI_VALID_TQ;
6156 if (tag_enable == 0)
6157 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6159 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6162 scsi->valid |= CTS_SCSI_VALID_TQ;
6163 if (tag_enable == 0)
6164 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6166 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6170 if (spi && offset != -1) {
6171 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6172 warnx("HBA is not capable of changing offset");
6174 goto ratecontrol_bailout;
6176 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6177 spi->sync_offset = offset;
6180 if (spi && syncrate != -1) {
6181 int prelim_sync_period;
6183 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6184 warnx("HBA is not capable of changing "
6187 goto ratecontrol_bailout;
6189 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6191 * The sync rate the user gives us is in MHz.
6192 * We need to translate it into KHz for this
6197 * Next, we calculate a "preliminary" sync period
6198 * in tenths of a nanosecond.
6201 prelim_sync_period = 0;
6203 prelim_sync_period = 10000000 / syncrate;
6205 scsi_calc_syncparam(prelim_sync_period);
6208 if (sata && syncrate != -1) {
6209 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6210 warnx("HBA is not capable of changing "
6213 goto ratecontrol_bailout;
6215 if (!user_settings) {
6216 warnx("You can modify only user rate "
6217 "settings for SATA");
6219 goto ratecontrol_bailout;
6221 sata->revision = ata_speed2revision(syncrate * 100);
6222 if (sata->revision < 0) {
6223 warnx("Invalid rate %f", syncrate);
6225 goto ratecontrol_bailout;
6227 sata->valid |= CTS_SATA_VALID_REVISION;
6230 if ((pata || sata) && mode != -1) {
6231 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6232 warnx("HBA is not capable of changing "
6235 goto ratecontrol_bailout;
6237 if (!user_settings) {
6238 warnx("You can modify only user mode "
6239 "settings for ATA/SATA");
6241 goto ratecontrol_bailout;
6245 pata->valid |= CTS_ATA_VALID_MODE;
6248 sata->valid |= CTS_SATA_VALID_MODE;
6253 * The bus_width argument goes like this:
6257 * Therefore, if you shift the number of bits given on the
6258 * command line right by 4, you should get the correct
6261 if (spi && bus_width != -1) {
6263 * We might as well validate things here with a
6264 * decipherable error message, rather than what
6265 * will probably be an indecipherable error message
6266 * by the time it gets back to us.
6268 if ((bus_width == 16)
6269 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6270 warnx("HBA does not support 16 bit bus width");
6272 goto ratecontrol_bailout;
6273 } else if ((bus_width == 32)
6274 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6275 warnx("HBA does not support 32 bit bus width");
6277 goto ratecontrol_bailout;
6278 } else if ((bus_width != 8)
6279 && (bus_width != 16)
6280 && (bus_width != 32)) {
6281 warnx("Invalid bus width %d", bus_width);
6283 goto ratecontrol_bailout;
6285 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6286 spi->bus_width = bus_width >> 4;
6289 if (didsettings == 0) {
6290 goto ratecontrol_bailout;
6292 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6293 if (cam_send_ccb(device, ccb) < 0) {
6294 warn("error sending XPT_SET_TRAN_SETTINGS CCB");
6296 goto ratecontrol_bailout;
6298 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6299 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6300 if (arglist & CAM_ARG_VERBOSE) {
6301 cam_error_print(device, ccb, CAM_ESF_ALL,
6302 CAM_EPF_ALL, stderr);
6305 goto ratecontrol_bailout;
6309 retval = testunitready(device, task_attr, retry_count, timeout,
6310 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6312 * If the TUR didn't succeed, just bail.
6316 fprintf(stderr, "Test Unit Ready failed\n");
6317 goto ratecontrol_bailout;
6320 if ((change_settings || send_tur) && !quiet &&
6321 (ccb->cts.transport == XPORT_ATA ||
6322 ccb->cts.transport == XPORT_SATA || send_tur)) {
6323 fprintf(stdout, "New parameters:\n");
6324 retval = get_print_cts(device, user_settings, 0, NULL);
6327 ratecontrol_bailout:
6333 scsiformat(struct cam_device *device, int argc, char **argv,
6334 char *combinedopt, int task_attr, int retry_count, int timeout)
6338 int ycount = 0, quiet = 0;
6339 int error = 0, retval = 0;
6340 int use_timeout = 10800 * 1000;
6342 struct format_defect_list_header fh;
6343 u_int8_t *data_ptr = NULL;
6344 u_int32_t dxfer_len = 0;
6346 int num_warnings = 0;
6349 ccb = cam_getccb(device);
6352 warnx("scsiformat: error allocating ccb");
6356 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6358 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6378 if (quiet == 0 && ycount == 0) {
6379 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6380 "following device:\n");
6382 error = scsidoinquiry(device, argc, argv, combinedopt,
6383 task_attr, retry_count, timeout);
6386 warnx("scsiformat: error sending inquiry");
6387 goto scsiformat_bailout;
6392 if (!get_confirmation()) {
6394 goto scsiformat_bailout;
6399 use_timeout = timeout;
6402 fprintf(stdout, "Current format timeout is %d seconds\n",
6403 use_timeout / 1000);
6407 * If the user hasn't disabled questions and didn't specify a
6408 * timeout on the command line, ask them if they want the current
6412 && (timeout == 0)) {
6414 int new_timeout = 0;
6416 fprintf(stdout, "Enter new timeout in seconds or press\n"
6417 "return to keep the current timeout [%d] ",
6418 use_timeout / 1000);
6420 if (fgets(str, sizeof(str), stdin) != NULL) {
6422 new_timeout = atoi(str);
6425 if (new_timeout != 0) {
6426 use_timeout = new_timeout * 1000;
6427 fprintf(stdout, "Using new timeout value %d\n",
6428 use_timeout / 1000);
6433 * Keep this outside the if block below to silence any unused
6434 * variable warnings.
6436 bzero(&fh, sizeof(fh));
6439 * If we're in immediate mode, we've got to include the format
6442 if (immediate != 0) {
6443 fh.byte2 = FU_DLH_IMMED;
6444 data_ptr = (u_int8_t *)&fh;
6445 dxfer_len = sizeof(fh);
6446 byte2 = FU_FMT_DATA;
6447 } else if (quiet == 0) {
6448 fprintf(stdout, "Formatting...");
6452 scsi_format_unit(&ccb->csio,
6453 /* retries */ retry_count,
6455 /* tag_action */ task_attr,
6458 /* data_ptr */ data_ptr,
6459 /* dxfer_len */ dxfer_len,
6460 /* sense_len */ SSD_FULL_SIZE,
6461 /* timeout */ use_timeout);
6463 /* Disable freezing the device queue */
6464 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6466 if (arglist & CAM_ARG_ERR_RECOVER)
6467 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6469 if (((retval = cam_send_ccb(device, ccb)) < 0)
6470 || ((immediate == 0)
6471 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6472 const char errstr[] = "error sending format command";
6479 if (arglist & CAM_ARG_VERBOSE) {
6480 cam_error_print(device, ccb, CAM_ESF_ALL,
6481 CAM_EPF_ALL, stderr);
6484 goto scsiformat_bailout;
6488 * If we ran in non-immediate mode, we already checked for errors
6489 * above and printed out any necessary information. If we're in
6490 * immediate mode, we need to loop through and get status
6491 * information periodically.
6493 if (immediate == 0) {
6495 fprintf(stdout, "Format Complete\n");
6497 goto scsiformat_bailout;
6504 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6507 * There's really no need to do error recovery or
6508 * retries here, since we're just going to sit in a
6509 * loop and wait for the device to finish formatting.
6511 scsi_test_unit_ready(&ccb->csio,
6514 /* tag_action */ task_attr,
6515 /* sense_len */ SSD_FULL_SIZE,
6516 /* timeout */ 5000);
6518 /* Disable freezing the device queue */
6519 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6521 retval = cam_send_ccb(device, ccb);
6524 * If we get an error from the ioctl, bail out. SCSI
6525 * errors are expected.
6528 warn("error sending TEST UNIT READY command");
6530 goto scsiformat_bailout;
6533 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6535 if ((status != CAM_REQ_CMP)
6536 && (status == CAM_SCSI_STATUS_ERROR)
6537 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6538 struct scsi_sense_data *sense;
6539 int error_code, sense_key, asc, ascq;
6541 sense = &ccb->csio.sense_data;
6542 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6543 ccb->csio.sense_resid, &error_code, &sense_key,
6544 &asc, &ascq, /*show_errors*/ 1);
6547 * According to the SCSI-2 and SCSI-3 specs, a
6548 * drive that is in the middle of a format should
6549 * return NOT READY with an ASC of "logical unit
6550 * not ready, format in progress". The sense key
6551 * specific bytes will then be a progress indicator.
6553 if ((sense_key == SSD_KEY_NOT_READY)
6554 && (asc == 0x04) && (ascq == 0x04)) {
6557 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6558 ccb->csio.sense_resid, sks) == 0)
6561 u_int64_t percentage;
6563 val = scsi_2btoul(&sks[1]);
6564 percentage = 10000ull * val;
6567 "\rFormatting: %ju.%02u %% "
6569 (uintmax_t)(percentage /
6571 (unsigned)((percentage /
6575 } else if ((quiet == 0)
6576 && (++num_warnings <= 1)) {
6577 warnx("Unexpected SCSI Sense Key "
6578 "Specific value returned "
6580 scsi_sense_print(device, &ccb->csio,
6582 warnx("Unable to print status "
6583 "information, but format will "
6585 warnx("will exit when format is "
6590 warnx("Unexpected SCSI error during format");
6591 cam_error_print(device, ccb, CAM_ESF_ALL,
6592 CAM_EPF_ALL, stderr);
6594 goto scsiformat_bailout;
6597 } else if (status != CAM_REQ_CMP) {
6598 warnx("Unexpected CAM status %#x", status);
6599 if (arglist & CAM_ARG_VERBOSE)
6600 cam_error_print(device, ccb, CAM_ESF_ALL,
6601 CAM_EPF_ALL, stderr);
6603 goto scsiformat_bailout;
6606 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6609 fprintf(stdout, "\nFormat Complete\n");
6619 sanitize_wait_ata(struct cam_device *device, union ccb *ccb, int quiet,
6620 camcontrol_devtype devtype)
6623 uint8_t error = 0, ata_device = 0, status = 0;
6629 retval = build_ata_cmd(ccb,
6631 /*flags*/ CAM_DIR_NONE,
6632 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6633 /*protocol*/ AP_PROTO_NON_DATA,
6634 /*ata_flags*/ AP_FLAG_CHK_COND,
6635 /*features*/ 0x00, /* SANITIZE STATUS EXT */
6638 /*command*/ ATA_SANITIZE,
6642 /*cdb_storage*/ NULL,
6643 /*cdb_storage_len*/ 0,
6644 /*sense_len*/ SSD_FULL_SIZE,
6647 /*devtype*/ devtype);
6649 warnx("%s: build_ata_cmd() failed, likely "
6650 "programmer error", __func__);
6654 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6655 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6656 retval = cam_send_ccb(device, ccb);
6658 warn("error sending SANITIZE STATUS EXT command");
6662 retval = get_ata_status(device, ccb, &error, &count, &lba,
6663 &ata_device, &status);
6665 warnx("Can't get SANITIZE STATUS EXT status, "
6666 "sanitize may still run.");
6669 if (status & ATA_STATUS_ERROR) {
6670 warnx("SANITIZE STATUS EXT failed, "
6671 "sanitize may still run.");
6674 if (count & 0x4000) {
6679 "Sanitizing: %u.%02u%% (%d/%d)\r",
6680 (perc / (0x10000 * 100)),
6681 ((perc / 0x10000) % 100),
6686 } else if ((count & 0x8000) == 0) {
6687 warnx("Sanitize complete with an error. ");
6696 sanitize_wait_scsi(struct cam_device *device, union ccb *ccb, int task_attr, int quiet)
6698 int warnings = 0, retval;
6703 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6706 * There's really no need to do error recovery or
6707 * retries here, since we're just going to sit in a
6708 * loop and wait for the device to finish sanitizing.
6710 scsi_test_unit_ready(&ccb->csio,
6713 /* tag_action */ task_attr,
6714 /* sense_len */ SSD_FULL_SIZE,
6715 /* timeout */ 5000);
6717 /* Disable freezing the device queue */
6718 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6720 retval = cam_send_ccb(device, ccb);
6723 * If we get an error from the ioctl, bail out. SCSI
6724 * errors are expected.
6727 warn("error sending TEST UNIT READY command");
6731 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6732 if ((status == CAM_SCSI_STATUS_ERROR) &&
6733 ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6734 struct scsi_sense_data *sense;
6735 int error_code, sense_key, asc, ascq;
6737 sense = &ccb->csio.sense_data;
6738 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6739 ccb->csio.sense_resid, &error_code, &sense_key,
6740 &asc, &ascq, /*show_errors*/ 1);
6743 * According to the SCSI-3 spec, a drive that is in the
6744 * middle of a sanitize should return NOT READY with an
6745 * ASC of "logical unit not ready, sanitize in
6746 * progress". The sense key specific bytes will then
6747 * be a progress indicator.
6749 if ((sense_key == SSD_KEY_NOT_READY)
6750 && (asc == 0x04) && (ascq == 0x1b)) {
6753 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6754 ccb->csio.sense_resid, sks) == 0)
6756 val = scsi_2btoul(&sks[1]);
6759 "Sanitizing: %u.%02u%% (%d/%d)\r",
6760 (perc / (0x10000 * 100)),
6761 ((perc / 0x10000) % 100),
6764 } else if ((quiet == 0) && (++warnings <= 1)) {
6765 warnx("Unexpected SCSI Sense Key "
6766 "Specific value returned "
6767 "during sanitize:");
6768 scsi_sense_print(device, &ccb->csio,
6770 warnx("Unable to print status "
6771 "information, but sanitze will "
6773 warnx("will exit when sanitize is "
6778 warnx("Unexpected SCSI error during sanitize");
6779 cam_error_print(device, ccb, CAM_ESF_ALL,
6780 CAM_EPF_ALL, stderr);
6784 } else if (status != CAM_REQ_CMP && status != CAM_REQUEUE_REQ) {
6785 warnx("Unexpected CAM status %#x", status);
6786 if (arglist & CAM_ARG_VERBOSE)
6787 cam_error_print(device, ccb, CAM_ESF_ALL,
6788 CAM_EPF_ALL, stderr);
6791 } while ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6796 sanitize(struct cam_device *device, int argc, char **argv,
6797 char *combinedopt, int task_attr, int retry_count, int timeout)
6800 u_int8_t action = 0;
6802 int ycount = 0, quiet = 0;
6810 const char *pattern = NULL;
6811 u_int8_t *data_ptr = NULL;
6812 u_int32_t dxfer_len = 0;
6814 uint16_t feature, count;
6817 camcontrol_devtype dt;
6820 * Get the device type, request no I/O be done to do this.
6822 error = get_device_type(device, -1, 0, 0, &dt);
6823 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
6824 warnx("sanitize: can't get device type");
6828 ccb = cam_getccb(device);
6831 warnx("sanitize: error allocating ccb");
6835 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6837 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6840 if (strcasecmp(optarg, "overwrite") == 0)
6841 action = SSZ_SERVICE_ACTION_OVERWRITE;
6842 else if (strcasecmp(optarg, "block") == 0)
6843 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6844 else if (strcasecmp(optarg, "crypto") == 0)
6845 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6846 else if (strcasecmp(optarg, "exitfailure") == 0)
6847 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6849 warnx("invalid service operation \"%s\"",
6852 goto sanitize_bailout;
6856 passes = strtol(optarg, NULL, 0);
6857 if (passes < 1 || passes > 31) {
6858 warnx("invalid passes value %d", passes);
6860 goto sanitize_bailout;
6879 /* ATA supports only immediate commands. */
6880 if (dt == CC_DT_SCSI)
6893 warnx("an action is required");
6895 goto sanitize_bailout;
6896 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6897 struct scsi_sanitize_parameter_list *pl;
6901 if (pattern == NULL) {
6902 warnx("overwrite action requires -P argument");
6904 goto sanitize_bailout;
6906 fd = open(pattern, O_RDONLY);
6908 warn("cannot open pattern file %s", pattern);
6910 goto sanitize_bailout;
6912 if (fstat(fd, &sb) < 0) {
6913 warn("cannot stat pattern file %s", pattern);
6915 goto sanitize_bailout;
6918 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6919 warnx("pattern file size exceeds maximum value %d",
6920 SSZPL_MAX_PATTERN_LENGTH);
6922 goto sanitize_bailout;
6924 dxfer_len = sizeof(*pl) + sz;
6925 data_ptr = calloc(1, dxfer_len);
6926 if (data_ptr == NULL) {
6927 warnx("cannot allocate parameter list buffer");
6929 goto sanitize_bailout;
6932 amt = read(fd, data_ptr + sizeof(*pl), sz);
6934 warn("cannot read pattern file");
6936 goto sanitize_bailout;
6937 } else if (amt != sz) {
6938 warnx("short pattern file read");
6940 goto sanitize_bailout;
6943 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6949 pl->byte1 |= SSZPL_INVERT;
6950 scsi_ulto2b(sz, pl->length);
6956 else if (invert != 0)
6958 else if (pattern != NULL)
6963 warnx("%s argument only valid with overwrite "
6966 goto sanitize_bailout;
6970 if (quiet == 0 && ycount == 0) {
6971 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6972 "following device:\n");
6974 if (dt == CC_DT_SCSI) {
6975 error = scsidoinquiry(device, argc, argv, combinedopt,
6976 task_attr, retry_count, timeout);
6977 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
6978 struct ata_params *ident_buf;
6979 error = ata_do_identify(device, retry_count, timeout,
6982 printf("%s%d: ", device->device_name,
6983 device->dev_unit_num);
6984 ata_print_ident(ident_buf);
6991 warnx("sanitize: error sending inquiry");
6992 goto sanitize_bailout;
6997 if (!get_confirmation()) {
6999 goto sanitize_bailout;
7004 use_timeout = timeout;
7006 use_timeout = (immediate ? 10 : 10800) * 1000;
7008 if (immediate == 0 && quiet == 0) {
7009 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
7010 use_timeout / 1000);
7014 * If the user hasn't disabled questions and didn't specify a
7015 * timeout on the command line, ask them if they want the current
7018 if (immediate == 0 && ycount == 0 && timeout == 0) {
7020 int new_timeout = 0;
7022 fprintf(stdout, "Enter new timeout in seconds or press\n"
7023 "return to keep the current timeout [%d] ",
7024 use_timeout / 1000);
7026 if (fgets(str, sizeof(str), stdin) != NULL) {
7028 new_timeout = atoi(str);
7031 if (new_timeout != 0) {
7032 use_timeout = new_timeout * 1000;
7033 fprintf(stdout, "Using new timeout value %d\n",
7034 use_timeout / 1000);
7038 if (dt == CC_DT_SCSI) {
7041 byte2 |= SSZ_UNRESTRICTED_EXIT;
7044 scsi_sanitize(&ccb->csio,
7045 /* retries */ retry_count,
7047 /* tag_action */ task_attr,
7050 /* data_ptr */ data_ptr,
7051 /* dxfer_len */ dxfer_len,
7052 /* sense_len */ SSD_FULL_SIZE,
7053 /* timeout */ use_timeout);
7055 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7056 if (arglist & CAM_ARG_ERR_RECOVER)
7057 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7058 if (cam_send_ccb(device, ccb) < 0) {
7059 warn("error sending sanitize command");
7061 goto sanitize_bailout;
7063 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7064 if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
7065 feature = 0x14; /* OVERWRITE EXT */
7066 lba = 0x4F5700000000 | scsi_4btoul(data_ptr + 4);
7067 count = (passes == 0) ? 1 : (passes >= 16) ? 0 : passes;
7069 count |= 0x80; /* INVERT PATTERN */
7071 count |= 0x10; /* FAILURE MODE */
7072 } else if (action == SSZ_SERVICE_ACTION_BLOCK_ERASE) {
7073 feature = 0x12; /* BLOCK ERASE EXT */
7074 lba = 0x0000426B4572;
7077 count |= 0x10; /* FAILURE MODE */
7078 } else if (action == SSZ_SERVICE_ACTION_CRYPTO_ERASE) {
7079 feature = 0x11; /* CRYPTO SCRAMBLE EXT */
7080 lba = 0x000043727970;
7083 count |= 0x10; /* FAILURE MODE */
7084 } else if (action == SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE) {
7085 feature = 0x00; /* SANITIZE STATUS EXT */
7087 count = 1; /* CLEAR SANITIZE OPERATION FAILED */
7090 goto sanitize_bailout;
7093 error = ata_do_cmd(device,
7096 /*flags*/CAM_DIR_NONE,
7097 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
7099 /*tag_action*/MSG_SIMPLE_Q_TAG,
7100 /*command*/ATA_SANITIZE,
7101 /*features*/feature,
7103 /*sector_count*/count,
7106 /*timeout*/ use_timeout,
7110 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7111 struct scsi_sense_data *sense;
7112 int error_code, sense_key, asc, ascq;
7114 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
7115 CAM_SCSI_STATUS_ERROR) {
7116 sense = &ccb->csio.sense_data;
7117 scsi_extract_sense_len(sense, ccb->csio.sense_len -
7118 ccb->csio.sense_resid, &error_code, &sense_key,
7119 &asc, &ascq, /*show_errors*/ 1);
7121 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
7122 asc == 0x20 && ascq == 0x00)
7123 warnx("sanitize is not supported by "
7126 warnx("error sanitizing this device");
7128 warnx("error sanitizing this device");
7130 if (arglist & CAM_ARG_VERBOSE) {
7131 cam_error_print(device, ccb, CAM_ESF_ALL,
7132 CAM_EPF_ALL, stderr);
7135 goto sanitize_bailout;
7139 * If we ran in non-immediate mode, we already checked for errors
7140 * above and printed out any necessary information. If we're in
7141 * immediate mode, we need to loop through and get status
7142 * information periodically.
7144 if (immediate == 0) {
7146 fprintf(stdout, "Sanitize Complete\n");
7148 goto sanitize_bailout;
7152 if (dt == CC_DT_SCSI) {
7153 error = sanitize_wait_scsi(device, ccb, task_attr, quiet);
7154 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7155 error = sanitize_wait_ata(device, ccb, quiet, dt);
7158 if (error == 0 && quiet == 0)
7159 fprintf(stdout, "Sanitize Complete \n");
7164 if (data_ptr != NULL)
7172 scsireportluns(struct cam_device *device, int argc, char **argv,
7173 char *combinedopt, int task_attr, int retry_count, int timeout)
7176 int c, countonly, lunsonly;
7177 struct scsi_report_luns_data *lundata;
7179 uint8_t report_type;
7180 uint32_t list_len, i, j;
7185 report_type = RPL_REPORT_DEFAULT;
7186 ccb = cam_getccb(device);
7189 warnx("%s: error allocating ccb", __func__);
7193 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7198 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7207 if (strcasecmp(optarg, "default") == 0)
7208 report_type = RPL_REPORT_DEFAULT;
7209 else if (strcasecmp(optarg, "wellknown") == 0)
7210 report_type = RPL_REPORT_WELLKNOWN;
7211 else if (strcasecmp(optarg, "all") == 0)
7212 report_type = RPL_REPORT_ALL;
7214 warnx("%s: invalid report type \"%s\"",
7225 if ((countonly != 0)
7226 && (lunsonly != 0)) {
7227 warnx("%s: you can only specify one of -c or -l", __func__);
7232 * According to SPC-4, the allocation length must be at least 16
7233 * bytes -- enough for the header and one LUN.
7235 alloc_len = sizeof(*lundata) + 8;
7239 lundata = malloc(alloc_len);
7241 if (lundata == NULL) {
7242 warn("%s: error mallocing %d bytes", __func__, alloc_len);
7247 scsi_report_luns(&ccb->csio,
7248 /*retries*/ retry_count,
7250 /*tag_action*/ task_attr,
7251 /*select_report*/ report_type,
7252 /*rpl_buf*/ lundata,
7253 /*alloc_len*/ alloc_len,
7254 /*sense_len*/ SSD_FULL_SIZE,
7255 /*timeout*/ timeout ? timeout : 5000);
7257 /* Disable freezing the device queue */
7258 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7260 if (arglist & CAM_ARG_ERR_RECOVER)
7261 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7263 if (cam_send_ccb(device, ccb) < 0) {
7264 warn("error sending REPORT LUNS command");
7269 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7270 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7276 list_len = scsi_4btoul(lundata->length);
7279 * If we need to list the LUNs, and our allocation
7280 * length was too short, reallocate and retry.
7282 if ((countonly == 0)
7283 && (list_len > (alloc_len - sizeof(*lundata)))) {
7284 alloc_len = list_len + sizeof(*lundata);
7290 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7291 ((list_len / 8) > 1) ? "s" : "");
7296 for (i = 0; i < (list_len / 8); i++) {
7300 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7302 fprintf(stdout, ",");
7303 switch (lundata->luns[i].lundata[j] &
7304 RPL_LUNDATA_ATYP_MASK) {
7305 case RPL_LUNDATA_ATYP_PERIPH:
7306 if ((lundata->luns[i].lundata[j] &
7307 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7308 fprintf(stdout, "%d:",
7309 lundata->luns[i].lundata[j] &
7310 RPL_LUNDATA_PERIPH_BUS_MASK);
7312 && ((lundata->luns[i].lundata[j+2] &
7313 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7316 fprintf(stdout, "%d",
7317 lundata->luns[i].lundata[j+1]);
7319 case RPL_LUNDATA_ATYP_FLAT: {
7321 tmplun[0] = lundata->luns[i].lundata[j] &
7322 RPL_LUNDATA_FLAT_LUN_MASK;
7323 tmplun[1] = lundata->luns[i].lundata[j+1];
7325 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7329 case RPL_LUNDATA_ATYP_LUN:
7330 fprintf(stdout, "%d:%d:%d",
7331 (lundata->luns[i].lundata[j+1] &
7332 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7333 lundata->luns[i].lundata[j] &
7334 RPL_LUNDATA_LUN_TARG_MASK,
7335 lundata->luns[i].lundata[j+1] &
7336 RPL_LUNDATA_LUN_LUN_MASK);
7338 case RPL_LUNDATA_ATYP_EXTLUN: {
7339 int field_len_code, eam_code;
7341 eam_code = lundata->luns[i].lundata[j] &
7342 RPL_LUNDATA_EXT_EAM_MASK;
7343 field_len_code = (lundata->luns[i].lundata[j] &
7344 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7346 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7347 && (field_len_code == 0x00)) {
7348 fprintf(stdout, "%d",
7349 lundata->luns[i].lundata[j+1]);
7350 } else if ((eam_code ==
7351 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7352 && (field_len_code == 0x03)) {
7356 * This format takes up all 8 bytes.
7357 * If we aren't starting at offset 0,
7361 fprintf(stdout, "Invalid "
7364 "specified format", j);
7368 bzero(tmp_lun, sizeof(tmp_lun));
7369 bcopy(&lundata->luns[i].lundata[j+1],
7370 &tmp_lun[1], sizeof(tmp_lun) - 1);
7371 fprintf(stdout, "%#jx",
7372 (intmax_t)scsi_8btou64(tmp_lun));
7375 fprintf(stderr, "Unknown Extended LUN"
7376 "Address method %#x, length "
7377 "code %#x", eam_code,
7384 fprintf(stderr, "Unknown LUN address method "
7385 "%#x\n", lundata->luns[i].lundata[0] &
7386 RPL_LUNDATA_ATYP_MASK);
7390 * For the flat addressing method, there are no
7391 * other levels after it.
7396 fprintf(stdout, "\n");
7409 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7410 char *combinedopt, int task_attr, int retry_count, int timeout)
7413 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7414 struct scsi_read_capacity_data rcap;
7415 struct scsi_read_capacity_data_long rcaplong;
7430 ccb = cam_getccb(device);
7433 warnx("%s: error allocating ccb", __func__);
7437 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7439 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7469 if ((blocksizeonly != 0)
7470 && (numblocks != 0)) {
7471 warnx("%s: you can only specify one of -b or -N", __func__);
7476 if ((blocksizeonly != 0)
7477 && (sizeonly != 0)) {
7478 warnx("%s: you can only specify one of -b or -s", __func__);
7485 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7491 && (blocksizeonly != 0)) {
7492 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7500 scsi_read_capacity(&ccb->csio,
7501 /*retries*/ retry_count,
7503 /*tag_action*/ task_attr,
7506 /*timeout*/ timeout ? timeout : 5000);
7508 /* Disable freezing the device queue */
7509 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7511 if (arglist & CAM_ARG_ERR_RECOVER)
7512 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7514 if (cam_send_ccb(device, ccb) < 0) {
7515 warn("error sending READ CAPACITY command");
7520 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7521 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7526 maxsector = scsi_4btoul(rcap.addr);
7527 block_len = scsi_4btoul(rcap.length);
7530 * A last block of 2^32-1 means that the true capacity is over 2TB,
7531 * and we need to issue the long READ CAPACITY to get the real
7532 * capacity. Otherwise, we're all set.
7534 if (maxsector != 0xffffffff)
7538 scsi_read_capacity_16(&ccb->csio,
7539 /*retries*/ retry_count,
7541 /*tag_action*/ task_attr,
7545 /*rcap_buf*/ (uint8_t *)&rcaplong,
7546 /*rcap_buf_len*/ sizeof(rcaplong),
7547 /*sense_len*/ SSD_FULL_SIZE,
7548 /*timeout*/ timeout ? timeout : 5000);
7550 /* Disable freezing the device queue */
7551 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7553 if (arglist & CAM_ARG_ERR_RECOVER)
7554 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7556 if (cam_send_ccb(device, ccb) < 0) {
7557 warn("error sending READ CAPACITY (16) command");
7562 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7563 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7568 maxsector = scsi_8btou64(rcaplong.addr);
7569 block_len = scsi_4btoul(rcaplong.length);
7572 if (blocksizeonly == 0) {
7574 * Humanize implies !quiet, and also implies numblocks.
7576 if (humanize != 0) {
7581 tmpbytes = (maxsector + 1) * block_len;
7582 ret = humanize_number(tmpstr, sizeof(tmpstr),
7583 tmpbytes, "", HN_AUTOSCALE,
7586 HN_DIVISOR_1000 : 0));
7588 warnx("%s: humanize_number failed!", __func__);
7592 fprintf(stdout, "Device Size: %s%s", tmpstr,
7593 (sizeonly == 0) ? ", " : "\n");
7594 } else if (numblocks != 0) {
7595 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7596 "Blocks: " : "", (uintmax_t)maxsector + 1,
7597 (sizeonly == 0) ? ", " : "\n");
7599 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7600 "Last Block: " : "", (uintmax_t)maxsector,
7601 (sizeonly == 0) ? ", " : "\n");
7605 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7606 "Block Length: " : "", block_len, (quiet == 0) ?
7615 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7616 int retry_count, int timeout)
7620 uint8_t *smp_request = NULL, *smp_response = NULL;
7621 int request_size = 0, response_size = 0;
7622 int fd_request = 0, fd_response = 0;
7623 char *datastr = NULL;
7624 struct get_hook hook;
7629 * Note that at the moment we don't support sending SMP CCBs to
7630 * devices that aren't probed by CAM.
7632 ccb = cam_getccb(device);
7634 warnx("%s: error allocating CCB", __func__);
7638 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7640 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7643 arglist |= CAM_ARG_CMD_IN;
7644 response_size = strtol(optarg, NULL, 0);
7645 if (response_size <= 0) {
7646 warnx("invalid number of response bytes %d",
7649 goto smpcmd_bailout;
7651 hook.argc = argc - optind;
7652 hook.argv = argv + optind;
7655 datastr = cget(&hook, NULL);
7657 * If the user supplied "-" instead of a format, he
7658 * wants the data to be written to stdout.
7660 if ((datastr != NULL)
7661 && (datastr[0] == '-'))
7664 smp_response = (u_int8_t *)malloc(response_size);
7665 if (smp_response == NULL) {
7666 warn("can't malloc memory for SMP response");
7668 goto smpcmd_bailout;
7672 arglist |= CAM_ARG_CMD_OUT;
7673 request_size = strtol(optarg, NULL, 0);
7674 if (request_size <= 0) {
7675 warnx("invalid number of request bytes %d",
7678 goto smpcmd_bailout;
7680 hook.argc = argc - optind;
7681 hook.argv = argv + optind;
7683 datastr = cget(&hook, NULL);
7684 smp_request = (u_int8_t *)malloc(request_size);
7685 if (smp_request == NULL) {
7686 warn("can't malloc memory for SMP request");
7688 goto smpcmd_bailout;
7690 bzero(smp_request, request_size);
7692 * If the user supplied "-" instead of a format, he
7693 * wants the data to be read from stdin.
7695 if ((datastr != NULL)
7696 && (datastr[0] == '-'))
7699 buff_encode_visit(smp_request, request_size,
7710 * If fd_data is set, and we're writing to the device, we need to
7711 * read the data the user wants written from stdin.
7713 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7715 int amt_to_read = request_size;
7716 u_int8_t *buf_ptr = smp_request;
7718 for (amt_read = 0; amt_to_read > 0;
7719 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7720 if (amt_read == -1) {
7721 warn("error reading data from stdin");
7723 goto smpcmd_bailout;
7725 amt_to_read -= amt_read;
7726 buf_ptr += amt_read;
7730 if (((arglist & CAM_ARG_CMD_IN) == 0)
7731 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7732 warnx("%s: need both the request (-r) and response (-R) "
7733 "arguments", __func__);
7735 goto smpcmd_bailout;
7738 flags |= CAM_DEV_QFRZDIS;
7740 cam_fill_smpio(&ccb->smpio,
7741 /*retries*/ retry_count,
7744 /*smp_request*/ smp_request,
7745 /*smp_request_len*/ request_size,
7746 /*smp_response*/ smp_response,
7747 /*smp_response_len*/ response_size,
7748 /*timeout*/ timeout ? timeout : 5000);
7750 ccb->smpio.flags = SMP_FLAG_NONE;
7752 if (((retval = cam_send_ccb(device, ccb)) < 0)
7753 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7754 const char warnstr[] = "error sending command";
7761 if (arglist & CAM_ARG_VERBOSE) {
7762 cam_error_print(device, ccb, CAM_ESF_ALL,
7763 CAM_EPF_ALL, stderr);
7767 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7768 && (response_size > 0)) {
7769 if (fd_response == 0) {
7770 buff_decode_visit(smp_response, response_size,
7771 datastr, arg_put, NULL);
7772 fprintf(stdout, "\n");
7774 ssize_t amt_written;
7775 int amt_to_write = response_size;
7776 u_int8_t *buf_ptr = smp_response;
7778 for (amt_written = 0; (amt_to_write > 0) &&
7779 (amt_written = write(STDOUT_FILENO, buf_ptr,
7780 amt_to_write)) > 0;){
7781 amt_to_write -= amt_written;
7782 buf_ptr += amt_written;
7784 if (amt_written == -1) {
7785 warn("error writing data to stdout");
7787 goto smpcmd_bailout;
7788 } else if ((amt_written == 0)
7789 && (amt_to_write > 0)) {
7790 warnx("only wrote %u bytes out of %u",
7791 response_size - amt_to_write,
7800 if (smp_request != NULL)
7803 if (smp_response != NULL)
7810 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7811 int retry_count, int timeout)
7815 int32_t mmc_opcode = 0, mmc_arg = 0;
7816 int32_t mmc_flags = -1;
7819 int is_bw_4 = 0, is_bw_1 = 0;
7820 int is_highspeed = 0, is_stdspeed = 0;
7821 int is_info_request = 0;
7823 uint8_t mmc_data_byte = 0;
7825 /* For IO_RW_EXTENDED command */
7826 uint8_t *mmc_data = NULL;
7827 struct mmc_data mmc_d;
7828 int mmc_data_len = 0;
7831 * Note that at the moment we don't support sending SMP CCBs to
7832 * devices that aren't probed by CAM.
7834 ccb = cam_getccb(device);
7836 warnx("%s: error allocating CCB", __func__);
7840 bzero(&(&ccb->ccb_h)[1],
7841 sizeof(union ccb) - sizeof(struct ccb_hdr));
7843 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7852 if (!strcmp(optarg, "high"))
7858 is_info_request = 1;
7861 mmc_opcode = strtol(optarg, NULL, 0);
7862 if (mmc_opcode < 0) {
7863 warnx("invalid MMC opcode %d",
7866 goto mmccmd_bailout;
7870 mmc_arg = strtol(optarg, NULL, 0);
7872 warnx("invalid MMC arg %d",
7875 goto mmccmd_bailout;
7879 mmc_flags = strtol(optarg, NULL, 0);
7880 if (mmc_flags < 0) {
7881 warnx("invalid MMC flags %d",
7884 goto mmccmd_bailout;
7888 mmc_data_len = strtol(optarg, NULL, 0);
7889 if (mmc_data_len <= 0) {
7890 warnx("invalid MMC data len %d",
7893 goto mmccmd_bailout;
7900 mmc_data_byte = strtol(optarg, NULL, 0);
7906 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7908 /* If flags are left default, supply the right flags */
7910 switch (mmc_opcode) {
7911 case MMC_GO_IDLE_STATE:
7912 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7914 case IO_SEND_OP_COND:
7915 mmc_flags = MMC_RSP_R4;
7917 case SD_SEND_RELATIVE_ADDR:
7918 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7920 case MMC_SELECT_CARD:
7921 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7922 mmc_arg = mmc_arg << 16;
7924 case SD_IO_RW_DIRECT:
7925 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7926 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7928 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7930 case SD_IO_RW_EXTENDED:
7931 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7932 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7933 int len_arg = mmc_data_len;
7934 if (mmc_data_len == 512)
7938 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7940 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7943 mmc_flags = MMC_RSP_R1;
7947 // Switch bus width instead of sending IO command
7948 if (is_bw_4 || is_bw_1) {
7949 struct ccb_trans_settings_mmc *cts;
7950 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7951 ccb->ccb_h.flags = 0;
7952 cts = &ccb->cts.proto_specific.mmc;
7953 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7954 cts->ios_valid = MMC_BW;
7955 if (((retval = cam_send_ccb(device, ccb)) < 0)
7956 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7957 warn("Error sending command");
7959 printf("Parameters set OK\n");
7965 // Switch bus speed instead of sending IO command
7966 if (is_stdspeed || is_highspeed) {
7967 struct ccb_trans_settings_mmc *cts;
7968 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7969 ccb->ccb_h.flags = 0;
7970 cts = &ccb->cts.proto_specific.mmc;
7971 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
7972 cts->ios_valid = MMC_BT;
7973 if (((retval = cam_send_ccb(device, ccb)) < 0)
7974 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7975 warn("Error sending command");
7977 printf("Speed set OK (HS: %d)\n", is_highspeed);
7983 // Get information about controller and its settings
7984 if (is_info_request) {
7985 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
7986 ccb->ccb_h.flags = 0;
7987 struct ccb_trans_settings_mmc *cts;
7988 cts = &ccb->cts.proto_specific.mmc;
7989 if (((retval = cam_send_ccb(device, ccb)) < 0)
7990 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7991 warn("Error sending command");
7994 printf("Host controller information\n");
7995 printf("Host OCR: 0x%x\n", cts->host_ocr);
7996 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
7997 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
7998 printf("Supported bus width: ");
7999 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
8001 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
8003 printf("\nCurrent settings:\n");
8004 printf("Bus width: ");
8005 switch (cts->ios.bus_width) {
8016 printf("Freq: %d.%03d MHz%s\n",
8017 cts->ios.clock / 1000000,
8018 (cts->ios.clock / 1000) % 1000,
8019 cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : "");
8023 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
8025 if (mmc_data_len > 0) {
8026 flags |= CAM_DIR_IN;
8027 mmc_data = malloc(mmc_data_len);
8028 memset(mmc_data, 0, mmc_data_len);
8029 memset(&mmc_d, 0, sizeof(mmc_d));
8030 mmc_d.len = mmc_data_len;
8031 mmc_d.data = mmc_data;
8032 mmc_d.flags = MMC_DATA_READ;
8033 } else flags |= CAM_DIR_NONE;
8035 cam_fill_mmcio(&ccb->mmcio,
8036 /*retries*/ retry_count,
8039 /*mmc_opcode*/ mmc_opcode,
8040 /*mmc_arg*/ mmc_arg,
8041 /*mmc_flags*/ mmc_flags,
8042 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
8043 /*timeout*/ timeout ? timeout : 5000);
8045 if (((retval = cam_send_ccb(device, ccb)) < 0)
8046 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8047 const char warnstr[] = "error sending command";
8054 if (arglist & CAM_ARG_VERBOSE) {
8055 cam_error_print(device, ccb, CAM_ESF_ALL,
8056 CAM_EPF_ALL, stderr);
8060 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
8061 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
8062 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
8063 ccb->mmcio.cmd.resp[1],
8064 ccb->mmcio.cmd.resp[2],
8065 ccb->mmcio.cmd.resp[3]);
8067 switch (mmc_opcode) {
8068 case SD_IO_RW_DIRECT:
8069 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
8070 SD_R5_DATA(ccb->mmcio.cmd.resp),
8071 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
8073 case SD_IO_RW_EXTENDED:
8074 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
8075 hexdump(mmc_data, mmc_data_len, NULL, 0);
8077 case SD_SEND_RELATIVE_ADDR:
8078 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
8081 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
8088 if (mmc_data_len > 0 && mmc_data != NULL)
8095 smpreportgeneral(struct cam_device *device, int argc, char **argv,
8096 char *combinedopt, int retry_count, int timeout)
8099 struct smp_report_general_request *request = NULL;
8100 struct smp_report_general_response *response = NULL;
8101 struct sbuf *sb = NULL;
8103 int c, long_response = 0;
8107 * Note that at the moment we don't support sending SMP CCBs to
8108 * devices that aren't probed by CAM.
8110 ccb = cam_getccb(device);
8112 warnx("%s: error allocating CCB", __func__);
8116 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8118 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8127 request = malloc(sizeof(*request));
8128 if (request == NULL) {
8129 warn("%s: unable to allocate %zd bytes", __func__,
8135 response = malloc(sizeof(*response));
8136 if (response == NULL) {
8137 warn("%s: unable to allocate %zd bytes", __func__,
8144 smp_report_general(&ccb->smpio,
8148 /*request_len*/ sizeof(*request),
8149 (uint8_t *)response,
8150 /*response_len*/ sizeof(*response),
8151 /*long_response*/ long_response,
8154 if (((retval = cam_send_ccb(device, ccb)) < 0)
8155 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8156 const char warnstr[] = "error sending command";
8163 if (arglist & CAM_ARG_VERBOSE) {
8164 cam_error_print(device, ccb, CAM_ESF_ALL,
8165 CAM_EPF_ALL, stderr);
8172 * If the device supports the long response bit, try again and see
8173 * if we can get all of the data.
8175 if ((response->long_response & SMP_RG_LONG_RESPONSE)
8176 && (long_response == 0)) {
8177 ccb->ccb_h.status = CAM_REQ_INPROG;
8178 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8184 * XXX KDM detect and decode SMP errors here.
8186 sb = sbuf_new_auto();
8188 warnx("%s: error allocating sbuf", __func__);
8192 smp_report_general_sbuf(response, sizeof(*response), sb);
8194 if (sbuf_finish(sb) != 0) {
8195 warnx("%s: sbuf_finish", __func__);
8199 printf("%s", sbuf_data(sb));
8205 if (request != NULL)
8208 if (response != NULL)
8217 static struct camcontrol_opts phy_ops[] = {
8218 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
8219 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
8220 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
8221 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
8222 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
8223 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
8224 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
8225 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
8226 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
8231 smpphycontrol(struct cam_device *device, int argc, char **argv,
8232 char *combinedopt, int retry_count, int timeout)
8235 struct smp_phy_control_request *request = NULL;
8236 struct smp_phy_control_response *response = NULL;
8237 int long_response = 0;
8240 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
8242 uint64_t attached_dev_name = 0;
8243 int dev_name_set = 0;
8244 uint32_t min_plr = 0, max_plr = 0;
8245 uint32_t pp_timeout_val = 0;
8246 int slumber_partial = 0;
8247 int set_pp_timeout_val = 0;
8251 * Note that at the moment we don't support sending SMP CCBs to
8252 * devices that aren't probed by CAM.
8254 ccb = cam_getccb(device);
8256 warnx("%s: error allocating CCB", __func__);
8260 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8262 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8270 if (strcasecmp(optarg, "enable") == 0)
8272 else if (strcasecmp(optarg, "disable") == 0)
8275 warnx("%s: Invalid argument %s", __func__,
8282 slumber_partial |= enable <<
8283 SMP_PC_SAS_SLUMBER_SHIFT;
8286 slumber_partial |= enable <<
8287 SMP_PC_SAS_PARTIAL_SHIFT;
8290 slumber_partial |= enable <<
8291 SMP_PC_SATA_SLUMBER_SHIFT;
8294 slumber_partial |= enable <<
8295 SMP_PC_SATA_PARTIAL_SHIFT;
8298 warnx("%s: programmer error", __func__);
8301 break; /*NOTREACHED*/
8306 attached_dev_name = (uintmax_t)strtoumax(optarg,
8315 * We don't do extensive checking here, so this
8316 * will continue to work when new speeds come out.
8318 min_plr = strtoul(optarg, NULL, 0);
8320 || (min_plr > 0xf)) {
8321 warnx("%s: invalid link rate %x",
8329 * We don't do extensive checking here, so this
8330 * will continue to work when new speeds come out.
8332 max_plr = strtoul(optarg, NULL, 0);
8334 || (max_plr > 0xf)) {
8335 warnx("%s: invalid link rate %x",
8342 camcontrol_optret optreturn;
8343 cam_argmask argnums;
8346 if (phy_op_set != 0) {
8347 warnx("%s: only one phy operation argument "
8348 "(-o) allowed", __func__);
8356 * Allow the user to specify the phy operation
8357 * numerically, as well as with a name. This will
8358 * future-proof it a bit, so options that are added
8359 * in future specs can be used.
8361 if (isdigit(optarg[0])) {
8362 phy_operation = strtoul(optarg, NULL, 0);
8363 if ((phy_operation == 0)
8364 || (phy_operation > 0xff)) {
8365 warnx("%s: invalid phy operation %#x",
8366 __func__, phy_operation);
8372 optreturn = getoption(phy_ops, optarg, &phy_operation,
8375 if (optreturn == CC_OR_AMBIGUOUS) {
8376 warnx("%s: ambiguous option %s", __func__,
8381 } else if (optreturn == CC_OR_NOT_FOUND) {
8382 warnx("%s: option %s not found", __func__,
8394 pp_timeout_val = strtoul(optarg, NULL, 0);
8395 if (pp_timeout_val > 15) {
8396 warnx("%s: invalid partial pathway timeout "
8397 "value %u, need a value less than 16",
8398 __func__, pp_timeout_val);
8402 set_pp_timeout_val = 1;
8410 warnx("%s: a PHY (-p phy) argument is required",__func__);
8415 if (((dev_name_set != 0)
8416 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8417 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8418 && (dev_name_set == 0))) {
8419 warnx("%s: -d name and -o setdevname arguments both "
8420 "required to set device name", __func__);
8425 request = malloc(sizeof(*request));
8426 if (request == NULL) {
8427 warn("%s: unable to allocate %zd bytes", __func__,
8433 response = malloc(sizeof(*response));
8434 if (response == NULL) {
8435 warn("%s: unable to allocate %zd bytes", __func__,
8441 smp_phy_control(&ccb->smpio,
8446 (uint8_t *)response,
8449 /*expected_exp_change_count*/ 0,
8452 (set_pp_timeout_val != 0) ? 1 : 0,
8460 if (((retval = cam_send_ccb(device, ccb)) < 0)
8461 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8462 const char warnstr[] = "error sending command";
8469 if (arglist & CAM_ARG_VERBOSE) {
8471 * Use CAM_EPF_NORMAL so we only get one line of
8472 * SMP command decoding.
8474 cam_error_print(device, ccb, CAM_ESF_ALL,
8475 CAM_EPF_NORMAL, stderr);
8481 /* XXX KDM print out something here for success? */
8486 if (request != NULL)
8489 if (response != NULL)
8496 smpmaninfo(struct cam_device *device, int argc, char **argv,
8497 char *combinedopt, int retry_count, int timeout)
8500 struct smp_report_manuf_info_request request;
8501 struct smp_report_manuf_info_response response;
8502 struct sbuf *sb = NULL;
8503 int long_response = 0;
8508 * Note that at the moment we don't support sending SMP CCBs to
8509 * devices that aren't probed by CAM.
8511 ccb = cam_getccb(device);
8513 warnx("%s: error allocating CCB", __func__);
8517 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8519 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8528 bzero(&request, sizeof(request));
8529 bzero(&response, sizeof(response));
8531 smp_report_manuf_info(&ccb->smpio,
8536 (uint8_t *)&response,
8541 if (((retval = cam_send_ccb(device, ccb)) < 0)
8542 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8543 const char warnstr[] = "error sending command";
8550 if (arglist & CAM_ARG_VERBOSE) {
8551 cam_error_print(device, ccb, CAM_ESF_ALL,
8552 CAM_EPF_ALL, stderr);
8558 sb = sbuf_new_auto();
8560 warnx("%s: error allocating sbuf", __func__);
8564 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8566 if (sbuf_finish(sb) != 0) {
8567 warnx("%s: sbuf_finish", __func__);
8571 printf("%s", sbuf_data(sb));
8585 getdevid(struct cam_devitem *item)
8588 union ccb *ccb = NULL;
8590 struct cam_device *dev;
8592 dev = cam_open_btl(item->dev_match.path_id,
8593 item->dev_match.target_id,
8594 item->dev_match.target_lun, O_RDWR, NULL);
8597 warnx("%s", cam_errbuf);
8602 item->device_id_len = 0;
8604 ccb = cam_getccb(dev);
8606 warnx("%s: error allocating CCB", __func__);
8611 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8614 * On the first try, we just probe for the size of the data, and
8615 * then allocate that much memory and try again.
8618 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8619 ccb->ccb_h.flags = CAM_DIR_IN;
8620 ccb->cdai.flags = CDAI_FLAG_NONE;
8621 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8622 ccb->cdai.bufsiz = item->device_id_len;
8623 if (item->device_id_len != 0)
8624 ccb->cdai.buf = (uint8_t *)item->device_id;
8626 if (cam_send_ccb(dev, ccb) < 0) {
8627 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8632 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8633 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8638 if (item->device_id_len == 0) {
8640 * This is our first time through. Allocate the buffer,
8641 * and then go back to get the data.
8643 if (ccb->cdai.provsiz == 0) {
8644 warnx("%s: invalid .provsiz field returned with "
8645 "XPT_GDEV_ADVINFO CCB", __func__);
8649 item->device_id_len = ccb->cdai.provsiz;
8650 item->device_id = malloc(item->device_id_len);
8651 if (item->device_id == NULL) {
8652 warn("%s: unable to allocate %d bytes", __func__,
8653 item->device_id_len);
8657 ccb->ccb_h.status = CAM_REQ_INPROG;
8663 cam_close_device(dev);
8672 * XXX KDM merge this code with getdevtree()?
8675 buildbusdevlist(struct cam_devlist *devlist)
8678 int bufsize, fd = -1;
8679 struct dev_match_pattern *patterns;
8680 struct cam_devitem *item = NULL;
8681 int skip_device = 0;
8684 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8685 warn("couldn't open %s", XPT_DEVICE);
8689 bzero(&ccb, sizeof(union ccb));
8691 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8692 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8693 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8695 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8696 bufsize = sizeof(struct dev_match_result) * 100;
8697 ccb.cdm.match_buf_len = bufsize;
8698 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8699 if (ccb.cdm.matches == NULL) {
8700 warnx("can't malloc memory for matches");
8704 ccb.cdm.num_matches = 0;
8705 ccb.cdm.num_patterns = 2;
8706 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8707 ccb.cdm.num_patterns;
8709 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8710 if (patterns == NULL) {
8711 warnx("can't malloc memory for patterns");
8716 ccb.cdm.patterns = patterns;
8717 bzero(patterns, ccb.cdm.pattern_buf_len);
8719 patterns[0].type = DEV_MATCH_DEVICE;
8720 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8721 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8722 patterns[1].type = DEV_MATCH_PERIPH;
8723 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8724 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8727 * We do the ioctl multiple times if necessary, in case there are
8728 * more than 100 nodes in the EDT.
8733 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8734 warn("error sending CAMIOCOMMAND ioctl");
8739 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8740 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8741 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8742 warnx("got CAM error %#x, CDM error %d\n",
8743 ccb.ccb_h.status, ccb.cdm.status);
8748 for (i = 0; i < ccb.cdm.num_matches; i++) {
8749 switch (ccb.cdm.matches[i].type) {
8750 case DEV_MATCH_DEVICE: {
8751 struct device_match_result *dev_result;
8754 &ccb.cdm.matches[i].result.device_result;
8756 if (dev_result->flags &
8757 DEV_RESULT_UNCONFIGURED) {
8763 item = malloc(sizeof(*item));
8765 warn("%s: unable to allocate %zd bytes",
8766 __func__, sizeof(*item));
8770 bzero(item, sizeof(*item));
8771 bcopy(dev_result, &item->dev_match,
8772 sizeof(*dev_result));
8773 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8776 if (getdevid(item) != 0) {
8782 case DEV_MATCH_PERIPH: {
8783 struct periph_match_result *periph_result;
8786 &ccb.cdm.matches[i].result.periph_result;
8788 if (skip_device != 0)
8790 item->num_periphs++;
8791 item->periph_matches = realloc(
8792 item->periph_matches,
8794 sizeof(struct periph_match_result));
8795 if (item->periph_matches == NULL) {
8796 warn("%s: error allocating periph "
8801 bcopy(periph_result, &item->periph_matches[
8802 item->num_periphs - 1],
8803 sizeof(*periph_result));
8807 fprintf(stderr, "%s: unexpected match "
8808 "type %d\n", __func__,
8809 ccb.cdm.matches[i].type);
8812 break; /*NOTREACHED*/
8815 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8816 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8824 free(ccb.cdm.matches);
8827 freebusdevlist(devlist);
8833 freebusdevlist(struct cam_devlist *devlist)
8835 struct cam_devitem *item, *item2;
8837 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8838 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8840 free(item->device_id);
8841 free(item->periph_matches);
8846 static struct cam_devitem *
8847 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8849 struct cam_devitem *item;
8851 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8852 struct scsi_vpd_id_descriptor *idd;
8855 * XXX KDM look for LUN IDs as well?
8857 idd = scsi_get_devid(item->device_id,
8858 item->device_id_len,
8859 scsi_devid_is_sas_target);
8863 if (scsi_8btou64(idd->identifier) == sasaddr)
8871 smpphylist(struct cam_device *device, int argc, char **argv,
8872 char *combinedopt, int retry_count, int timeout)
8874 struct smp_report_general_request *rgrequest = NULL;
8875 struct smp_report_general_response *rgresponse = NULL;
8876 struct smp_discover_request *disrequest = NULL;
8877 struct smp_discover_response *disresponse = NULL;
8878 struct cam_devlist devlist;
8880 int long_response = 0;
8887 * Note that at the moment we don't support sending SMP CCBs to
8888 * devices that aren't probed by CAM.
8890 ccb = cam_getccb(device);
8892 warnx("%s: error allocating CCB", __func__);
8896 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8897 STAILQ_INIT(&devlist.dev_queue);
8899 rgrequest = malloc(sizeof(*rgrequest));
8900 if (rgrequest == NULL) {
8901 warn("%s: unable to allocate %zd bytes", __func__,
8902 sizeof(*rgrequest));
8907 rgresponse = malloc(sizeof(*rgresponse));
8908 if (rgresponse == NULL) {
8909 warn("%s: unable to allocate %zd bytes", __func__,
8910 sizeof(*rgresponse));
8915 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8928 smp_report_general(&ccb->smpio,
8932 /*request_len*/ sizeof(*rgrequest),
8933 (uint8_t *)rgresponse,
8934 /*response_len*/ sizeof(*rgresponse),
8935 /*long_response*/ long_response,
8938 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8940 if (((retval = cam_send_ccb(device, ccb)) < 0)
8941 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8942 const char warnstr[] = "error sending command";
8949 if (arglist & CAM_ARG_VERBOSE) {
8950 cam_error_print(device, ccb, CAM_ESF_ALL,
8951 CAM_EPF_ALL, stderr);
8957 num_phys = rgresponse->num_phys;
8959 if (num_phys == 0) {
8961 fprintf(stdout, "%s: No Phys reported\n", __func__);
8966 devlist.path_id = device->path_id;
8968 retval = buildbusdevlist(&devlist);
8973 fprintf(stdout, "%d PHYs:\n", num_phys);
8974 fprintf(stdout, "PHY Attached SAS Address\n");
8977 disrequest = malloc(sizeof(*disrequest));
8978 if (disrequest == NULL) {
8979 warn("%s: unable to allocate %zd bytes", __func__,
8980 sizeof(*disrequest));
8985 disresponse = malloc(sizeof(*disresponse));
8986 if (disresponse == NULL) {
8987 warn("%s: unable to allocate %zd bytes", __func__,
8988 sizeof(*disresponse));
8993 for (i = 0; i < num_phys; i++) {
8994 struct cam_devitem *item;
8995 struct device_match_result *dev_match;
8996 char vendor[16], product[48], revision[16];
9000 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
9002 ccb->ccb_h.status = CAM_REQ_INPROG;
9003 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9005 smp_discover(&ccb->smpio,
9009 sizeof(*disrequest),
9010 (uint8_t *)disresponse,
9011 sizeof(*disresponse),
9013 /*ignore_zone_group*/ 0,
9017 if (((retval = cam_send_ccb(device, ccb)) < 0)
9018 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
9019 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
9020 const char warnstr[] = "error sending command";
9027 if (arglist & CAM_ARG_VERBOSE) {
9028 cam_error_print(device, ccb, CAM_ESF_ALL,
9029 CAM_EPF_ALL, stderr);
9035 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
9037 fprintf(stdout, "%3d <vacant>\n", i);
9041 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
9044 item = findsasdevice(&devlist,
9045 scsi_8btou64(disresponse->attached_sas_address));
9049 || (item != NULL)) {
9050 fprintf(stdout, "%3d 0x%016jx", i,
9051 (uintmax_t)scsi_8btou64(
9052 disresponse->attached_sas_address));
9054 fprintf(stdout, "\n");
9057 } else if (quiet != 0)
9060 dev_match = &item->dev_match;
9062 if (dev_match->protocol == PROTO_SCSI) {
9063 cam_strvis(vendor, dev_match->inq_data.vendor,
9064 sizeof(dev_match->inq_data.vendor),
9066 cam_strvis(product, dev_match->inq_data.product,
9067 sizeof(dev_match->inq_data.product),
9069 cam_strvis(revision, dev_match->inq_data.revision,
9070 sizeof(dev_match->inq_data.revision),
9072 sprintf(tmpstr, "<%s %s %s>", vendor, product,
9074 } else if ((dev_match->protocol == PROTO_ATA)
9075 || (dev_match->protocol == PROTO_SATAPM)) {
9076 cam_strvis(product, dev_match->ident_data.model,
9077 sizeof(dev_match->ident_data.model),
9079 cam_strvis(revision, dev_match->ident_data.revision,
9080 sizeof(dev_match->ident_data.revision),
9082 sprintf(tmpstr, "<%s %s>", product, revision);
9084 sprintf(tmpstr, "<>");
9086 fprintf(stdout, " %-33s ", tmpstr);
9089 * If we have 0 periphs, that's a bug...
9091 if (item->num_periphs == 0) {
9092 fprintf(stdout, "\n");
9096 fprintf(stdout, "(");
9097 for (j = 0; j < item->num_periphs; j++) {
9099 fprintf(stdout, ",");
9101 fprintf(stdout, "%s%d",
9102 item->periph_matches[j].periph_name,
9103 item->periph_matches[j].unit_number);
9106 fprintf(stdout, ")\n");
9120 freebusdevlist(&devlist);
9126 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
9128 uint8_t error = 0, ata_device = 0, status = 0;
9133 retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
9136 if (arglist & CAM_ARG_VERBOSE) {
9137 cam_error_print(device, ccb, CAM_ESF_ALL,
9138 CAM_EPF_ALL, stderr);
9140 warnx("Can't get ATA command status");
9144 if (status & ATA_STATUS_ERROR) {
9145 cam_error_print(device, ccb, CAM_ESF_ALL,
9146 CAM_EPF_ALL, stderr);
9150 printf("%s%d: ", device->device_name, device->dev_unit_num);
9153 printf("Standby mode\n");
9156 printf("Standby_y mode\n");
9159 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
9162 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
9165 printf("Idle mode\n");
9168 printf("Idle_a mode\n");
9171 printf("Idle_b mode\n");
9174 printf("Idle_c mode\n");
9177 printf("Active or Idle mode\n");
9180 printf("Unknown mode 0x%02x\n", count);
9188 atapm(struct cam_device *device, int argc, char **argv,
9189 char *combinedopt, int retry_count, int timeout)
9195 u_int8_t ata_flags = 0;
9198 ccb = cam_getccb(device);
9201 warnx("%s: error allocating ccb", __func__);
9205 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9214 if (strcmp(argv[1], "idle") == 0) {
9216 cmd = ATA_IDLE_IMMEDIATE;
9219 } else if (strcmp(argv[1], "standby") == 0) {
9221 cmd = ATA_STANDBY_IMMEDIATE;
9223 cmd = ATA_STANDBY_CMD;
9224 } else if (strcmp(argv[1], "powermode") == 0) {
9225 cmd = ATA_CHECK_POWER_MODE;
9226 ata_flags = AP_FLAG_CHK_COND;
9235 else if (t <= (240 * 5))
9237 else if (t <= (252 * 5))
9238 /* special encoding for 21 minutes */
9240 else if (t <= (11 * 30 * 60))
9241 sc = (t - 1) / (30 * 60) + 241;
9245 retval = ata_do_cmd(device,
9247 /*retries*/retry_count,
9248 /*flags*/CAM_DIR_NONE,
9249 /*protocol*/AP_PROTO_NON_DATA,
9250 /*ata_flags*/ata_flags,
9251 /*tag_action*/MSG_SIMPLE_Q_TAG,
9258 /*timeout*/timeout ? timeout : 30 * 1000,
9263 if (retval || cmd != ATA_CHECK_POWER_MODE)
9266 return (atapm_proc_resp(device, ccb));
9270 ataaxm(struct cam_device *device, int argc, char **argv,
9271 char *combinedopt, int retry_count, int timeout)
9279 ccb = cam_getccb(device);
9282 warnx("%s: error allocating ccb", __func__);
9286 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9296 if (strcmp(argv[1], "apm") == 0) {
9312 retval = ata_do_cmd(device,
9314 /*retries*/retry_count,
9315 /*flags*/CAM_DIR_NONE,
9316 /*protocol*/AP_PROTO_NON_DATA,
9318 /*tag_action*/MSG_SIMPLE_Q_TAG,
9319 /*command*/ATA_SETFEATURES,
9325 /*timeout*/timeout ? timeout : 30 * 1000,
9333 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9334 int show_sa_errors, int sa_set, int service_action,
9335 int timeout_desc, int task_attr, int retry_count, int timeout,
9336 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9338 union ccb *ccb = NULL;
9339 uint8_t *buf = NULL;
9340 uint32_t alloc_len = 0, num_opcodes;
9341 uint32_t valid_len = 0;
9342 uint32_t avail_len = 0;
9343 struct scsi_report_supported_opcodes_all *all_hdr;
9344 struct scsi_report_supported_opcodes_one *one;
9349 * Make it clear that we haven't yet allocated or filled anything.
9354 ccb = cam_getccb(device);
9356 warnx("couldn't allocate CCB");
9361 /* cam_getccb cleans up the header, caller has to zero the payload */
9362 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9364 if (opcode_set != 0) {
9365 options |= RSO_OPTIONS_OC;
9367 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9370 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9371 sizeof(struct scsi_report_supported_opcodes_descr));
9374 if (timeout_desc != 0) {
9375 options |= RSO_RCTD;
9376 alloc_len += num_opcodes *
9377 sizeof(struct scsi_report_supported_opcodes_timeout);
9381 options |= RSO_OPTIONS_OC_SA;
9382 if (show_sa_errors != 0)
9383 options &= ~RSO_OPTIONS_OC;
9392 buf = malloc(alloc_len);
9394 warn("Unable to allocate %u bytes", alloc_len);
9398 bzero(buf, alloc_len);
9400 scsi_report_supported_opcodes(&ccb->csio,
9401 /*retries*/ retry_count,
9403 /*tag_action*/ task_attr,
9404 /*options*/ options,
9405 /*req_opcode*/ opcode,
9406 /*req_service_action*/ service_action,
9408 /*dxfer_len*/ alloc_len,
9409 /*sense_len*/ SSD_FULL_SIZE,
9410 /*timeout*/ timeout ? timeout : 10000);
9412 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9414 if (retry_count != 0)
9415 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9417 if (cam_send_ccb(device, ccb) < 0) {
9418 warn("error sending REPORT SUPPORTED OPERATION CODES command");
9423 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9424 if (verbosemode != 0)
9425 cam_error_print(device, ccb, CAM_ESF_ALL,
9426 CAM_EPF_ALL, stderr);
9431 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9433 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9434 && (valid_len >= sizeof(*all_hdr))) {
9435 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9436 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9437 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9438 && (valid_len >= sizeof(*one))) {
9439 uint32_t cdb_length;
9441 one = (struct scsi_report_supported_opcodes_one *)buf;
9442 cdb_length = scsi_2btoul(one->cdb_length);
9443 avail_len = sizeof(*one) + cdb_length;
9444 if (one->support & RSO_ONE_CTDP) {
9445 struct scsi_report_supported_opcodes_timeout *td;
9447 td = (struct scsi_report_supported_opcodes_timeout *)
9449 if (valid_len >= (avail_len + sizeof(td->length))) {
9450 avail_len += scsi_2btoul(td->length) +
9453 avail_len += sizeof(*td);
9459 * avail_len could be zero if we didn't get enough data back from
9460 * thet target to determine
9462 if ((avail_len != 0)
9463 && (avail_len > valid_len)) {
9464 alloc_len = avail_len;
9468 *fill_len = valid_len;
9480 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9481 int req_sa, uint8_t *buf, uint32_t valid_len)
9483 struct scsi_report_supported_opcodes_one *one;
9484 struct scsi_report_supported_opcodes_timeout *td;
9485 uint32_t cdb_len = 0, td_len = 0;
9486 const char *op_desc = NULL;
9490 one = (struct scsi_report_supported_opcodes_one *)buf;
9493 * If we don't have the full single opcode descriptor, no point in
9496 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9498 warnx("Only %u bytes returned, not enough to verify support",
9504 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9506 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9509 printf(", SA 0x%x", req_sa);
9512 switch (one->support & RSO_ONE_SUP_MASK) {
9513 case RSO_ONE_SUP_UNAVAIL:
9514 printf("No command support information currently available\n");
9516 case RSO_ONE_SUP_NOT_SUP:
9517 printf("Command not supported\n");
9520 break; /*NOTREACHED*/
9521 case RSO_ONE_SUP_AVAIL:
9522 printf("Command is supported, complies with a SCSI standard\n");
9524 case RSO_ONE_SUP_VENDOR:
9525 printf("Command is supported, vendor-specific "
9526 "implementation\n");
9529 printf("Unknown command support flags 0x%#x\n",
9530 one->support & RSO_ONE_SUP_MASK);
9535 * If we don't have the CDB length, it isn't exactly an error, the
9536 * command probably isn't supported.
9538 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9542 cdb_len = scsi_2btoul(one->cdb_length);
9545 * If our valid data doesn't include the full reported length,
9546 * return. The caller should have detected this and adjusted his
9547 * allocation length to get all of the available data.
9549 if (valid_len < sizeof(*one) + cdb_len) {
9555 * If all we have is the opcode, there is no point in printing out
9563 printf("CDB usage bitmap:");
9564 for (i = 0; i < cdb_len; i++) {
9565 printf(" %02x", one->cdb_usage[i]);
9570 * If we don't have a timeout descriptor, we're done.
9572 if ((one->support & RSO_ONE_CTDP) == 0)
9576 * If we don't have enough valid length to include the timeout
9577 * descriptor length, we're done.
9579 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9582 td = (struct scsi_report_supported_opcodes_timeout *)
9583 &buf[sizeof(*one) + cdb_len];
9584 td_len = scsi_2btoul(td->length);
9585 td_len += sizeof(td->length);
9588 * If we don't have the full timeout descriptor, we're done.
9590 if (td_len < sizeof(*td))
9594 * If we don't have enough valid length to contain the full timeout
9595 * descriptor, we're done.
9597 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9600 printf("Timeout information:\n");
9601 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9602 printf("Nominal timeout: %u seconds\n",
9603 scsi_4btoul(td->nominal_time));
9604 printf("Recommended timeout: %u seconds\n",
9605 scsi_4btoul(td->recommended_time));
9612 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9615 struct scsi_report_supported_opcodes_all *hdr;
9616 struct scsi_report_supported_opcodes_descr *desc;
9617 uint32_t avail_len = 0, used_len = 0;
9621 if (valid_len < sizeof(*hdr)) {
9622 warnx("%s: not enough returned data (%u bytes) opcode list",
9623 __func__, valid_len);
9627 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9628 avail_len = scsi_4btoul(hdr->length);
9629 avail_len += sizeof(hdr->length);
9631 * Take the lesser of the amount of data the drive claims is
9632 * available, and the amount of data the HBA says was returned.
9634 avail_len = MIN(avail_len, valid_len);
9636 used_len = sizeof(hdr->length);
9638 printf("%-6s %4s %8s ",
9639 "Opcode", "SA", "CDB len" );
9642 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9643 printf(" Description\n");
9645 while ((avail_len - used_len) > sizeof(*desc)) {
9646 struct scsi_report_supported_opcodes_timeout *td;
9648 const char *op_desc = NULL;
9650 cur_ptr = &buf[used_len];
9651 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9653 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9654 if (op_desc == NULL)
9655 op_desc = "UNKNOWN";
9657 printf("0x%02x %#4x %8u ", desc->opcode,
9658 scsi_2btoul(desc->service_action),
9659 scsi_2btoul(desc->cdb_length));
9661 used_len += sizeof(*desc);
9663 if ((desc->flags & RSO_CTDP) == 0) {
9664 printf(" %s\n", op_desc);
9669 * If we don't have enough space to fit a timeout
9670 * descriptor, then we're done.
9672 if (avail_len - used_len < sizeof(*td)) {
9673 used_len = avail_len;
9674 printf(" %s\n", op_desc);
9677 cur_ptr = &buf[used_len];
9678 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9679 td_len = scsi_2btoul(td->length);
9680 td_len += sizeof(td->length);
9684 * If the given timeout descriptor length is less than what
9685 * we understand, skip it.
9687 if (td_len < sizeof(*td)) {
9688 printf(" %s\n", op_desc);
9692 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9693 scsi_4btoul(td->nominal_time),
9694 scsi_4btoul(td->recommended_time), op_desc);
9701 scsiopcodes(struct cam_device *device, int argc, char **argv,
9702 char *combinedopt, int task_attr, int retry_count, int timeout,
9706 uint32_t opcode = 0, service_action = 0;
9707 int td_set = 0, opcode_set = 0, sa_set = 0;
9708 int show_sa_errors = 1;
9709 uint32_t valid_len = 0;
9710 uint8_t *buf = NULL;
9714 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9720 opcode = strtoul(optarg, &endptr, 0);
9721 if (*endptr != '\0') {
9722 warnx("Invalid opcode \"%s\", must be a number",
9727 if (opcode > 0xff) {
9728 warnx("Invalid opcode 0x%#x, must be between"
9729 "0 and 0xff inclusive", opcode);
9736 service_action = strtoul(optarg, &endptr, 0);
9737 if (*endptr != '\0') {
9738 warnx("Invalid service action \"%s\", must "
9739 "be a number", optarg);
9743 if (service_action > 0xffff) {
9744 warnx("Invalid service action 0x%#x, must "
9745 "be between 0 and 0xffff inclusive",
9760 && (opcode_set == 0)) {
9761 warnx("You must specify an opcode with -o if a service "
9766 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9767 sa_set, service_action, td_set, task_attr,
9768 retry_count, timeout, verbosemode, &valid_len,
9773 if ((opcode_set != 0)
9775 retval = scsiprintoneopcode(device, opcode, sa_set,
9776 service_action, buf, valid_len);
9778 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9789 reprobe(struct cam_device *device)
9794 ccb = cam_getccb(device);
9797 warnx("%s: error allocating ccb", __func__);
9801 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
9803 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9805 if (cam_send_ccb(device, ccb) < 0) {
9806 warn("error sending XPT_REPROBE_LUN CCB");
9811 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9812 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9824 usage(int printlong)
9827 fprintf(printlong ? stdout : stderr,
9828 "usage: camcontrol <command> [device id][generic args][command args]\n"
9829 " camcontrol devlist [-b] [-v]\n"
9830 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9831 " camcontrol tur [dev_id][generic args]\n"
9832 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9833 " camcontrol identify [dev_id][generic args] [-v]\n"
9834 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9835 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9837 " camcontrol start [dev_id][generic args]\n"
9838 " camcontrol stop [dev_id][generic args]\n"
9839 " camcontrol load [dev_id][generic args]\n"
9840 " camcontrol eject [dev_id][generic args]\n"
9841 " camcontrol reprobe [dev_id][generic args]\n"
9842 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9843 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9844 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9845 " [-q][-s][-S offset][-X]\n"
9846 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9847 " [-P pagectl][-e | -b][-d]\n"
9848 " camcontrol cmd [dev_id][generic args]\n"
9849 " <-a cmd [args] | -c cmd [args]>\n"
9850 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9851 " camcontrol smpcmd [dev_id][generic args]\n"
9852 " <-r len fmt [args]> <-R len fmt [args]>\n"
9853 " camcontrol smprg [dev_id][generic args][-l]\n"
9854 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9855 " [-o operation][-d name][-m rate][-M rate]\n"
9856 " [-T pp_timeout][-a enable|disable]\n"
9857 " [-A enable|disable][-s enable|disable]\n"
9858 " [-S enable|disable]\n"
9859 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9860 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9861 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9862 " <all|dev_id|bus[:target[:lun]]|off>\n"
9863 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9864 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9865 " [-D <enable|disable>][-M mode][-O offset]\n"
9866 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9867 " [-U][-W bus_width]\n"
9868 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9869 " camcontrol sanitize [dev_id][generic args]\n"
9870 " [-a overwrite|block|crypto|exitfailure]\n"
9871 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9873 " camcontrol idle [dev_id][generic args][-t time]\n"
9874 " camcontrol standby [dev_id][generic args][-t time]\n"
9875 " camcontrol sleep [dev_id][generic args]\n"
9876 " camcontrol powermode [dev_id][generic args]\n"
9877 " camcontrol apm [dev_id][generic args][-l level]\n"
9878 " camcontrol aam [dev_id][generic args][-l level]\n"
9879 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9881 " camcontrol security [dev_id][generic args]\n"
9882 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9883 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9884 " [-U <user|master>] [-y]\n"
9885 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9886 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9887 " camcontrol ama [dev_id][generic args] [-f] [-q] [-s max_sectors]\n"
9888 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9889 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9890 " [-s scope][-S][-T type][-U]\n"
9891 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9892 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9893 " [-p part][-s start][-T type][-V vol]\n"
9894 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9896 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9897 " [-o rep_opts] [-P print_opts]\n"
9898 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9899 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9900 " [-S power_src] [-T timer]\n"
9901 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9902 " <-s <-f format -T time | -U >>\n"
9903 " camcontrol devtype [dev_id]\n"
9905 " camcontrol help\n");
9909 "Specify one of the following options:\n"
9910 "devlist list all CAM devices\n"
9911 "periphlist list all CAM peripheral drivers attached to a device\n"
9912 "tur send a test unit ready to the named device\n"
9913 "inquiry send a SCSI inquiry command to the named device\n"
9914 "identify send a ATA identify command to the named device\n"
9915 "reportluns send a SCSI report luns command to the device\n"
9916 "readcap send a SCSI read capacity command to the device\n"
9917 "start send a Start Unit command to the device\n"
9918 "stop send a Stop Unit command to the device\n"
9919 "load send a Start Unit command to the device with the load bit set\n"
9920 "eject send a Stop Unit command to the device with the eject bit set\n"
9921 "reprobe update capacity information of the given device\n"
9922 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9923 "reset reset all buses, the given bus, bus:target:lun or device\n"
9924 "defects read the defect list of the specified device\n"
9925 "modepage display or edit (-e) the given mode page\n"
9926 "cmd send the given SCSI command, may need -i or -o as well\n"
9927 "smpcmd send the given SMP command, requires -o and -i\n"
9928 "smprg send the SMP Report General command\n"
9929 "smppc send the SMP PHY Control command, requires -p\n"
9930 "smpphylist display phys attached to a SAS expander\n"
9931 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9932 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9933 "tags report or set the number of transaction slots for a device\n"
9934 "negotiate report or set device negotiation parameters\n"
9935 "format send the SCSI FORMAT UNIT command to the named device\n"
9936 "sanitize send the SCSI SANITIZE command to the named device\n"
9937 "idle send the ATA IDLE command to the named device\n"
9938 "standby send the ATA STANDBY command to the named device\n"
9939 "sleep send the ATA SLEEP command to the named device\n"
9940 "powermode send the ATA CHECK POWER MODE command to the named device\n"
9941 "fwdownload program firmware of the named device with the given image\n"
9942 "security report or send ATA security commands to the named device\n"
9943 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9944 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9945 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9946 "zone manage Zoned Block (Shingled) devices\n"
9947 "epc send ATA Extended Power Conditions commands\n"
9948 "timestamp report or set the device's timestamp\n"
9949 "devtype report the type of device\n"
9950 "help this message\n"
9951 "Device Identifiers:\n"
9952 "bus:target specify the bus and target, lun defaults to 0\n"
9953 "bus:target:lun specify the bus, target and lun\n"
9954 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
9955 "Generic arguments:\n"
9956 "-v be verbose, print out sense information\n"
9957 "-t timeout command timeout in seconds, overrides default timeout\n"
9958 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
9959 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
9960 "-E have the kernel attempt to perform SCSI error recovery\n"
9961 "-C count specify the SCSI command retry count (needs -E to work)\n"
9962 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
9963 "modepage arguments:\n"
9964 "-l list all available mode pages\n"
9965 "-m page specify the mode page to view or edit\n"
9966 "-e edit the specified mode page\n"
9967 "-b force view to binary mode\n"
9968 "-d disable block descriptors for mode sense\n"
9969 "-P pgctl page control field 0-3\n"
9970 "defects arguments:\n"
9971 "-f format specify defect list format (block, bfi or phys)\n"
9972 "-G get the grown defect list\n"
9973 "-P get the permanent defect list\n"
9974 "inquiry arguments:\n"
9975 "-D get the standard inquiry data\n"
9976 "-S get the serial number\n"
9977 "-R get the transfer rate, etc.\n"
9978 "reportluns arguments:\n"
9979 "-c only report a count of available LUNs\n"
9980 "-l only print out luns, and not a count\n"
9981 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
9982 "readcap arguments\n"
9983 "-b only report the blocksize\n"
9984 "-h human readable device size, base 2\n"
9985 "-H human readable device size, base 10\n"
9986 "-N print the number of blocks instead of last block\n"
9987 "-q quiet, print numbers only\n"
9988 "-s only report the last block/device size\n"
9990 "-c cdb [args] specify the SCSI CDB\n"
9991 "-i len fmt specify input data and input data format\n"
9992 "-o len fmt [args] specify output data and output data fmt\n"
9993 "smpcmd arguments:\n"
9994 "-r len fmt [args] specify the SMP command to be sent\n"
9995 "-R len fmt [args] specify SMP response format\n"
9996 "smprg arguments:\n"
9997 "-l specify the long response format\n"
9998 "smppc arguments:\n"
9999 "-p phy specify the PHY to operate on\n"
10000 "-l specify the long request/response format\n"
10001 "-o operation specify the phy control operation\n"
10002 "-d name set the attached device name\n"
10003 "-m rate set the minimum physical link rate\n"
10004 "-M rate set the maximum physical link rate\n"
10005 "-T pp_timeout set the partial pathway timeout value\n"
10006 "-a enable|disable enable or disable SATA slumber\n"
10007 "-A enable|disable enable or disable SATA partial phy power\n"
10008 "-s enable|disable enable or disable SAS slumber\n"
10009 "-S enable|disable enable or disable SAS partial phy power\n"
10010 "smpphylist arguments:\n"
10011 "-l specify the long response format\n"
10012 "-q only print phys with attached devices\n"
10013 "smpmaninfo arguments:\n"
10014 "-l specify the long response format\n"
10015 "debug arguments:\n"
10016 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
10017 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
10018 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
10019 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
10020 "tags arguments:\n"
10021 "-N tags specify the number of tags to use for this device\n"
10022 "-q be quiet, don't report the number of tags\n"
10023 "-v report a number of tag-related parameters\n"
10024 "negotiate arguments:\n"
10025 "-a send a test unit ready after negotiation\n"
10026 "-c report/set current negotiation settings\n"
10027 "-D <arg> \"enable\" or \"disable\" disconnection\n"
10028 "-M mode set ATA mode\n"
10029 "-O offset set command delay offset\n"
10030 "-q be quiet, don't report anything\n"
10031 "-R syncrate synchronization rate in MHz\n"
10032 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
10033 "-U report/set user negotiation settings\n"
10034 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
10035 "-v also print a Path Inquiry CCB for the controller\n"
10036 "format arguments:\n"
10037 "-q be quiet, don't print status messages\n"
10038 "-r run in report only mode\n"
10039 "-w don't send immediate format command\n"
10040 "-y don't ask any questions\n"
10041 "sanitize arguments:\n"
10042 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
10043 "-c passes overwrite passes to perform (1 to 31)\n"
10044 "-I invert overwrite pattern after each pass\n"
10045 "-P pattern path to overwrite pattern file\n"
10046 "-q be quiet, don't print status messages\n"
10047 "-r run in report only mode\n"
10048 "-U run operation in unrestricted completion exit mode\n"
10049 "-w don't send immediate sanitize command\n"
10050 "-y don't ask any questions\n"
10051 "idle/standby arguments:\n"
10052 "-t <arg> number of seconds before respective state.\n"
10053 "fwdownload arguments:\n"
10054 "-f fw_image path to firmware image file\n"
10055 "-q don't print informational messages, only errors\n"
10056 "-s run in simulation mode\n"
10057 "-v print info for every firmware segment sent to device\n"
10058 "-y don't ask any questions\n"
10059 "security arguments:\n"
10060 "-d pwd disable security using the given password for the selected\n"
10062 "-e pwd erase the device using the given pwd for the selected user\n"
10063 "-f freeze the security configuration of the specified device\n"
10064 "-h pwd enhanced erase the device using the given pwd for the\n"
10066 "-k pwd unlock the device using the given pwd for the selected\n"
10068 "-l <high|maximum> specifies which security level to set: high or maximum\n"
10069 "-q be quiet, do not print any status messages\n"
10070 "-s pwd password the device (enable security) using the given\n"
10071 " pwd for the selected user\n"
10072 "-T timeout overrides the timeout (seconds) used for erase operation\n"
10073 "-U <user|master> specifies which user to set: user or master\n"
10074 "-y don't ask any questions\n"
10076 "-f freeze the HPA configuration of the device\n"
10077 "-l lock the HPA configuration of the device\n"
10078 "-P make the HPA max sectors persist\n"
10079 "-p pwd Set the HPA configuration password required for unlock\n"
10081 "-q be quiet, do not print any status messages\n"
10082 "-s sectors configures the maximum user accessible sectors of the\n"
10084 "-U pwd unlock the HPA configuration of the device\n"
10085 "-y don't ask any questions\n"
10087 "-f freeze the AMA configuration of the device\n"
10088 "-q be quiet, do not print any status messages\n"
10089 "-s sectors configures the maximum user accessible sectors of the\n"
10091 "persist arguments:\n"
10092 "-i action specify read_keys, read_reservation, report_cap, or\n"
10093 " read_full_status\n"
10094 "-o action specify register, register_ignore, reserve, release,\n"
10095 " clear, preempt, preempt_abort, register_move, replace_lost\n"
10096 "-a set the All Target Ports (ALL_TG_PT) bit\n"
10097 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
10098 "-k key specify the Reservation Key\n"
10099 "-K sa_key specify the Service Action Reservation Key\n"
10100 "-p set the Activate Persist Through Power Loss bit\n"
10101 "-R rtp specify the Relative Target Port\n"
10102 "-s scope specify the scope: lun, extent, element or a number\n"
10103 "-S specify Transport ID for register, requires -I\n"
10104 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
10105 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
10106 "-U unregister the current initiator for register_move\n"
10107 "attrib arguments:\n"
10108 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
10110 "-w attr specify an attribute to write, one -w argument per attr\n"
10111 "-a attr_num only display this attribute number\n"
10112 "-c get cached attributes\n"
10113 "-e elem_addr request attributes for the given element in a changer\n"
10114 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
10115 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
10116 " field_none, field_desc, field_num, field_size, field_rw\n"
10117 "-p partition request attributes for the given partition\n"
10118 "-s start_attr request attributes starting at the given number\n"
10119 "-T elem_type specify the element type (used with -e)\n"
10120 "-V logical_vol specify the logical volume ID\n"
10121 "opcodes arguments:\n"
10122 "-o opcode specify the individual opcode to list\n"
10123 "-s service_action specify the service action for the opcode\n"
10124 "-N do not return SCSI error for unsupported SA\n"
10125 "-T request nominal and recommended timeout values\n"
10126 "zone arguments:\n"
10127 "-c cmd required: rz, open, close, finish, or rwp\n"
10128 "-a apply the action to all zones\n"
10129 "-l LBA specify the zone starting LBA\n"
10130 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
10131 " closed, full, ro, offline, reset, nonseq, nonwp\n"
10132 "-P print_opt report zones printing: normal, summary, script\n"
10134 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
10135 " source, status, list\n"
10136 "-d disable power mode (timer, state)\n"
10137 "-D delayed entry (goto)\n"
10138 "-e enable power mode (timer, state)\n"
10139 "-H hold power mode (goto)\n"
10140 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
10142 "-P only display power mode (status)\n"
10143 "-r rst_src restore settings from: default, saved (restore)\n"
10144 "-s save mode (timer, state, restore)\n"
10145 "-S power_src set power source: battery, nonbattery (source)\n"
10146 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
10147 "timestamp arguments:\n"
10148 "-r report the timestamp of the device\n"
10149 "-f format report the timestamp of the device with the given\n"
10150 " strftime(3) format string\n"
10151 "-m report the timestamp of the device as milliseconds since\n"
10152 " January 1st, 1970\n"
10153 "-U report the time with UTC instead of the local time zone\n"
10154 "-s set the timestamp of the device\n"
10155 "-f format the format of the time string passed into strptime(3)\n"
10156 "-T time the time value passed into strptime(3)\n"
10157 "-U set the timestamp of the device to UTC time\n"
10162 main(int argc, char **argv)
10165 char *device = NULL;
10167 struct cam_device *cam_dev = NULL;
10168 int timeout = 0, retry_count = 1;
10169 camcontrol_optret optreturn;
10171 const char *mainopt = "C:En:Q:t:u:v";
10172 const char *subopt = NULL;
10173 char combinedopt[256];
10174 int error = 0, optstart = 2;
10175 int task_attr = MSG_SIMPLE_Q_TAG;
10178 target_id_t target;
10181 cmdlist = CAM_CMD_NONE;
10182 arglist = CAM_ARG_NONE;
10190 * Get the base option.
10192 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
10194 if (optreturn == CC_OR_AMBIGUOUS) {
10195 warnx("ambiguous option %s", argv[1]);
10198 } else if (optreturn == CC_OR_NOT_FOUND) {
10199 warnx("option %s not found", argv[1]);
10205 * Ahh, getopt(3) is a pain.
10207 * This is a gross hack. There really aren't many other good
10208 * options (excuse the pun) for parsing options in a situation like
10209 * this. getopt is kinda braindead, so you end up having to run
10210 * through the options twice, and give each invocation of getopt
10211 * the option string for the other invocation.
10213 * You would think that you could just have two groups of options.
10214 * The first group would get parsed by the first invocation of
10215 * getopt, and the second group would get parsed by the second
10216 * invocation of getopt. It doesn't quite work out that way. When
10217 * the first invocation of getopt finishes, it leaves optind pointing
10218 * to the argument _after_ the first argument in the second group.
10219 * So when the second invocation of getopt comes around, it doesn't
10220 * recognize the first argument it gets and then bails out.
10222 * A nice alternative would be to have a flag for getopt that says
10223 * "just keep parsing arguments even when you encounter an unknown
10224 * argument", but there isn't one. So there's no real clean way to
10225 * easily parse two sets of arguments without having one invocation
10226 * of getopt know about the other.
10228 * Without this hack, the first invocation of getopt would work as
10229 * long as the generic arguments are first, but the second invocation
10230 * (in the subfunction) would fail in one of two ways. In the case
10231 * where you don't set optreset, it would fail because optind may be
10232 * pointing to the argument after the one it should be pointing at.
10233 * In the case where you do set optreset, and reset optind, it would
10234 * fail because getopt would run into the first set of options, which
10235 * it doesn't understand.
10237 * All of this would "sort of" work if you could somehow figure out
10238 * whether optind had been incremented one option too far. The
10239 * mechanics of that, however, are more daunting than just giving
10240 * both invocations all of the expect options for either invocation.
10242 * Needless to say, I wouldn't mind if someone invented a better
10243 * (non-GPL!) command line parsing interface than getopt. I
10244 * wouldn't mind if someone added more knobs to getopt to make it
10245 * work better. Who knows, I may talk myself into doing it someday,
10246 * if the standards weenies let me. As it is, it just leads to
10247 * hackery like this and causes people to avoid it in some cases.
10249 * KDM, September 8th, 1998
10251 if (subopt != NULL)
10252 sprintf(combinedopt, "%s%s", mainopt, subopt);
10254 sprintf(combinedopt, "%s", mainopt);
10257 * For these options we do not parse optional device arguments and
10258 * we do not open a passthrough device.
10260 if ((cmdlist == CAM_CMD_RESCAN)
10261 || (cmdlist == CAM_CMD_RESET)
10262 || (cmdlist == CAM_CMD_DEVTREE)
10263 || (cmdlist == CAM_CMD_USAGE)
10264 || (cmdlist == CAM_CMD_DEBUG))
10268 && (argc > 2 && argv[2][0] != '-')) {
10272 if (isdigit(argv[2][0])) {
10273 /* device specified as bus:target[:lun] */
10274 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10276 errx(1, "numeric device specification must "
10277 "be either bus:target, or "
10279 /* default to 0 if lun was not specified */
10280 if ((arglist & CAM_ARG_LUN) == 0) {
10282 arglist |= CAM_ARG_LUN;
10286 if (cam_get_device(argv[2], name, sizeof name, &unit)
10288 errx(1, "%s", cam_errbuf);
10289 device = strdup(name);
10290 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10295 * Start getopt processing at argv[2/3], since we've already
10296 * accepted argv[1..2] as the command name, and as a possible
10302 * Now we run through the argument list looking for generic
10303 * options, and ignoring options that possibly belong to
10306 while ((c = getopt(argc, argv, combinedopt))!= -1){
10309 retry_count = strtol(optarg, NULL, 0);
10310 if (retry_count < 0)
10311 errx(1, "retry count %d is < 0",
10313 arglist |= CAM_ARG_RETRIES;
10316 arglist |= CAM_ARG_ERR_RECOVER;
10319 arglist |= CAM_ARG_DEVICE;
10321 while (isspace(*tstr) && (*tstr != '\0'))
10323 device = (char *)strdup(tstr);
10327 int table_entry = 0;
10330 while (isspace(*tstr) && (*tstr != '\0'))
10332 if (isdigit(*tstr)) {
10333 task_attr = strtol(tstr, &endptr, 0);
10334 if (*endptr != '\0') {
10335 errx(1, "Invalid queue option "
10340 scsi_nv_status status;
10342 table_size = sizeof(task_attrs) /
10343 sizeof(task_attrs[0]);
10344 status = scsi_get_nv(task_attrs,
10345 table_size, tstr, &table_entry,
10346 SCSI_NV_FLAG_IG_CASE);
10347 if (status == SCSI_NV_FOUND)
10348 task_attr = task_attrs[
10349 table_entry].value;
10351 errx(1, "%s option %s",
10352 (status == SCSI_NV_AMBIGUOUS)?
10353 "ambiguous" : "invalid",
10360 timeout = strtol(optarg, NULL, 0);
10362 errx(1, "invalid timeout %d", timeout);
10363 /* Convert the timeout from seconds to ms */
10365 arglist |= CAM_ARG_TIMEOUT;
10368 arglist |= CAM_ARG_UNIT;
10369 unit = strtol(optarg, NULL, 0);
10372 arglist |= CAM_ARG_VERBOSE;
10380 * For most commands we'll want to open the passthrough device
10381 * associated with the specified device. In the case of the rescan
10382 * commands, we don't use a passthrough device at all, just the
10383 * transport layer device.
10385 if (devopen == 1) {
10386 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10387 && (((arglist & CAM_ARG_DEVICE) == 0)
10388 || ((arglist & CAM_ARG_UNIT) == 0))) {
10389 errx(1, "subcommand \"%s\" requires a valid device "
10390 "identifier", argv[1]);
10393 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10394 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10395 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10397 errx(1,"%s", cam_errbuf);
10401 * Reset optind to 2, and reset getopt, so these routines can parse
10402 * the arguments again.
10408 case CAM_CMD_DEVLIST:
10409 error = getdevlist(cam_dev);
10412 error = atahpa(cam_dev, retry_count, timeout,
10413 argc, argv, combinedopt);
10416 error = ataama(cam_dev, retry_count, timeout,
10417 argc, argv, combinedopt);
10419 case CAM_CMD_DEVTREE:
10420 error = getdevtree(argc, argv, combinedopt);
10422 case CAM_CMD_DEVTYPE:
10423 error = getdevtype(cam_dev);
10426 error = testunitready(cam_dev, task_attr, retry_count,
10429 case CAM_CMD_INQUIRY:
10430 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10431 task_attr, retry_count, timeout);
10433 case CAM_CMD_IDENTIFY:
10434 error = identify(cam_dev, retry_count, timeout);
10436 case CAM_CMD_STARTSTOP:
10437 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10438 arglist & CAM_ARG_EJECT, task_attr,
10439 retry_count, timeout);
10441 case CAM_CMD_RESCAN:
10442 error = dorescan_or_reset(argc, argv, 1);
10444 case CAM_CMD_RESET:
10445 error = dorescan_or_reset(argc, argv, 0);
10447 case CAM_CMD_READ_DEFECTS:
10448 error = readdefects(cam_dev, argc, argv, combinedopt,
10449 task_attr, retry_count, timeout);
10451 case CAM_CMD_MODE_PAGE:
10452 modepage(cam_dev, argc, argv, combinedopt,
10453 task_attr, retry_count, timeout);
10455 case CAM_CMD_SCSI_CMD:
10456 error = scsicmd(cam_dev, argc, argv, combinedopt,
10457 task_attr, retry_count, timeout);
10459 case CAM_CMD_MMCSD_CMD:
10460 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10461 retry_count, timeout);
10463 case CAM_CMD_SMP_CMD:
10464 error = smpcmd(cam_dev, argc, argv, combinedopt,
10465 retry_count, timeout);
10467 case CAM_CMD_SMP_RG:
10468 error = smpreportgeneral(cam_dev, argc, argv,
10469 combinedopt, retry_count,
10472 case CAM_CMD_SMP_PC:
10473 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10474 retry_count, timeout);
10476 case CAM_CMD_SMP_PHYLIST:
10477 error = smpphylist(cam_dev, argc, argv, combinedopt,
10478 retry_count, timeout);
10480 case CAM_CMD_SMP_MANINFO:
10481 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10482 retry_count, timeout);
10484 case CAM_CMD_DEBUG:
10485 error = camdebug(argc, argv, combinedopt);
10488 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10491 error = ratecontrol(cam_dev, task_attr, retry_count,
10492 timeout, argc, argv, combinedopt);
10494 case CAM_CMD_FORMAT:
10495 error = scsiformat(cam_dev, argc, argv,
10496 combinedopt, task_attr, retry_count,
10499 case CAM_CMD_REPORTLUNS:
10500 error = scsireportluns(cam_dev, argc, argv,
10501 combinedopt, task_attr,
10502 retry_count, timeout);
10504 case CAM_CMD_READCAP:
10505 error = scsireadcapacity(cam_dev, argc, argv,
10506 combinedopt, task_attr,
10507 retry_count, timeout);
10510 case CAM_CMD_STANDBY:
10511 case CAM_CMD_SLEEP:
10512 case CAM_CMD_POWER_MODE:
10513 error = atapm(cam_dev, argc, argv,
10514 combinedopt, retry_count, timeout);
10518 error = ataaxm(cam_dev, argc, argv,
10519 combinedopt, retry_count, timeout);
10521 case CAM_CMD_SECURITY:
10522 error = atasecurity(cam_dev, retry_count, timeout,
10523 argc, argv, combinedopt);
10525 case CAM_CMD_DOWNLOAD_FW:
10526 error = fwdownload(cam_dev, argc, argv, combinedopt,
10527 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10530 case CAM_CMD_SANITIZE:
10531 error = sanitize(cam_dev, argc, argv, combinedopt, task_attr,
10532 retry_count, timeout);
10534 case CAM_CMD_PERSIST:
10535 error = scsipersist(cam_dev, argc, argv, combinedopt,
10536 task_attr, retry_count, timeout,
10537 arglist & CAM_ARG_VERBOSE,
10538 arglist & CAM_ARG_ERR_RECOVER);
10540 case CAM_CMD_ATTRIB:
10541 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10542 task_attr, retry_count, timeout,
10543 arglist & CAM_ARG_VERBOSE,
10544 arglist & CAM_ARG_ERR_RECOVER);
10546 case CAM_CMD_OPCODES:
10547 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10548 task_attr, retry_count, timeout,
10549 arglist & CAM_ARG_VERBOSE);
10551 case CAM_CMD_REPROBE:
10552 error = reprobe(cam_dev);
10555 error = zone(cam_dev, argc, argv, combinedopt,
10556 task_attr, retry_count, timeout,
10557 arglist & CAM_ARG_VERBOSE);
10560 error = epc(cam_dev, argc, argv, combinedopt,
10561 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10563 case CAM_CMD_TIMESTAMP:
10564 error = timestamp(cam_dev, argc, argv, combinedopt,
10565 task_attr, retry_count, timeout,
10566 arglist & CAM_ARG_VERBOSE);
10568 case CAM_CMD_USAGE:
10577 if (cam_dev != NULL)
10578 cam_close_device(cam_dev);