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: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((uint16_t *)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 if (error & ATA_ERROR_ABORT) {
6671 switch (lba & 0xff) {
6673 warnx("Reason not reported or sanitize failed.");
6676 warnx("Sanitize command unsuccessful. ");
6679 warnx("Unsupported sanitize device command. ");
6682 warnx("Device is in sanitize frozen state. ");
6685 warnx("Sanitize antifreeze lock is enabled. ");
6689 warnx("SANITIZE STATUS EXT failed, "
6690 "sanitize may still run.");
6693 if (count & 0x4000) {
6698 "Sanitizing: %u.%02u%% (%d/%d)\r",
6699 (perc / (0x10000 * 100)),
6700 ((perc / 0x10000) % 100),
6712 sanitize_wait_scsi(struct cam_device *device, union ccb *ccb, int task_attr, int quiet)
6714 int warnings = 0, retval;
6719 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6722 * There's really no need to do error recovery or
6723 * retries here, since we're just going to sit in a
6724 * loop and wait for the device to finish sanitizing.
6726 scsi_test_unit_ready(&ccb->csio,
6729 /* tag_action */ task_attr,
6730 /* sense_len */ SSD_FULL_SIZE,
6731 /* timeout */ 5000);
6733 /* Disable freezing the device queue */
6734 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6736 retval = cam_send_ccb(device, ccb);
6739 * If we get an error from the ioctl, bail out. SCSI
6740 * errors are expected.
6743 warn("error sending TEST UNIT READY command");
6747 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6748 if ((status == CAM_SCSI_STATUS_ERROR) &&
6749 ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6750 struct scsi_sense_data *sense;
6751 int error_code, sense_key, asc, ascq;
6753 sense = &ccb->csio.sense_data;
6754 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6755 ccb->csio.sense_resid, &error_code, &sense_key,
6756 &asc, &ascq, /*show_errors*/ 1);
6759 * According to the SCSI-3 spec, a drive that is in the
6760 * middle of a sanitize should return NOT READY with an
6761 * ASC of "logical unit not ready, sanitize in
6762 * progress". The sense key specific bytes will then
6763 * be a progress indicator.
6765 if ((sense_key == SSD_KEY_NOT_READY)
6766 && (asc == 0x04) && (ascq == 0x1b)) {
6769 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6770 ccb->csio.sense_resid, sks) == 0)
6772 val = scsi_2btoul(&sks[1]);
6775 "Sanitizing: %u.%02u%% (%d/%d)\r",
6776 (perc / (0x10000 * 100)),
6777 ((perc / 0x10000) % 100),
6780 } else if ((quiet == 0) && (++warnings <= 1)) {
6781 warnx("Unexpected SCSI Sense Key "
6782 "Specific value returned "
6783 "during sanitize:");
6784 scsi_sense_print(device, &ccb->csio,
6786 warnx("Unable to print status "
6787 "information, but sanitze will "
6789 warnx("will exit when sanitize is "
6794 warnx("Unexpected SCSI error during sanitize");
6795 cam_error_print(device, ccb, CAM_ESF_ALL,
6796 CAM_EPF_ALL, stderr);
6800 } else if (status != CAM_REQ_CMP && status != CAM_REQUEUE_REQ) {
6801 warnx("Unexpected CAM status %#x", status);
6802 if (arglist & CAM_ARG_VERBOSE)
6803 cam_error_print(device, ccb, CAM_ESF_ALL,
6804 CAM_EPF_ALL, stderr);
6807 } while ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6812 sanitize(struct cam_device *device, int argc, char **argv,
6813 char *combinedopt, int task_attr, int retry_count, int timeout)
6816 u_int8_t action = 0;
6818 int ycount = 0, quiet = 0;
6826 const char *pattern = NULL;
6827 u_int8_t *data_ptr = NULL;
6828 u_int32_t dxfer_len = 0;
6830 uint16_t feature, count;
6833 camcontrol_devtype dt;
6836 * Get the device type, request no I/O be done to do this.
6838 error = get_device_type(device, -1, 0, 0, &dt);
6839 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
6840 warnx("sanitize: can't get device type");
6844 ccb = cam_getccb(device);
6847 warnx("sanitize: error allocating ccb");
6851 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6853 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6856 if (strcasecmp(optarg, "overwrite") == 0)
6857 action = SSZ_SERVICE_ACTION_OVERWRITE;
6858 else if (strcasecmp(optarg, "block") == 0)
6859 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6860 else if (strcasecmp(optarg, "crypto") == 0)
6861 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6862 else if (strcasecmp(optarg, "exitfailure") == 0)
6863 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6865 warnx("invalid service operation \"%s\"",
6868 goto sanitize_bailout;
6872 passes = strtol(optarg, NULL, 0);
6873 if (passes < 1 || passes > 31) {
6874 warnx("invalid passes value %d", passes);
6876 goto sanitize_bailout;
6895 /* ATA supports only immediate commands. */
6896 if (dt == CC_DT_SCSI)
6909 warnx("an action is required");
6911 goto sanitize_bailout;
6912 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6913 struct scsi_sanitize_parameter_list *pl;
6917 if (pattern == NULL) {
6918 warnx("overwrite action requires -P argument");
6920 goto sanitize_bailout;
6922 fd = open(pattern, O_RDONLY);
6924 warn("cannot open pattern file %s", pattern);
6926 goto sanitize_bailout;
6928 if (fstat(fd, &sb) < 0) {
6929 warn("cannot stat pattern file %s", pattern);
6931 goto sanitize_bailout;
6934 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6935 warnx("pattern file size exceeds maximum value %d",
6936 SSZPL_MAX_PATTERN_LENGTH);
6938 goto sanitize_bailout;
6940 dxfer_len = sizeof(*pl) + sz;
6941 data_ptr = calloc(1, dxfer_len);
6942 if (data_ptr == NULL) {
6943 warnx("cannot allocate parameter list buffer");
6945 goto sanitize_bailout;
6948 amt = read(fd, data_ptr + sizeof(*pl), sz);
6950 warn("cannot read pattern file");
6952 goto sanitize_bailout;
6953 } else if (amt != sz) {
6954 warnx("short pattern file read");
6956 goto sanitize_bailout;
6959 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6965 pl->byte1 |= SSZPL_INVERT;
6966 scsi_ulto2b(sz, pl->length);
6972 else if (invert != 0)
6974 else if (pattern != NULL)
6979 warnx("%s argument only valid with overwrite "
6982 goto sanitize_bailout;
6986 if (quiet == 0 && ycount == 0) {
6987 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6988 "following device:\n");
6990 if (dt == CC_DT_SCSI) {
6991 error = scsidoinquiry(device, argc, argv, combinedopt,
6992 task_attr, retry_count, timeout);
6993 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
6994 struct ata_params *ident_buf;
6995 error = ata_do_identify(device, retry_count, timeout,
6998 printf("%s%d: ", device->device_name,
6999 device->dev_unit_num);
7000 ata_print_ident(ident_buf);
7007 warnx("sanitize: error sending inquiry");
7008 goto sanitize_bailout;
7013 if (!get_confirmation()) {
7015 goto sanitize_bailout;
7020 use_timeout = timeout;
7022 use_timeout = (immediate ? 10 : 10800) * 1000;
7024 if (immediate == 0 && quiet == 0) {
7025 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
7026 use_timeout / 1000);
7030 * If the user hasn't disabled questions and didn't specify a
7031 * timeout on the command line, ask them if they want the current
7034 if (immediate == 0 && ycount == 0 && timeout == 0) {
7036 int new_timeout = 0;
7038 fprintf(stdout, "Enter new timeout in seconds or press\n"
7039 "return to keep the current timeout [%d] ",
7040 use_timeout / 1000);
7042 if (fgets(str, sizeof(str), stdin) != NULL) {
7044 new_timeout = atoi(str);
7047 if (new_timeout != 0) {
7048 use_timeout = new_timeout * 1000;
7049 fprintf(stdout, "Using new timeout value %d\n",
7050 use_timeout / 1000);
7054 if (dt == CC_DT_SCSI) {
7057 byte2 |= SSZ_UNRESTRICTED_EXIT;
7060 scsi_sanitize(&ccb->csio,
7061 /* retries */ retry_count,
7063 /* tag_action */ task_attr,
7066 /* data_ptr */ data_ptr,
7067 /* dxfer_len */ dxfer_len,
7068 /* sense_len */ SSD_FULL_SIZE,
7069 /* timeout */ use_timeout);
7071 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7072 if (arglist & CAM_ARG_ERR_RECOVER)
7073 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7074 if (cam_send_ccb(device, ccb) < 0) {
7075 warn("error sending sanitize command");
7077 goto sanitize_bailout;
7079 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7080 if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
7081 feature = 0x14; /* OVERWRITE EXT */
7082 lba = 0x4F5700000000 | scsi_4btoul(data_ptr + 4);
7083 count = (passes == 0) ? 1 : (passes >= 16) ? 0 : passes;
7085 count |= 0x80; /* INVERT PATTERN */
7087 count |= 0x10; /* FAILURE MODE */
7088 } else if (action == SSZ_SERVICE_ACTION_BLOCK_ERASE) {
7089 feature = 0x12; /* BLOCK ERASE EXT */
7090 lba = 0x0000426B4572;
7093 count |= 0x10; /* FAILURE MODE */
7094 } else if (action == SSZ_SERVICE_ACTION_CRYPTO_ERASE) {
7095 feature = 0x11; /* CRYPTO SCRAMBLE EXT */
7096 lba = 0x000043727970;
7099 count |= 0x10; /* FAILURE MODE */
7100 } else if (action == SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE) {
7101 feature = 0x00; /* SANITIZE STATUS EXT */
7103 count = 1; /* CLEAR SANITIZE OPERATION FAILED */
7106 goto sanitize_bailout;
7109 error = ata_do_cmd(device,
7112 /*flags*/CAM_DIR_NONE,
7113 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
7115 /*tag_action*/MSG_SIMPLE_Q_TAG,
7116 /*command*/ATA_SANITIZE,
7117 /*features*/feature,
7119 /*sector_count*/count,
7122 /*timeout*/ use_timeout,
7126 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7127 struct scsi_sense_data *sense;
7128 int error_code, sense_key, asc, ascq;
7130 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
7131 CAM_SCSI_STATUS_ERROR) {
7132 sense = &ccb->csio.sense_data;
7133 scsi_extract_sense_len(sense, ccb->csio.sense_len -
7134 ccb->csio.sense_resid, &error_code, &sense_key,
7135 &asc, &ascq, /*show_errors*/ 1);
7137 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
7138 asc == 0x20 && ascq == 0x00)
7139 warnx("sanitize is not supported by "
7142 warnx("error sanitizing this device");
7144 warnx("error sanitizing this device");
7146 if (arglist & CAM_ARG_VERBOSE) {
7147 cam_error_print(device, ccb, CAM_ESF_ALL,
7148 CAM_EPF_ALL, stderr);
7151 goto sanitize_bailout;
7155 * If we ran in non-immediate mode, we already checked for errors
7156 * above and printed out any necessary information. If we're in
7157 * immediate mode, we need to loop through and get status
7158 * information periodically.
7160 if (immediate == 0) {
7162 fprintf(stdout, "Sanitize Complete\n");
7164 goto sanitize_bailout;
7168 if (dt == CC_DT_SCSI) {
7169 error = sanitize_wait_scsi(device, ccb, task_attr, quiet);
7170 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7171 error = sanitize_wait_ata(device, ccb, quiet, dt);
7174 if (error == 0 && quiet == 0)
7175 fprintf(stdout, "Sanitize Complete \n");
7180 if (data_ptr != NULL)
7188 scsireportluns(struct cam_device *device, int argc, char **argv,
7189 char *combinedopt, int task_attr, int retry_count, int timeout)
7192 int c, countonly, lunsonly;
7193 struct scsi_report_luns_data *lundata;
7195 uint8_t report_type;
7196 uint32_t list_len, i, j;
7201 report_type = RPL_REPORT_DEFAULT;
7202 ccb = cam_getccb(device);
7205 warnx("%s: error allocating ccb", __func__);
7209 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7214 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7223 if (strcasecmp(optarg, "default") == 0)
7224 report_type = RPL_REPORT_DEFAULT;
7225 else if (strcasecmp(optarg, "wellknown") == 0)
7226 report_type = RPL_REPORT_WELLKNOWN;
7227 else if (strcasecmp(optarg, "all") == 0)
7228 report_type = RPL_REPORT_ALL;
7230 warnx("%s: invalid report type \"%s\"",
7241 if ((countonly != 0)
7242 && (lunsonly != 0)) {
7243 warnx("%s: you can only specify one of -c or -l", __func__);
7248 * According to SPC-4, the allocation length must be at least 16
7249 * bytes -- enough for the header and one LUN.
7251 alloc_len = sizeof(*lundata) + 8;
7255 lundata = malloc(alloc_len);
7257 if (lundata == NULL) {
7258 warn("%s: error mallocing %d bytes", __func__, alloc_len);
7263 scsi_report_luns(&ccb->csio,
7264 /*retries*/ retry_count,
7266 /*tag_action*/ task_attr,
7267 /*select_report*/ report_type,
7268 /*rpl_buf*/ lundata,
7269 /*alloc_len*/ alloc_len,
7270 /*sense_len*/ SSD_FULL_SIZE,
7271 /*timeout*/ timeout ? timeout : 5000);
7273 /* Disable freezing the device queue */
7274 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7276 if (arglist & CAM_ARG_ERR_RECOVER)
7277 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7279 if (cam_send_ccb(device, ccb) < 0) {
7280 warn("error sending REPORT LUNS command");
7285 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7286 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7292 list_len = scsi_4btoul(lundata->length);
7295 * If we need to list the LUNs, and our allocation
7296 * length was too short, reallocate and retry.
7298 if ((countonly == 0)
7299 && (list_len > (alloc_len - sizeof(*lundata)))) {
7300 alloc_len = list_len + sizeof(*lundata);
7306 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7307 ((list_len / 8) > 1) ? "s" : "");
7312 for (i = 0; i < (list_len / 8); i++) {
7316 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7318 fprintf(stdout, ",");
7319 switch (lundata->luns[i].lundata[j] &
7320 RPL_LUNDATA_ATYP_MASK) {
7321 case RPL_LUNDATA_ATYP_PERIPH:
7322 if ((lundata->luns[i].lundata[j] &
7323 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7324 fprintf(stdout, "%d:",
7325 lundata->luns[i].lundata[j] &
7326 RPL_LUNDATA_PERIPH_BUS_MASK);
7328 && ((lundata->luns[i].lundata[j+2] &
7329 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7332 fprintf(stdout, "%d",
7333 lundata->luns[i].lundata[j+1]);
7335 case RPL_LUNDATA_ATYP_FLAT: {
7337 tmplun[0] = lundata->luns[i].lundata[j] &
7338 RPL_LUNDATA_FLAT_LUN_MASK;
7339 tmplun[1] = lundata->luns[i].lundata[j+1];
7341 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7345 case RPL_LUNDATA_ATYP_LUN:
7346 fprintf(stdout, "%d:%d:%d",
7347 (lundata->luns[i].lundata[j+1] &
7348 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7349 lundata->luns[i].lundata[j] &
7350 RPL_LUNDATA_LUN_TARG_MASK,
7351 lundata->luns[i].lundata[j+1] &
7352 RPL_LUNDATA_LUN_LUN_MASK);
7354 case RPL_LUNDATA_ATYP_EXTLUN: {
7355 int field_len_code, eam_code;
7357 eam_code = lundata->luns[i].lundata[j] &
7358 RPL_LUNDATA_EXT_EAM_MASK;
7359 field_len_code = (lundata->luns[i].lundata[j] &
7360 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7362 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7363 && (field_len_code == 0x00)) {
7364 fprintf(stdout, "%d",
7365 lundata->luns[i].lundata[j+1]);
7366 } else if ((eam_code ==
7367 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7368 && (field_len_code == 0x03)) {
7372 * This format takes up all 8 bytes.
7373 * If we aren't starting at offset 0,
7377 fprintf(stdout, "Invalid "
7380 "specified format", j);
7384 bzero(tmp_lun, sizeof(tmp_lun));
7385 bcopy(&lundata->luns[i].lundata[j+1],
7386 &tmp_lun[1], sizeof(tmp_lun) - 1);
7387 fprintf(stdout, "%#jx",
7388 (intmax_t)scsi_8btou64(tmp_lun));
7391 fprintf(stderr, "Unknown Extended LUN"
7392 "Address method %#x, length "
7393 "code %#x", eam_code,
7400 fprintf(stderr, "Unknown LUN address method "
7401 "%#x\n", lundata->luns[i].lundata[0] &
7402 RPL_LUNDATA_ATYP_MASK);
7406 * For the flat addressing method, there are no
7407 * other levels after it.
7412 fprintf(stdout, "\n");
7425 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7426 char *combinedopt, int task_attr, int retry_count, int timeout)
7429 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7430 struct scsi_read_capacity_data rcap;
7431 struct scsi_read_capacity_data_long rcaplong;
7446 ccb = cam_getccb(device);
7449 warnx("%s: error allocating ccb", __func__);
7453 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7455 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7485 if ((blocksizeonly != 0)
7486 && (numblocks != 0)) {
7487 warnx("%s: you can only specify one of -b or -N", __func__);
7492 if ((blocksizeonly != 0)
7493 && (sizeonly != 0)) {
7494 warnx("%s: you can only specify one of -b or -s", __func__);
7501 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7507 && (blocksizeonly != 0)) {
7508 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7516 scsi_read_capacity(&ccb->csio,
7517 /*retries*/ retry_count,
7519 /*tag_action*/ task_attr,
7522 /*timeout*/ timeout ? timeout : 5000);
7524 /* Disable freezing the device queue */
7525 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7527 if (arglist & CAM_ARG_ERR_RECOVER)
7528 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7530 if (cam_send_ccb(device, ccb) < 0) {
7531 warn("error sending READ CAPACITY command");
7536 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7537 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7542 maxsector = scsi_4btoul(rcap.addr);
7543 block_len = scsi_4btoul(rcap.length);
7546 * A last block of 2^32-1 means that the true capacity is over 2TB,
7547 * and we need to issue the long READ CAPACITY to get the real
7548 * capacity. Otherwise, we're all set.
7550 if (maxsector != 0xffffffff)
7554 scsi_read_capacity_16(&ccb->csio,
7555 /*retries*/ retry_count,
7557 /*tag_action*/ task_attr,
7561 /*rcap_buf*/ (uint8_t *)&rcaplong,
7562 /*rcap_buf_len*/ sizeof(rcaplong),
7563 /*sense_len*/ SSD_FULL_SIZE,
7564 /*timeout*/ timeout ? timeout : 5000);
7566 /* Disable freezing the device queue */
7567 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7569 if (arglist & CAM_ARG_ERR_RECOVER)
7570 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7572 if (cam_send_ccb(device, ccb) < 0) {
7573 warn("error sending READ CAPACITY (16) command");
7578 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7579 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7584 maxsector = scsi_8btou64(rcaplong.addr);
7585 block_len = scsi_4btoul(rcaplong.length);
7588 if (blocksizeonly == 0) {
7590 * Humanize implies !quiet, and also implies numblocks.
7592 if (humanize != 0) {
7597 tmpbytes = (maxsector + 1) * block_len;
7598 ret = humanize_number(tmpstr, sizeof(tmpstr),
7599 tmpbytes, "", HN_AUTOSCALE,
7602 HN_DIVISOR_1000 : 0));
7604 warnx("%s: humanize_number failed!", __func__);
7608 fprintf(stdout, "Device Size: %s%s", tmpstr,
7609 (sizeonly == 0) ? ", " : "\n");
7610 } else if (numblocks != 0) {
7611 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7612 "Blocks: " : "", (uintmax_t)maxsector + 1,
7613 (sizeonly == 0) ? ", " : "\n");
7615 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7616 "Last Block: " : "", (uintmax_t)maxsector,
7617 (sizeonly == 0) ? ", " : "\n");
7621 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7622 "Block Length: " : "", block_len, (quiet == 0) ?
7631 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7632 int retry_count, int timeout)
7636 uint8_t *smp_request = NULL, *smp_response = NULL;
7637 int request_size = 0, response_size = 0;
7638 int fd_request = 0, fd_response = 0;
7639 char *datastr = NULL;
7640 struct get_hook hook;
7645 * Note that at the moment we don't support sending SMP CCBs to
7646 * devices that aren't probed by CAM.
7648 ccb = cam_getccb(device);
7650 warnx("%s: error allocating CCB", __func__);
7654 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7656 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7659 arglist |= CAM_ARG_CMD_IN;
7660 response_size = strtol(optarg, NULL, 0);
7661 if (response_size <= 0) {
7662 warnx("invalid number of response bytes %d",
7665 goto smpcmd_bailout;
7667 hook.argc = argc - optind;
7668 hook.argv = argv + optind;
7671 datastr = cget(&hook, NULL);
7673 * If the user supplied "-" instead of a format, he
7674 * wants the data to be written to stdout.
7676 if ((datastr != NULL)
7677 && (datastr[0] == '-'))
7680 smp_response = (u_int8_t *)malloc(response_size);
7681 if (smp_response == NULL) {
7682 warn("can't malloc memory for SMP response");
7684 goto smpcmd_bailout;
7688 arglist |= CAM_ARG_CMD_OUT;
7689 request_size = strtol(optarg, NULL, 0);
7690 if (request_size <= 0) {
7691 warnx("invalid number of request bytes %d",
7694 goto smpcmd_bailout;
7696 hook.argc = argc - optind;
7697 hook.argv = argv + optind;
7699 datastr = cget(&hook, NULL);
7700 smp_request = (u_int8_t *)malloc(request_size);
7701 if (smp_request == NULL) {
7702 warn("can't malloc memory for SMP request");
7704 goto smpcmd_bailout;
7706 bzero(smp_request, request_size);
7708 * If the user supplied "-" instead of a format, he
7709 * wants the data to be read from stdin.
7711 if ((datastr != NULL)
7712 && (datastr[0] == '-'))
7715 buff_encode_visit(smp_request, request_size,
7726 * If fd_data is set, and we're writing to the device, we need to
7727 * read the data the user wants written from stdin.
7729 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7731 int amt_to_read = request_size;
7732 u_int8_t *buf_ptr = smp_request;
7734 for (amt_read = 0; amt_to_read > 0;
7735 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7736 if (amt_read == -1) {
7737 warn("error reading data from stdin");
7739 goto smpcmd_bailout;
7741 amt_to_read -= amt_read;
7742 buf_ptr += amt_read;
7746 if (((arglist & CAM_ARG_CMD_IN) == 0)
7747 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7748 warnx("%s: need both the request (-r) and response (-R) "
7749 "arguments", __func__);
7751 goto smpcmd_bailout;
7754 flags |= CAM_DEV_QFRZDIS;
7756 cam_fill_smpio(&ccb->smpio,
7757 /*retries*/ retry_count,
7760 /*smp_request*/ smp_request,
7761 /*smp_request_len*/ request_size,
7762 /*smp_response*/ smp_response,
7763 /*smp_response_len*/ response_size,
7764 /*timeout*/ timeout ? timeout : 5000);
7766 ccb->smpio.flags = SMP_FLAG_NONE;
7768 if (((retval = cam_send_ccb(device, ccb)) < 0)
7769 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7770 const char warnstr[] = "error sending command";
7777 if (arglist & CAM_ARG_VERBOSE) {
7778 cam_error_print(device, ccb, CAM_ESF_ALL,
7779 CAM_EPF_ALL, stderr);
7783 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7784 && (response_size > 0)) {
7785 if (fd_response == 0) {
7786 buff_decode_visit(smp_response, response_size,
7787 datastr, arg_put, NULL);
7788 fprintf(stdout, "\n");
7790 ssize_t amt_written;
7791 int amt_to_write = response_size;
7792 u_int8_t *buf_ptr = smp_response;
7794 for (amt_written = 0; (amt_to_write > 0) &&
7795 (amt_written = write(STDOUT_FILENO, buf_ptr,
7796 amt_to_write)) > 0;){
7797 amt_to_write -= amt_written;
7798 buf_ptr += amt_written;
7800 if (amt_written == -1) {
7801 warn("error writing data to stdout");
7803 goto smpcmd_bailout;
7804 } else if ((amt_written == 0)
7805 && (amt_to_write > 0)) {
7806 warnx("only wrote %u bytes out of %u",
7807 response_size - amt_to_write,
7816 if (smp_request != NULL)
7819 if (smp_response != NULL)
7826 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7827 int retry_count, int timeout)
7831 int32_t mmc_opcode = 0, mmc_arg = 0;
7832 int32_t mmc_flags = -1;
7835 int is_bw_4 = 0, is_bw_1 = 0;
7836 int is_frequency = 0;
7837 int is_highspeed = 0, is_stdspeed = 0;
7838 int is_info_request = 0;
7840 uint8_t mmc_data_byte = 0;
7841 uint32_t mmc_frequency = 0;
7843 /* For IO_RW_EXTENDED command */
7844 uint8_t *mmc_data = NULL;
7845 struct mmc_data mmc_d;
7846 int mmc_data_len = 0;
7849 * Note that at the moment we don't support sending SMP CCBs to
7850 * devices that aren't probed by CAM.
7852 ccb = cam_getccb(device);
7854 warnx("%s: error allocating CCB", __func__);
7858 bzero(&(&ccb->ccb_h)[1],
7859 sizeof(union ccb) - sizeof(struct ccb_hdr));
7861 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7870 if (!strcmp(optarg, "high"))
7876 is_info_request = 1;
7880 mmc_frequency = strtol(optarg, NULL, 0);
7883 mmc_opcode = strtol(optarg, NULL, 0);
7884 if (mmc_opcode < 0) {
7885 warnx("invalid MMC opcode %d",
7888 goto mmccmd_bailout;
7892 mmc_arg = strtol(optarg, NULL, 0);
7894 warnx("invalid MMC arg %d",
7897 goto mmccmd_bailout;
7901 mmc_flags = strtol(optarg, NULL, 0);
7902 if (mmc_flags < 0) {
7903 warnx("invalid MMC flags %d",
7906 goto mmccmd_bailout;
7910 mmc_data_len = strtol(optarg, NULL, 0);
7911 if (mmc_data_len <= 0) {
7912 warnx("invalid MMC data len %d",
7915 goto mmccmd_bailout;
7922 mmc_data_byte = strtol(optarg, NULL, 0);
7928 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7930 /* If flags are left default, supply the right flags */
7932 switch (mmc_opcode) {
7933 case MMC_GO_IDLE_STATE:
7934 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7936 case IO_SEND_OP_COND:
7937 mmc_flags = MMC_RSP_R4;
7939 case SD_SEND_RELATIVE_ADDR:
7940 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7942 case MMC_SELECT_CARD:
7943 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7944 mmc_arg = mmc_arg << 16;
7946 case SD_IO_RW_DIRECT:
7947 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7948 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7950 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7952 case SD_IO_RW_EXTENDED:
7953 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7954 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7955 int len_arg = mmc_data_len;
7956 if (mmc_data_len == 512)
7960 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7962 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7965 mmc_flags = MMC_RSP_R1;
7969 // Switch bus width instead of sending IO command
7970 if (is_bw_4 || is_bw_1) {
7971 struct ccb_trans_settings_mmc *cts;
7972 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7973 ccb->ccb_h.flags = 0;
7974 cts = &ccb->cts.proto_specific.mmc;
7975 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7976 cts->ios_valid = MMC_BW;
7977 if (((retval = cam_send_ccb(device, ccb)) < 0)
7978 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7979 warn("Error sending command");
7981 printf("Parameters set OK\n");
7988 struct ccb_trans_settings_mmc *cts;
7989 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7990 ccb->ccb_h.flags = 0;
7991 cts = &ccb->cts.proto_specific.mmc;
7992 cts->ios.clock = mmc_frequency;
7993 cts->ios_valid = MMC_CLK;
7994 if (((retval = cam_send_ccb(device, ccb)) < 0)
7995 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7996 warn("Error sending command");
7998 printf("Parameters set OK\n");
8004 // Switch bus speed instead of sending IO command
8005 if (is_stdspeed || is_highspeed) {
8006 struct ccb_trans_settings_mmc *cts;
8007 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
8008 ccb->ccb_h.flags = 0;
8009 cts = &ccb->cts.proto_specific.mmc;
8010 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
8011 cts->ios_valid = MMC_BT;
8012 if (((retval = cam_send_ccb(device, ccb)) < 0)
8013 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8014 warn("Error sending command");
8016 printf("Speed set OK (HS: %d)\n", is_highspeed);
8022 // Get information about controller and its settings
8023 if (is_info_request) {
8024 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
8025 ccb->ccb_h.flags = 0;
8026 struct ccb_trans_settings_mmc *cts;
8027 cts = &ccb->cts.proto_specific.mmc;
8028 if (((retval = cam_send_ccb(device, ccb)) < 0)
8029 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8030 warn("Error sending command");
8033 printf("Host controller information\n");
8034 printf("Host OCR: 0x%x\n", cts->host_ocr);
8035 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
8036 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
8037 printf("Supported bus width:\n");
8038 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
8040 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
8043 printf("Supported operating modes:\n");
8044 if (cts->host_caps & MMC_CAP_HSPEED)
8045 printf(" Can do High Speed transfers\n");
8046 if (cts->host_caps & MMC_CAP_UHS_SDR12)
8047 printf(" Can do UHS SDR12\n");
8048 if (cts->host_caps & MMC_CAP_UHS_SDR25)
8049 printf(" Can do UHS SDR25\n");
8050 if (cts->host_caps & MMC_CAP_UHS_SDR50)
8051 printf(" Can do UHS SDR50\n");
8052 if (cts->host_caps & MMC_CAP_UHS_SDR104)
8053 printf(" Can do UHS SDR104\n");
8054 if (cts->host_caps & MMC_CAP_UHS_DDR50)
8055 printf(" Can do UHS DDR50\n");
8056 if (cts->host_caps & MMC_CAP_MMC_DDR52_120)
8057 printf(" Can do eMMC DDR52 at 1.2V\n");
8058 if (cts->host_caps & MMC_CAP_MMC_DDR52_180)
8059 printf(" Can do eMMC DDR52 at 1.8V\n");
8060 if (cts->host_caps & MMC_CAP_MMC_HS200_120)
8061 printf(" Can do eMMC HS200 at 1.2V\n");
8062 if (cts->host_caps & MMC_CAP_MMC_HS200_180)
8063 printf(" Can do eMMC HS200 at 1.8V\n");
8064 if (cts->host_caps & MMC_CAP_MMC_HS400_120)
8065 printf(" Can do eMMC HS400 at 1.2V\n");
8066 if (cts->host_caps & MMC_CAP_MMC_HS400_180)
8067 printf(" Can do eMMC HS400 at 1.8V\n");
8069 printf("Supported VCCQ voltages:\n");
8070 if (cts->host_caps & MMC_CAP_SIGNALING_120)
8072 if (cts->host_caps & MMC_CAP_SIGNALING_180)
8074 if (cts->host_caps & MMC_CAP_SIGNALING_330)
8077 printf("Current settings:\n");
8078 printf(" Bus width: ");
8079 switch (cts->ios.bus_width) {
8090 printf(" Freq: %d.%03d MHz%s\n",
8091 cts->ios.clock / 1000000,
8092 (cts->ios.clock / 1000) % 1000,
8093 cts->ios.timing == bus_timing_hs ? " (high-speed timing)" : "");
8096 switch (cts->ios.vccq) {
8110 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
8112 if (mmc_data_len > 0) {
8113 flags |= CAM_DIR_IN;
8114 mmc_data = malloc(mmc_data_len);
8115 memset(mmc_data, 0, mmc_data_len);
8116 memset(&mmc_d, 0, sizeof(mmc_d));
8117 mmc_d.len = mmc_data_len;
8118 mmc_d.data = mmc_data;
8119 mmc_d.flags = MMC_DATA_READ;
8120 } else flags |= CAM_DIR_NONE;
8122 cam_fill_mmcio(&ccb->mmcio,
8123 /*retries*/ retry_count,
8126 /*mmc_opcode*/ mmc_opcode,
8127 /*mmc_arg*/ mmc_arg,
8128 /*mmc_flags*/ mmc_flags,
8129 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
8130 /*timeout*/ timeout ? timeout : 5000);
8132 if (((retval = cam_send_ccb(device, ccb)) < 0)
8133 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8134 const char warnstr[] = "error sending command";
8141 if (arglist & CAM_ARG_VERBOSE) {
8142 cam_error_print(device, ccb, CAM_ESF_ALL,
8143 CAM_EPF_ALL, stderr);
8147 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
8148 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
8149 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
8150 ccb->mmcio.cmd.resp[1],
8151 ccb->mmcio.cmd.resp[2],
8152 ccb->mmcio.cmd.resp[3]);
8154 switch (mmc_opcode) {
8155 case SD_IO_RW_DIRECT:
8156 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
8157 SD_R5_DATA(ccb->mmcio.cmd.resp),
8158 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
8160 case SD_IO_RW_EXTENDED:
8161 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
8162 hexdump(mmc_data, mmc_data_len, NULL, 0);
8164 case SD_SEND_RELATIVE_ADDR:
8165 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
8168 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
8175 if (mmc_data_len > 0 && mmc_data != NULL)
8182 smpreportgeneral(struct cam_device *device, int argc, char **argv,
8183 char *combinedopt, int retry_count, int timeout)
8186 struct smp_report_general_request *request = NULL;
8187 struct smp_report_general_response *response = NULL;
8188 struct sbuf *sb = NULL;
8190 int c, long_response = 0;
8194 * Note that at the moment we don't support sending SMP CCBs to
8195 * devices that aren't probed by CAM.
8197 ccb = cam_getccb(device);
8199 warnx("%s: error allocating CCB", __func__);
8203 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8205 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8214 request = malloc(sizeof(*request));
8215 if (request == NULL) {
8216 warn("%s: unable to allocate %zd bytes", __func__,
8222 response = malloc(sizeof(*response));
8223 if (response == NULL) {
8224 warn("%s: unable to allocate %zd bytes", __func__,
8231 smp_report_general(&ccb->smpio,
8235 /*request_len*/ sizeof(*request),
8236 (uint8_t *)response,
8237 /*response_len*/ sizeof(*response),
8238 /*long_response*/ long_response,
8241 if (((retval = cam_send_ccb(device, ccb)) < 0)
8242 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8243 const char warnstr[] = "error sending command";
8250 if (arglist & CAM_ARG_VERBOSE) {
8251 cam_error_print(device, ccb, CAM_ESF_ALL,
8252 CAM_EPF_ALL, stderr);
8259 * If the device supports the long response bit, try again and see
8260 * if we can get all of the data.
8262 if ((response->long_response & SMP_RG_LONG_RESPONSE)
8263 && (long_response == 0)) {
8264 ccb->ccb_h.status = CAM_REQ_INPROG;
8265 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8271 * XXX KDM detect and decode SMP errors here.
8273 sb = sbuf_new_auto();
8275 warnx("%s: error allocating sbuf", __func__);
8279 smp_report_general_sbuf(response, sizeof(*response), sb);
8281 if (sbuf_finish(sb) != 0) {
8282 warnx("%s: sbuf_finish", __func__);
8286 printf("%s", sbuf_data(sb));
8292 if (request != NULL)
8295 if (response != NULL)
8304 static struct camcontrol_opts phy_ops[] = {
8305 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
8306 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
8307 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
8308 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
8309 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
8310 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
8311 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
8312 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
8313 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
8318 smpphycontrol(struct cam_device *device, int argc, char **argv,
8319 char *combinedopt, int retry_count, int timeout)
8322 struct smp_phy_control_request *request = NULL;
8323 struct smp_phy_control_response *response = NULL;
8324 int long_response = 0;
8327 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
8329 uint64_t attached_dev_name = 0;
8330 int dev_name_set = 0;
8331 uint32_t min_plr = 0, max_plr = 0;
8332 uint32_t pp_timeout_val = 0;
8333 int slumber_partial = 0;
8334 int set_pp_timeout_val = 0;
8338 * Note that at the moment we don't support sending SMP CCBs to
8339 * devices that aren't probed by CAM.
8341 ccb = cam_getccb(device);
8343 warnx("%s: error allocating CCB", __func__);
8347 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8349 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8357 if (strcasecmp(optarg, "enable") == 0)
8359 else if (strcasecmp(optarg, "disable") == 0)
8362 warnx("%s: Invalid argument %s", __func__,
8369 slumber_partial |= enable <<
8370 SMP_PC_SAS_SLUMBER_SHIFT;
8373 slumber_partial |= enable <<
8374 SMP_PC_SAS_PARTIAL_SHIFT;
8377 slumber_partial |= enable <<
8378 SMP_PC_SATA_SLUMBER_SHIFT;
8381 slumber_partial |= enable <<
8382 SMP_PC_SATA_PARTIAL_SHIFT;
8385 warnx("%s: programmer error", __func__);
8388 break; /*NOTREACHED*/
8393 attached_dev_name = (uintmax_t)strtoumax(optarg,
8402 * We don't do extensive checking here, so this
8403 * will continue to work when new speeds come out.
8405 min_plr = strtoul(optarg, NULL, 0);
8407 || (min_plr > 0xf)) {
8408 warnx("%s: invalid link rate %x",
8416 * We don't do extensive checking here, so this
8417 * will continue to work when new speeds come out.
8419 max_plr = strtoul(optarg, NULL, 0);
8421 || (max_plr > 0xf)) {
8422 warnx("%s: invalid link rate %x",
8429 camcontrol_optret optreturn;
8430 cam_argmask argnums;
8433 if (phy_op_set != 0) {
8434 warnx("%s: only one phy operation argument "
8435 "(-o) allowed", __func__);
8443 * Allow the user to specify the phy operation
8444 * numerically, as well as with a name. This will
8445 * future-proof it a bit, so options that are added
8446 * in future specs can be used.
8448 if (isdigit(optarg[0])) {
8449 phy_operation = strtoul(optarg, NULL, 0);
8450 if ((phy_operation == 0)
8451 || (phy_operation > 0xff)) {
8452 warnx("%s: invalid phy operation %#x",
8453 __func__, phy_operation);
8459 optreturn = getoption(phy_ops, optarg, &phy_operation,
8462 if (optreturn == CC_OR_AMBIGUOUS) {
8463 warnx("%s: ambiguous option %s", __func__,
8468 } else if (optreturn == CC_OR_NOT_FOUND) {
8469 warnx("%s: option %s not found", __func__,
8481 pp_timeout_val = strtoul(optarg, NULL, 0);
8482 if (pp_timeout_val > 15) {
8483 warnx("%s: invalid partial pathway timeout "
8484 "value %u, need a value less than 16",
8485 __func__, pp_timeout_val);
8489 set_pp_timeout_val = 1;
8497 warnx("%s: a PHY (-p phy) argument is required",__func__);
8502 if (((dev_name_set != 0)
8503 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8504 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8505 && (dev_name_set == 0))) {
8506 warnx("%s: -d name and -o setdevname arguments both "
8507 "required to set device name", __func__);
8512 request = malloc(sizeof(*request));
8513 if (request == NULL) {
8514 warn("%s: unable to allocate %zd bytes", __func__,
8520 response = malloc(sizeof(*response));
8521 if (response == NULL) {
8522 warn("%s: unable to allocate %zd bytes", __func__,
8528 smp_phy_control(&ccb->smpio,
8533 (uint8_t *)response,
8536 /*expected_exp_change_count*/ 0,
8539 (set_pp_timeout_val != 0) ? 1 : 0,
8547 if (((retval = cam_send_ccb(device, ccb)) < 0)
8548 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8549 const char warnstr[] = "error sending command";
8556 if (arglist & CAM_ARG_VERBOSE) {
8558 * Use CAM_EPF_NORMAL so we only get one line of
8559 * SMP command decoding.
8561 cam_error_print(device, ccb, CAM_ESF_ALL,
8562 CAM_EPF_NORMAL, stderr);
8568 /* XXX KDM print out something here for success? */
8573 if (request != NULL)
8576 if (response != NULL)
8583 smpmaninfo(struct cam_device *device, int argc, char **argv,
8584 char *combinedopt, int retry_count, int timeout)
8587 struct smp_report_manuf_info_request request;
8588 struct smp_report_manuf_info_response response;
8589 struct sbuf *sb = NULL;
8590 int long_response = 0;
8595 * Note that at the moment we don't support sending SMP CCBs to
8596 * devices that aren't probed by CAM.
8598 ccb = cam_getccb(device);
8600 warnx("%s: error allocating CCB", __func__);
8604 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8606 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8615 bzero(&request, sizeof(request));
8616 bzero(&response, sizeof(response));
8618 smp_report_manuf_info(&ccb->smpio,
8623 (uint8_t *)&response,
8628 if (((retval = cam_send_ccb(device, ccb)) < 0)
8629 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8630 const char warnstr[] = "error sending command";
8637 if (arglist & CAM_ARG_VERBOSE) {
8638 cam_error_print(device, ccb, CAM_ESF_ALL,
8639 CAM_EPF_ALL, stderr);
8645 sb = sbuf_new_auto();
8647 warnx("%s: error allocating sbuf", __func__);
8651 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8653 if (sbuf_finish(sb) != 0) {
8654 warnx("%s: sbuf_finish", __func__);
8658 printf("%s", sbuf_data(sb));
8672 getdevid(struct cam_devitem *item)
8675 union ccb *ccb = NULL;
8677 struct cam_device *dev;
8679 dev = cam_open_btl(item->dev_match.path_id,
8680 item->dev_match.target_id,
8681 item->dev_match.target_lun, O_RDWR, NULL);
8684 warnx("%s", cam_errbuf);
8689 item->device_id_len = 0;
8691 ccb = cam_getccb(dev);
8693 warnx("%s: error allocating CCB", __func__);
8698 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8701 * On the first try, we just probe for the size of the data, and
8702 * then allocate that much memory and try again.
8705 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8706 ccb->ccb_h.flags = CAM_DIR_IN;
8707 ccb->cdai.flags = CDAI_FLAG_NONE;
8708 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8709 ccb->cdai.bufsiz = item->device_id_len;
8710 if (item->device_id_len != 0)
8711 ccb->cdai.buf = (uint8_t *)item->device_id;
8713 if (cam_send_ccb(dev, ccb) < 0) {
8714 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8719 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8720 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8725 if (item->device_id_len == 0) {
8727 * This is our first time through. Allocate the buffer,
8728 * and then go back to get the data.
8730 if (ccb->cdai.provsiz == 0) {
8731 warnx("%s: invalid .provsiz field returned with "
8732 "XPT_GDEV_ADVINFO CCB", __func__);
8736 item->device_id_len = ccb->cdai.provsiz;
8737 item->device_id = malloc(item->device_id_len);
8738 if (item->device_id == NULL) {
8739 warn("%s: unable to allocate %d bytes", __func__,
8740 item->device_id_len);
8744 ccb->ccb_h.status = CAM_REQ_INPROG;
8750 cam_close_device(dev);
8759 * XXX KDM merge this code with getdevtree()?
8762 buildbusdevlist(struct cam_devlist *devlist)
8765 int bufsize, fd = -1;
8766 struct dev_match_pattern *patterns;
8767 struct cam_devitem *item = NULL;
8768 int skip_device = 0;
8771 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8772 warn("couldn't open %s", XPT_DEVICE);
8776 bzero(&ccb, sizeof(union ccb));
8778 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8779 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8780 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8782 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8783 bufsize = sizeof(struct dev_match_result) * 100;
8784 ccb.cdm.match_buf_len = bufsize;
8785 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8786 if (ccb.cdm.matches == NULL) {
8787 warnx("can't malloc memory for matches");
8791 ccb.cdm.num_matches = 0;
8792 ccb.cdm.num_patterns = 2;
8793 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8794 ccb.cdm.num_patterns;
8796 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8797 if (patterns == NULL) {
8798 warnx("can't malloc memory for patterns");
8803 ccb.cdm.patterns = patterns;
8804 bzero(patterns, ccb.cdm.pattern_buf_len);
8806 patterns[0].type = DEV_MATCH_DEVICE;
8807 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8808 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8809 patterns[1].type = DEV_MATCH_PERIPH;
8810 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8811 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8814 * We do the ioctl multiple times if necessary, in case there are
8815 * more than 100 nodes in the EDT.
8820 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8821 warn("error sending CAMIOCOMMAND ioctl");
8826 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8827 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8828 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8829 warnx("got CAM error %#x, CDM error %d\n",
8830 ccb.ccb_h.status, ccb.cdm.status);
8835 for (i = 0; i < ccb.cdm.num_matches; i++) {
8836 switch (ccb.cdm.matches[i].type) {
8837 case DEV_MATCH_DEVICE: {
8838 struct device_match_result *dev_result;
8841 &ccb.cdm.matches[i].result.device_result;
8843 if (dev_result->flags &
8844 DEV_RESULT_UNCONFIGURED) {
8850 item = malloc(sizeof(*item));
8852 warn("%s: unable to allocate %zd bytes",
8853 __func__, sizeof(*item));
8857 bzero(item, sizeof(*item));
8858 bcopy(dev_result, &item->dev_match,
8859 sizeof(*dev_result));
8860 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8863 if (getdevid(item) != 0) {
8869 case DEV_MATCH_PERIPH: {
8870 struct periph_match_result *periph_result;
8873 &ccb.cdm.matches[i].result.periph_result;
8875 if (skip_device != 0)
8877 item->num_periphs++;
8878 item->periph_matches = realloc(
8879 item->periph_matches,
8881 sizeof(struct periph_match_result));
8882 if (item->periph_matches == NULL) {
8883 warn("%s: error allocating periph "
8888 bcopy(periph_result, &item->periph_matches[
8889 item->num_periphs - 1],
8890 sizeof(*periph_result));
8894 fprintf(stderr, "%s: unexpected match "
8895 "type %d\n", __func__,
8896 ccb.cdm.matches[i].type);
8899 break; /*NOTREACHED*/
8902 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8903 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8911 free(ccb.cdm.matches);
8914 freebusdevlist(devlist);
8920 freebusdevlist(struct cam_devlist *devlist)
8922 struct cam_devitem *item, *item2;
8924 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8925 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8927 free(item->device_id);
8928 free(item->periph_matches);
8933 static struct cam_devitem *
8934 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8936 struct cam_devitem *item;
8938 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8939 struct scsi_vpd_id_descriptor *idd;
8942 * XXX KDM look for LUN IDs as well?
8944 idd = scsi_get_devid(item->device_id,
8945 item->device_id_len,
8946 scsi_devid_is_sas_target);
8950 if (scsi_8btou64(idd->identifier) == sasaddr)
8958 smpphylist(struct cam_device *device, int argc, char **argv,
8959 char *combinedopt, int retry_count, int timeout)
8961 struct smp_report_general_request *rgrequest = NULL;
8962 struct smp_report_general_response *rgresponse = NULL;
8963 struct smp_discover_request *disrequest = NULL;
8964 struct smp_discover_response *disresponse = NULL;
8965 struct cam_devlist devlist;
8967 int long_response = 0;
8974 * Note that at the moment we don't support sending SMP CCBs to
8975 * devices that aren't probed by CAM.
8977 ccb = cam_getccb(device);
8979 warnx("%s: error allocating CCB", __func__);
8983 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8984 STAILQ_INIT(&devlist.dev_queue);
8986 rgrequest = malloc(sizeof(*rgrequest));
8987 if (rgrequest == NULL) {
8988 warn("%s: unable to allocate %zd bytes", __func__,
8989 sizeof(*rgrequest));
8994 rgresponse = malloc(sizeof(*rgresponse));
8995 if (rgresponse == NULL) {
8996 warn("%s: unable to allocate %zd bytes", __func__,
8997 sizeof(*rgresponse));
9002 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9015 smp_report_general(&ccb->smpio,
9019 /*request_len*/ sizeof(*rgrequest),
9020 (uint8_t *)rgresponse,
9021 /*response_len*/ sizeof(*rgresponse),
9022 /*long_response*/ long_response,
9025 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9027 if (((retval = cam_send_ccb(device, ccb)) < 0)
9028 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
9029 const char warnstr[] = "error sending command";
9036 if (arglist & CAM_ARG_VERBOSE) {
9037 cam_error_print(device, ccb, CAM_ESF_ALL,
9038 CAM_EPF_ALL, stderr);
9044 num_phys = rgresponse->num_phys;
9046 if (num_phys == 0) {
9048 fprintf(stdout, "%s: No Phys reported\n", __func__);
9053 devlist.path_id = device->path_id;
9055 retval = buildbusdevlist(&devlist);
9060 fprintf(stdout, "%d PHYs:\n", num_phys);
9061 fprintf(stdout, "PHY Attached SAS Address\n");
9064 disrequest = malloc(sizeof(*disrequest));
9065 if (disrequest == NULL) {
9066 warn("%s: unable to allocate %zd bytes", __func__,
9067 sizeof(*disrequest));
9072 disresponse = malloc(sizeof(*disresponse));
9073 if (disresponse == NULL) {
9074 warn("%s: unable to allocate %zd bytes", __func__,
9075 sizeof(*disresponse));
9080 for (i = 0; i < num_phys; i++) {
9081 struct cam_devitem *item;
9082 struct device_match_result *dev_match;
9083 char vendor[16], product[48], revision[16];
9087 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
9089 ccb->ccb_h.status = CAM_REQ_INPROG;
9090 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9092 smp_discover(&ccb->smpio,
9096 sizeof(*disrequest),
9097 (uint8_t *)disresponse,
9098 sizeof(*disresponse),
9100 /*ignore_zone_group*/ 0,
9104 if (((retval = cam_send_ccb(device, ccb)) < 0)
9105 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
9106 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
9107 const char warnstr[] = "error sending command";
9114 if (arglist & CAM_ARG_VERBOSE) {
9115 cam_error_print(device, ccb, CAM_ESF_ALL,
9116 CAM_EPF_ALL, stderr);
9122 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
9124 fprintf(stdout, "%3d <vacant>\n", i);
9128 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
9131 item = findsasdevice(&devlist,
9132 scsi_8btou64(disresponse->attached_sas_address));
9136 || (item != NULL)) {
9137 fprintf(stdout, "%3d 0x%016jx", i,
9138 (uintmax_t)scsi_8btou64(
9139 disresponse->attached_sas_address));
9141 fprintf(stdout, "\n");
9144 } else if (quiet != 0)
9147 dev_match = &item->dev_match;
9149 if (dev_match->protocol == PROTO_SCSI) {
9150 cam_strvis(vendor, dev_match->inq_data.vendor,
9151 sizeof(dev_match->inq_data.vendor),
9153 cam_strvis(product, dev_match->inq_data.product,
9154 sizeof(dev_match->inq_data.product),
9156 cam_strvis(revision, dev_match->inq_data.revision,
9157 sizeof(dev_match->inq_data.revision),
9159 sprintf(tmpstr, "<%s %s %s>", vendor, product,
9161 } else if ((dev_match->protocol == PROTO_ATA)
9162 || (dev_match->protocol == PROTO_SATAPM)) {
9163 cam_strvis(product, dev_match->ident_data.model,
9164 sizeof(dev_match->ident_data.model),
9166 cam_strvis(revision, dev_match->ident_data.revision,
9167 sizeof(dev_match->ident_data.revision),
9169 sprintf(tmpstr, "<%s %s>", product, revision);
9171 sprintf(tmpstr, "<>");
9173 fprintf(stdout, " %-33s ", tmpstr);
9176 * If we have 0 periphs, that's a bug...
9178 if (item->num_periphs == 0) {
9179 fprintf(stdout, "\n");
9183 fprintf(stdout, "(");
9184 for (j = 0; j < item->num_periphs; j++) {
9186 fprintf(stdout, ",");
9188 fprintf(stdout, "%s%d",
9189 item->periph_matches[j].periph_name,
9190 item->periph_matches[j].unit_number);
9193 fprintf(stdout, ")\n");
9207 freebusdevlist(&devlist);
9213 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
9215 uint8_t error = 0, ata_device = 0, status = 0;
9220 retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
9223 if (arglist & CAM_ARG_VERBOSE) {
9224 cam_error_print(device, ccb, CAM_ESF_ALL,
9225 CAM_EPF_ALL, stderr);
9227 warnx("Can't get ATA command status");
9231 if (status & ATA_STATUS_ERROR) {
9232 cam_error_print(device, ccb, CAM_ESF_ALL,
9233 CAM_EPF_ALL, stderr);
9237 printf("%s%d: ", device->device_name, device->dev_unit_num);
9240 printf("Standby mode\n");
9243 printf("Standby_y mode\n");
9246 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
9249 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
9252 printf("Idle mode\n");
9255 printf("Idle_a mode\n");
9258 printf("Idle_b mode\n");
9261 printf("Idle_c mode\n");
9264 printf("Active or Idle mode\n");
9267 printf("Unknown mode 0x%02x\n", count);
9275 atapm(struct cam_device *device, int argc, char **argv,
9276 char *combinedopt, int retry_count, int timeout)
9282 u_int8_t ata_flags = 0;
9285 ccb = cam_getccb(device);
9288 warnx("%s: error allocating ccb", __func__);
9292 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9301 if (strcmp(argv[1], "idle") == 0) {
9303 cmd = ATA_IDLE_IMMEDIATE;
9306 } else if (strcmp(argv[1], "standby") == 0) {
9308 cmd = ATA_STANDBY_IMMEDIATE;
9310 cmd = ATA_STANDBY_CMD;
9311 } else if (strcmp(argv[1], "powermode") == 0) {
9312 cmd = ATA_CHECK_POWER_MODE;
9313 ata_flags = AP_FLAG_CHK_COND;
9322 else if (t <= (240 * 5))
9324 else if (t <= (252 * 5))
9325 /* special encoding for 21 minutes */
9327 else if (t <= (11 * 30 * 60))
9328 sc = (t - 1) / (30 * 60) + 241;
9332 retval = ata_do_cmd(device,
9334 /*retries*/retry_count,
9335 /*flags*/CAM_DIR_NONE,
9336 /*protocol*/AP_PROTO_NON_DATA,
9337 /*ata_flags*/ata_flags,
9338 /*tag_action*/MSG_SIMPLE_Q_TAG,
9345 /*timeout*/timeout ? timeout : 30 * 1000,
9350 if (retval || cmd != ATA_CHECK_POWER_MODE)
9353 return (atapm_proc_resp(device, ccb));
9357 ataaxm(struct cam_device *device, int argc, char **argv,
9358 char *combinedopt, int retry_count, int timeout)
9366 ccb = cam_getccb(device);
9369 warnx("%s: error allocating ccb", __func__);
9373 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9383 if (strcmp(argv[1], "apm") == 0) {
9399 retval = ata_do_cmd(device,
9401 /*retries*/retry_count,
9402 /*flags*/CAM_DIR_NONE,
9403 /*protocol*/AP_PROTO_NON_DATA,
9405 /*tag_action*/MSG_SIMPLE_Q_TAG,
9406 /*command*/ATA_SETFEATURES,
9412 /*timeout*/timeout ? timeout : 30 * 1000,
9420 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9421 int show_sa_errors, int sa_set, int service_action,
9422 int timeout_desc, int task_attr, int retry_count, int timeout,
9423 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9425 union ccb *ccb = NULL;
9426 uint8_t *buf = NULL;
9427 uint32_t alloc_len = 0, num_opcodes;
9428 uint32_t valid_len = 0;
9429 uint32_t avail_len = 0;
9430 struct scsi_report_supported_opcodes_all *all_hdr;
9431 struct scsi_report_supported_opcodes_one *one;
9436 * Make it clear that we haven't yet allocated or filled anything.
9441 ccb = cam_getccb(device);
9443 warnx("couldn't allocate CCB");
9448 /* cam_getccb cleans up the header, caller has to zero the payload */
9449 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9451 if (opcode_set != 0) {
9452 options |= RSO_OPTIONS_OC;
9454 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9457 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9458 sizeof(struct scsi_report_supported_opcodes_descr));
9461 if (timeout_desc != 0) {
9462 options |= RSO_RCTD;
9463 alloc_len += num_opcodes *
9464 sizeof(struct scsi_report_supported_opcodes_timeout);
9468 options |= RSO_OPTIONS_OC_SA;
9469 if (show_sa_errors != 0)
9470 options &= ~RSO_OPTIONS_OC;
9479 buf = malloc(alloc_len);
9481 warn("Unable to allocate %u bytes", alloc_len);
9485 bzero(buf, alloc_len);
9487 scsi_report_supported_opcodes(&ccb->csio,
9488 /*retries*/ retry_count,
9490 /*tag_action*/ task_attr,
9491 /*options*/ options,
9492 /*req_opcode*/ opcode,
9493 /*req_service_action*/ service_action,
9495 /*dxfer_len*/ alloc_len,
9496 /*sense_len*/ SSD_FULL_SIZE,
9497 /*timeout*/ timeout ? timeout : 10000);
9499 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9501 if (retry_count != 0)
9502 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9504 if (cam_send_ccb(device, ccb) < 0) {
9505 warn("error sending REPORT SUPPORTED OPERATION CODES command");
9510 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9511 if (verbosemode != 0)
9512 cam_error_print(device, ccb, CAM_ESF_ALL,
9513 CAM_EPF_ALL, stderr);
9518 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9520 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9521 && (valid_len >= sizeof(*all_hdr))) {
9522 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9523 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9524 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9525 && (valid_len >= sizeof(*one))) {
9526 uint32_t cdb_length;
9528 one = (struct scsi_report_supported_opcodes_one *)buf;
9529 cdb_length = scsi_2btoul(one->cdb_length);
9530 avail_len = sizeof(*one) + cdb_length;
9531 if (one->support & RSO_ONE_CTDP) {
9532 struct scsi_report_supported_opcodes_timeout *td;
9534 td = (struct scsi_report_supported_opcodes_timeout *)
9536 if (valid_len >= (avail_len + sizeof(td->length))) {
9537 avail_len += scsi_2btoul(td->length) +
9540 avail_len += sizeof(*td);
9546 * avail_len could be zero if we didn't get enough data back from
9547 * thet target to determine
9549 if ((avail_len != 0)
9550 && (avail_len > valid_len)) {
9551 alloc_len = avail_len;
9555 *fill_len = valid_len;
9567 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9568 int req_sa, uint8_t *buf, uint32_t valid_len)
9570 struct scsi_report_supported_opcodes_one *one;
9571 struct scsi_report_supported_opcodes_timeout *td;
9572 uint32_t cdb_len = 0, td_len = 0;
9573 const char *op_desc = NULL;
9577 one = (struct scsi_report_supported_opcodes_one *)buf;
9580 * If we don't have the full single opcode descriptor, no point in
9583 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9585 warnx("Only %u bytes returned, not enough to verify support",
9591 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9593 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9596 printf(", SA 0x%x", req_sa);
9599 switch (one->support & RSO_ONE_SUP_MASK) {
9600 case RSO_ONE_SUP_UNAVAIL:
9601 printf("No command support information currently available\n");
9603 case RSO_ONE_SUP_NOT_SUP:
9604 printf("Command not supported\n");
9607 break; /*NOTREACHED*/
9608 case RSO_ONE_SUP_AVAIL:
9609 printf("Command is supported, complies with a SCSI standard\n");
9611 case RSO_ONE_SUP_VENDOR:
9612 printf("Command is supported, vendor-specific "
9613 "implementation\n");
9616 printf("Unknown command support flags 0x%#x\n",
9617 one->support & RSO_ONE_SUP_MASK);
9622 * If we don't have the CDB length, it isn't exactly an error, the
9623 * command probably isn't supported.
9625 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9629 cdb_len = scsi_2btoul(one->cdb_length);
9632 * If our valid data doesn't include the full reported length,
9633 * return. The caller should have detected this and adjusted his
9634 * allocation length to get all of the available data.
9636 if (valid_len < sizeof(*one) + cdb_len) {
9642 * If all we have is the opcode, there is no point in printing out
9650 printf("CDB usage bitmap:");
9651 for (i = 0; i < cdb_len; i++) {
9652 printf(" %02x", one->cdb_usage[i]);
9657 * If we don't have a timeout descriptor, we're done.
9659 if ((one->support & RSO_ONE_CTDP) == 0)
9663 * If we don't have enough valid length to include the timeout
9664 * descriptor length, we're done.
9666 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9669 td = (struct scsi_report_supported_opcodes_timeout *)
9670 &buf[sizeof(*one) + cdb_len];
9671 td_len = scsi_2btoul(td->length);
9672 td_len += sizeof(td->length);
9675 * If we don't have the full timeout descriptor, we're done.
9677 if (td_len < sizeof(*td))
9681 * If we don't have enough valid length to contain the full timeout
9682 * descriptor, we're done.
9684 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9687 printf("Timeout information:\n");
9688 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9689 printf("Nominal timeout: %u seconds\n",
9690 scsi_4btoul(td->nominal_time));
9691 printf("Recommended timeout: %u seconds\n",
9692 scsi_4btoul(td->recommended_time));
9699 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9702 struct scsi_report_supported_opcodes_all *hdr;
9703 struct scsi_report_supported_opcodes_descr *desc;
9704 uint32_t avail_len = 0, used_len = 0;
9708 if (valid_len < sizeof(*hdr)) {
9709 warnx("%s: not enough returned data (%u bytes) opcode list",
9710 __func__, valid_len);
9714 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9715 avail_len = scsi_4btoul(hdr->length);
9716 avail_len += sizeof(hdr->length);
9718 * Take the lesser of the amount of data the drive claims is
9719 * available, and the amount of data the HBA says was returned.
9721 avail_len = MIN(avail_len, valid_len);
9723 used_len = sizeof(hdr->length);
9725 printf("%-6s %4s %8s ",
9726 "Opcode", "SA", "CDB len" );
9729 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9730 printf(" Description\n");
9732 while ((avail_len - used_len) > sizeof(*desc)) {
9733 struct scsi_report_supported_opcodes_timeout *td;
9735 const char *op_desc = NULL;
9737 cur_ptr = &buf[used_len];
9738 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9740 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9741 if (op_desc == NULL)
9742 op_desc = "UNKNOWN";
9744 printf("0x%02x %#4x %8u ", desc->opcode,
9745 scsi_2btoul(desc->service_action),
9746 scsi_2btoul(desc->cdb_length));
9748 used_len += sizeof(*desc);
9750 if ((desc->flags & RSO_CTDP) == 0) {
9751 printf(" %s\n", op_desc);
9756 * If we don't have enough space to fit a timeout
9757 * descriptor, then we're done.
9759 if (avail_len - used_len < sizeof(*td)) {
9760 used_len = avail_len;
9761 printf(" %s\n", op_desc);
9764 cur_ptr = &buf[used_len];
9765 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9766 td_len = scsi_2btoul(td->length);
9767 td_len += sizeof(td->length);
9771 * If the given timeout descriptor length is less than what
9772 * we understand, skip it.
9774 if (td_len < sizeof(*td)) {
9775 printf(" %s\n", op_desc);
9779 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9780 scsi_4btoul(td->nominal_time),
9781 scsi_4btoul(td->recommended_time), op_desc);
9788 scsiopcodes(struct cam_device *device, int argc, char **argv,
9789 char *combinedopt, int task_attr, int retry_count, int timeout,
9793 uint32_t opcode = 0, service_action = 0;
9794 int td_set = 0, opcode_set = 0, sa_set = 0;
9795 int show_sa_errors = 1;
9796 uint32_t valid_len = 0;
9797 uint8_t *buf = NULL;
9801 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9807 opcode = strtoul(optarg, &endptr, 0);
9808 if (*endptr != '\0') {
9809 warnx("Invalid opcode \"%s\", must be a number",
9814 if (opcode > 0xff) {
9815 warnx("Invalid opcode 0x%#x, must be between"
9816 "0 and 0xff inclusive", opcode);
9823 service_action = strtoul(optarg, &endptr, 0);
9824 if (*endptr != '\0') {
9825 warnx("Invalid service action \"%s\", must "
9826 "be a number", optarg);
9830 if (service_action > 0xffff) {
9831 warnx("Invalid service action 0x%#x, must "
9832 "be between 0 and 0xffff inclusive",
9847 && (opcode_set == 0)) {
9848 warnx("You must specify an opcode with -o if a service "
9853 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9854 sa_set, service_action, td_set, task_attr,
9855 retry_count, timeout, verbosemode, &valid_len,
9860 if ((opcode_set != 0)
9862 retval = scsiprintoneopcode(device, opcode, sa_set,
9863 service_action, buf, valid_len);
9865 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9876 reprobe(struct cam_device *device)
9881 ccb = cam_getccb(device);
9884 warnx("%s: error allocating ccb", __func__);
9888 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
9890 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9892 if (cam_send_ccb(device, ccb) < 0) {
9893 warn("error sending XPT_REPROBE_LUN CCB");
9898 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9899 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9911 usage(int printlong)
9914 fprintf(printlong ? stdout : stderr,
9915 "usage: camcontrol <command> [device id][generic args][command args]\n"
9916 " camcontrol devlist [-b] [-v]\n"
9917 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9918 " camcontrol tur [dev_id][generic args]\n"
9919 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9920 " camcontrol identify [dev_id][generic args] [-v]\n"
9921 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9922 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9924 " camcontrol start [dev_id][generic args]\n"
9925 " camcontrol stop [dev_id][generic args]\n"
9926 " camcontrol load [dev_id][generic args]\n"
9927 " camcontrol eject [dev_id][generic args]\n"
9928 " camcontrol reprobe [dev_id][generic args]\n"
9929 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9930 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9931 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9932 " [-q][-s][-S offset][-X]\n"
9933 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9934 " [-P pagectl][-e | -b][-d]\n"
9935 " camcontrol cmd [dev_id][generic args]\n"
9936 " <-a cmd [args] | -c cmd [args]>\n"
9937 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9938 " camcontrol smpcmd [dev_id][generic args]\n"
9939 " <-r len fmt [args]> <-R len fmt [args]>\n"
9940 " camcontrol smprg [dev_id][generic args][-l]\n"
9941 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9942 " [-o operation][-d name][-m rate][-M rate]\n"
9943 " [-T pp_timeout][-a enable|disable]\n"
9944 " [-A enable|disable][-s enable|disable]\n"
9945 " [-S enable|disable]\n"
9946 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9947 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9948 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9949 " <all|dev_id|bus[:target[:lun]]|off>\n"
9950 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9951 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9952 " [-D <enable|disable>][-M mode][-O offset]\n"
9953 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9954 " [-U][-W bus_width]\n"
9955 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9956 " camcontrol sanitize [dev_id][generic args]\n"
9957 " [-a overwrite|block|crypto|exitfailure]\n"
9958 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9960 " camcontrol idle [dev_id][generic args][-t time]\n"
9961 " camcontrol standby [dev_id][generic args][-t time]\n"
9962 " camcontrol sleep [dev_id][generic args]\n"
9963 " camcontrol powermode [dev_id][generic args]\n"
9964 " camcontrol apm [dev_id][generic args][-l level]\n"
9965 " camcontrol aam [dev_id][generic args][-l level]\n"
9966 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9968 " camcontrol security [dev_id][generic args]\n"
9969 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9970 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9971 " [-U <user|master>] [-y]\n"
9972 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9973 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9974 " camcontrol ama [dev_id][generic args] [-f] [-q] [-s max_sectors]\n"
9975 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9976 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9977 " [-s scope][-S][-T type][-U]\n"
9978 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9979 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9980 " [-p part][-s start][-T type][-V vol]\n"
9981 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9983 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9984 " [-o rep_opts] [-P print_opts]\n"
9985 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9986 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9987 " [-S power_src] [-T timer]\n"
9988 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9989 " <-s <-f format -T time | -U >>\n"
9990 " camcontrol devtype [dev_id]\n"
9992 " camcontrol help\n");
9996 "Specify one of the following options:\n"
9997 "devlist list all CAM devices\n"
9998 "periphlist list all CAM peripheral drivers attached to a device\n"
9999 "tur send a test unit ready to the named device\n"
10000 "inquiry send a SCSI inquiry command to the named device\n"
10001 "identify send a ATA identify command to the named device\n"
10002 "reportluns send a SCSI report luns command to the device\n"
10003 "readcap send a SCSI read capacity command to the device\n"
10004 "start send a Start Unit command to the device\n"
10005 "stop send a Stop Unit command to the device\n"
10006 "load send a Start Unit command to the device with the load bit set\n"
10007 "eject send a Stop Unit command to the device with the eject bit set\n"
10008 "reprobe update capacity information of the given device\n"
10009 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
10010 "reset reset all buses, the given bus, bus:target:lun or device\n"
10011 "defects read the defect list of the specified device\n"
10012 "modepage display or edit (-e) the given mode page\n"
10013 "cmd send the given SCSI command, may need -i or -o as well\n"
10014 "smpcmd send the given SMP command, requires -o and -i\n"
10015 "smprg send the SMP Report General command\n"
10016 "smppc send the SMP PHY Control command, requires -p\n"
10017 "smpphylist display phys attached to a SAS expander\n"
10018 "smpmaninfo send the SMP Report Manufacturer Info command\n"
10019 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
10020 "tags report or set the number of transaction slots for a device\n"
10021 "negotiate report or set device negotiation parameters\n"
10022 "format send the SCSI FORMAT UNIT command to the named device\n"
10023 "sanitize send the SCSI SANITIZE command to the named device\n"
10024 "idle send the ATA IDLE command to the named device\n"
10025 "standby send the ATA STANDBY command to the named device\n"
10026 "sleep send the ATA SLEEP command to the named device\n"
10027 "powermode send the ATA CHECK POWER MODE command to the named device\n"
10028 "fwdownload program firmware of the named device with the given image\n"
10029 "security report or send ATA security commands to the named device\n"
10030 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
10031 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
10032 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
10033 "zone manage Zoned Block (Shingled) devices\n"
10034 "epc send ATA Extended Power Conditions commands\n"
10035 "timestamp report or set the device's timestamp\n"
10036 "devtype report the type of device\n"
10037 "help this message\n"
10038 "Device Identifiers:\n"
10039 "bus:target specify the bus and target, lun defaults to 0\n"
10040 "bus:target:lun specify the bus, target and lun\n"
10041 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
10042 "Generic arguments:\n"
10043 "-v be verbose, print out sense information\n"
10044 "-t timeout command timeout in seconds, overrides default timeout\n"
10045 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
10046 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
10047 "-E have the kernel attempt to perform SCSI error recovery\n"
10048 "-C count specify the SCSI command retry count (needs -E to work)\n"
10049 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
10050 "modepage arguments:\n"
10051 "-l list all available mode pages\n"
10052 "-m page specify the mode page to view or edit\n"
10053 "-e edit the specified mode page\n"
10054 "-b force view to binary mode\n"
10055 "-d disable block descriptors for mode sense\n"
10056 "-P pgctl page control field 0-3\n"
10057 "defects arguments:\n"
10058 "-f format specify defect list format (block, bfi or phys)\n"
10059 "-G get the grown defect list\n"
10060 "-P get the permanent defect list\n"
10061 "inquiry arguments:\n"
10062 "-D get the standard inquiry data\n"
10063 "-S get the serial number\n"
10064 "-R get the transfer rate, etc.\n"
10065 "reportluns arguments:\n"
10066 "-c only report a count of available LUNs\n"
10067 "-l only print out luns, and not a count\n"
10068 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
10069 "readcap arguments\n"
10070 "-b only report the blocksize\n"
10071 "-h human readable device size, base 2\n"
10072 "-H human readable device size, base 10\n"
10073 "-N print the number of blocks instead of last block\n"
10074 "-q quiet, print numbers only\n"
10075 "-s only report the last block/device size\n"
10077 "-c cdb [args] specify the SCSI CDB\n"
10078 "-i len fmt specify input data and input data format\n"
10079 "-o len fmt [args] specify output data and output data fmt\n"
10080 "smpcmd arguments:\n"
10081 "-r len fmt [args] specify the SMP command to be sent\n"
10082 "-R len fmt [args] specify SMP response format\n"
10083 "smprg arguments:\n"
10084 "-l specify the long response format\n"
10085 "smppc arguments:\n"
10086 "-p phy specify the PHY to operate on\n"
10087 "-l specify the long request/response format\n"
10088 "-o operation specify the phy control operation\n"
10089 "-d name set the attached device name\n"
10090 "-m rate set the minimum physical link rate\n"
10091 "-M rate set the maximum physical link rate\n"
10092 "-T pp_timeout set the partial pathway timeout value\n"
10093 "-a enable|disable enable or disable SATA slumber\n"
10094 "-A enable|disable enable or disable SATA partial phy power\n"
10095 "-s enable|disable enable or disable SAS slumber\n"
10096 "-S enable|disable enable or disable SAS partial phy power\n"
10097 "smpphylist arguments:\n"
10098 "-l specify the long response format\n"
10099 "-q only print phys with attached devices\n"
10100 "smpmaninfo arguments:\n"
10101 "-l specify the long response format\n"
10102 "debug arguments:\n"
10103 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
10104 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
10105 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
10106 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
10107 "tags arguments:\n"
10108 "-N tags specify the number of tags to use for this device\n"
10109 "-q be quiet, don't report the number of tags\n"
10110 "-v report a number of tag-related parameters\n"
10111 "negotiate arguments:\n"
10112 "-a send a test unit ready after negotiation\n"
10113 "-c report/set current negotiation settings\n"
10114 "-D <arg> \"enable\" or \"disable\" disconnection\n"
10115 "-M mode set ATA mode\n"
10116 "-O offset set command delay offset\n"
10117 "-q be quiet, don't report anything\n"
10118 "-R syncrate synchronization rate in MHz\n"
10119 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
10120 "-U report/set user negotiation settings\n"
10121 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
10122 "-v also print a Path Inquiry CCB for the controller\n"
10123 "format arguments:\n"
10124 "-q be quiet, don't print status messages\n"
10125 "-r run in report only mode\n"
10126 "-w don't send immediate format command\n"
10127 "-y don't ask any questions\n"
10128 "sanitize arguments:\n"
10129 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
10130 "-c passes overwrite passes to perform (1 to 31)\n"
10131 "-I invert overwrite pattern after each pass\n"
10132 "-P pattern path to overwrite pattern file\n"
10133 "-q be quiet, don't print status messages\n"
10134 "-r run in report only mode\n"
10135 "-U run operation in unrestricted completion exit mode\n"
10136 "-w don't send immediate sanitize command\n"
10137 "-y don't ask any questions\n"
10138 "idle/standby arguments:\n"
10139 "-t <arg> number of seconds before respective state.\n"
10140 "fwdownload arguments:\n"
10141 "-f fw_image path to firmware image file\n"
10142 "-q don't print informational messages, only errors\n"
10143 "-s run in simulation mode\n"
10144 "-v print info for every firmware segment sent to device\n"
10145 "-y don't ask any questions\n"
10146 "security arguments:\n"
10147 "-d pwd disable security using the given password for the selected\n"
10149 "-e pwd erase the device using the given pwd for the selected user\n"
10150 "-f freeze the security configuration of the specified device\n"
10151 "-h pwd enhanced erase the device using the given pwd for the\n"
10153 "-k pwd unlock the device using the given pwd for the selected\n"
10155 "-l <high|maximum> specifies which security level to set: high or maximum\n"
10156 "-q be quiet, do not print any status messages\n"
10157 "-s pwd password the device (enable security) using the given\n"
10158 " pwd for the selected user\n"
10159 "-T timeout overrides the timeout (seconds) used for erase operation\n"
10160 "-U <user|master> specifies which user to set: user or master\n"
10161 "-y don't ask any questions\n"
10163 "-f freeze the HPA configuration of the device\n"
10164 "-l lock the HPA configuration of the device\n"
10165 "-P make the HPA max sectors persist\n"
10166 "-p pwd Set the HPA configuration password required for unlock\n"
10168 "-q be quiet, do not print any status messages\n"
10169 "-s sectors configures the maximum user accessible sectors of the\n"
10171 "-U pwd unlock the HPA configuration of the device\n"
10172 "-y don't ask any questions\n"
10174 "-f freeze the AMA configuration of the device\n"
10175 "-q be quiet, do not print any status messages\n"
10176 "-s sectors configures the maximum user accessible sectors of the\n"
10178 "persist arguments:\n"
10179 "-i action specify read_keys, read_reservation, report_cap, or\n"
10180 " read_full_status\n"
10181 "-o action specify register, register_ignore, reserve, release,\n"
10182 " clear, preempt, preempt_abort, register_move, replace_lost\n"
10183 "-a set the All Target Ports (ALL_TG_PT) bit\n"
10184 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
10185 "-k key specify the Reservation Key\n"
10186 "-K sa_key specify the Service Action Reservation Key\n"
10187 "-p set the Activate Persist Through Power Loss bit\n"
10188 "-R rtp specify the Relative Target Port\n"
10189 "-s scope specify the scope: lun, extent, element or a number\n"
10190 "-S specify Transport ID for register, requires -I\n"
10191 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
10192 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
10193 "-U unregister the current initiator for register_move\n"
10194 "attrib arguments:\n"
10195 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
10197 "-w attr specify an attribute to write, one -w argument per attr\n"
10198 "-a attr_num only display this attribute number\n"
10199 "-c get cached attributes\n"
10200 "-e elem_addr request attributes for the given element in a changer\n"
10201 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
10202 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
10203 " field_none, field_desc, field_num, field_size, field_rw\n"
10204 "-p partition request attributes for the given partition\n"
10205 "-s start_attr request attributes starting at the given number\n"
10206 "-T elem_type specify the element type (used with -e)\n"
10207 "-V logical_vol specify the logical volume ID\n"
10208 "opcodes arguments:\n"
10209 "-o opcode specify the individual opcode to list\n"
10210 "-s service_action specify the service action for the opcode\n"
10211 "-N do not return SCSI error for unsupported SA\n"
10212 "-T request nominal and recommended timeout values\n"
10213 "zone arguments:\n"
10214 "-c cmd required: rz, open, close, finish, or rwp\n"
10215 "-a apply the action to all zones\n"
10216 "-l LBA specify the zone starting LBA\n"
10217 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
10218 " closed, full, ro, offline, reset, nonseq, nonwp\n"
10219 "-P print_opt report zones printing: normal, summary, script\n"
10221 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
10222 " source, status, list\n"
10223 "-d disable power mode (timer, state)\n"
10224 "-D delayed entry (goto)\n"
10225 "-e enable power mode (timer, state)\n"
10226 "-H hold power mode (goto)\n"
10227 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
10229 "-P only display power mode (status)\n"
10230 "-r rst_src restore settings from: default, saved (restore)\n"
10231 "-s save mode (timer, state, restore)\n"
10232 "-S power_src set power source: battery, nonbattery (source)\n"
10233 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
10234 "timestamp arguments:\n"
10235 "-r report the timestamp of the device\n"
10236 "-f format report the timestamp of the device with the given\n"
10237 " strftime(3) format string\n"
10238 "-m report the timestamp of the device as milliseconds since\n"
10239 " January 1st, 1970\n"
10240 "-U report the time with UTC instead of the local time zone\n"
10241 "-s set the timestamp of the device\n"
10242 "-f format the format of the time string passed into strptime(3)\n"
10243 "-T time the time value passed into strptime(3)\n"
10244 "-U set the timestamp of the device to UTC time\n"
10249 main(int argc, char **argv)
10252 char *device = NULL;
10254 struct cam_device *cam_dev = NULL;
10255 int timeout = 0, retry_count = 1;
10256 camcontrol_optret optreturn;
10258 const char *mainopt = "C:En:Q:t:u:v";
10259 const char *subopt = NULL;
10260 char combinedopt[256];
10261 int error = 0, optstart = 2;
10262 int task_attr = MSG_SIMPLE_Q_TAG;
10265 target_id_t target;
10268 cmdlist = CAM_CMD_NONE;
10269 arglist = CAM_ARG_NONE;
10277 * Get the base option.
10279 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
10281 if (optreturn == CC_OR_AMBIGUOUS) {
10282 warnx("ambiguous option %s", argv[1]);
10285 } else if (optreturn == CC_OR_NOT_FOUND) {
10286 warnx("option %s not found", argv[1]);
10292 * Ahh, getopt(3) is a pain.
10294 * This is a gross hack. There really aren't many other good
10295 * options (excuse the pun) for parsing options in a situation like
10296 * this. getopt is kinda braindead, so you end up having to run
10297 * through the options twice, and give each invocation of getopt
10298 * the option string for the other invocation.
10300 * You would think that you could just have two groups of options.
10301 * The first group would get parsed by the first invocation of
10302 * getopt, and the second group would get parsed by the second
10303 * invocation of getopt. It doesn't quite work out that way. When
10304 * the first invocation of getopt finishes, it leaves optind pointing
10305 * to the argument _after_ the first argument in the second group.
10306 * So when the second invocation of getopt comes around, it doesn't
10307 * recognize the first argument it gets and then bails out.
10309 * A nice alternative would be to have a flag for getopt that says
10310 * "just keep parsing arguments even when you encounter an unknown
10311 * argument", but there isn't one. So there's no real clean way to
10312 * easily parse two sets of arguments without having one invocation
10313 * of getopt know about the other.
10315 * Without this hack, the first invocation of getopt would work as
10316 * long as the generic arguments are first, but the second invocation
10317 * (in the subfunction) would fail in one of two ways. In the case
10318 * where you don't set optreset, it would fail because optind may be
10319 * pointing to the argument after the one it should be pointing at.
10320 * In the case where you do set optreset, and reset optind, it would
10321 * fail because getopt would run into the first set of options, which
10322 * it doesn't understand.
10324 * All of this would "sort of" work if you could somehow figure out
10325 * whether optind had been incremented one option too far. The
10326 * mechanics of that, however, are more daunting than just giving
10327 * both invocations all of the expect options for either invocation.
10329 * Needless to say, I wouldn't mind if someone invented a better
10330 * (non-GPL!) command line parsing interface than getopt. I
10331 * wouldn't mind if someone added more knobs to getopt to make it
10332 * work better. Who knows, I may talk myself into doing it someday,
10333 * if the standards weenies let me. As it is, it just leads to
10334 * hackery like this and causes people to avoid it in some cases.
10336 * KDM, September 8th, 1998
10338 if (subopt != NULL)
10339 sprintf(combinedopt, "%s%s", mainopt, subopt);
10341 sprintf(combinedopt, "%s", mainopt);
10344 * For these options we do not parse optional device arguments and
10345 * we do not open a passthrough device.
10347 if ((cmdlist == CAM_CMD_RESCAN)
10348 || (cmdlist == CAM_CMD_RESET)
10349 || (cmdlist == CAM_CMD_DEVTREE)
10350 || (cmdlist == CAM_CMD_USAGE)
10351 || (cmdlist == CAM_CMD_DEBUG))
10355 && (argc > 2 && argv[2][0] != '-')) {
10359 if (isdigit(argv[2][0])) {
10360 /* device specified as bus:target[:lun] */
10361 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10363 errx(1, "numeric device specification must "
10364 "be either bus:target, or "
10366 /* default to 0 if lun was not specified */
10367 if ((arglist & CAM_ARG_LUN) == 0) {
10369 arglist |= CAM_ARG_LUN;
10373 if (cam_get_device(argv[2], name, sizeof name, &unit)
10375 errx(1, "%s", cam_errbuf);
10376 device = strdup(name);
10377 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10382 * Start getopt processing at argv[2/3], since we've already
10383 * accepted argv[1..2] as the command name, and as a possible
10389 * Now we run through the argument list looking for generic
10390 * options, and ignoring options that possibly belong to
10393 while ((c = getopt(argc, argv, combinedopt))!= -1){
10396 retry_count = strtol(optarg, NULL, 0);
10397 if (retry_count < 0)
10398 errx(1, "retry count %d is < 0",
10400 arglist |= CAM_ARG_RETRIES;
10403 arglist |= CAM_ARG_ERR_RECOVER;
10406 arglist |= CAM_ARG_DEVICE;
10408 while (isspace(*tstr) && (*tstr != '\0'))
10410 device = (char *)strdup(tstr);
10414 int table_entry = 0;
10417 while (isspace(*tstr) && (*tstr != '\0'))
10419 if (isdigit(*tstr)) {
10420 task_attr = strtol(tstr, &endptr, 0);
10421 if (*endptr != '\0') {
10422 errx(1, "Invalid queue option "
10427 scsi_nv_status status;
10429 table_size = sizeof(task_attrs) /
10430 sizeof(task_attrs[0]);
10431 status = scsi_get_nv(task_attrs,
10432 table_size, tstr, &table_entry,
10433 SCSI_NV_FLAG_IG_CASE);
10434 if (status == SCSI_NV_FOUND)
10435 task_attr = task_attrs[
10436 table_entry].value;
10438 errx(1, "%s option %s",
10439 (status == SCSI_NV_AMBIGUOUS)?
10440 "ambiguous" : "invalid",
10447 timeout = strtol(optarg, NULL, 0);
10449 errx(1, "invalid timeout %d", timeout);
10450 /* Convert the timeout from seconds to ms */
10452 arglist |= CAM_ARG_TIMEOUT;
10455 arglist |= CAM_ARG_UNIT;
10456 unit = strtol(optarg, NULL, 0);
10459 arglist |= CAM_ARG_VERBOSE;
10467 * For most commands we'll want to open the passthrough device
10468 * associated with the specified device. In the case of the rescan
10469 * commands, we don't use a passthrough device at all, just the
10470 * transport layer device.
10472 if (devopen == 1) {
10473 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10474 && (((arglist & CAM_ARG_DEVICE) == 0)
10475 || ((arglist & CAM_ARG_UNIT) == 0))) {
10476 errx(1, "subcommand \"%s\" requires a valid device "
10477 "identifier", argv[1]);
10480 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10481 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10482 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10484 errx(1,"%s", cam_errbuf);
10488 * Reset optind to 2, and reset getopt, so these routines can parse
10489 * the arguments again.
10495 case CAM_CMD_DEVLIST:
10496 error = getdevlist(cam_dev);
10499 error = atahpa(cam_dev, retry_count, timeout,
10500 argc, argv, combinedopt);
10503 error = ataama(cam_dev, retry_count, timeout,
10504 argc, argv, combinedopt);
10506 case CAM_CMD_DEVTREE:
10507 error = getdevtree(argc, argv, combinedopt);
10509 case CAM_CMD_DEVTYPE:
10510 error = getdevtype(cam_dev);
10513 error = testunitready(cam_dev, task_attr, retry_count,
10516 case CAM_CMD_INQUIRY:
10517 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10518 task_attr, retry_count, timeout);
10520 case CAM_CMD_IDENTIFY:
10521 error = identify(cam_dev, retry_count, timeout);
10523 case CAM_CMD_STARTSTOP:
10524 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10525 arglist & CAM_ARG_EJECT, task_attr,
10526 retry_count, timeout);
10528 case CAM_CMD_RESCAN:
10529 error = dorescan_or_reset(argc, argv, 1);
10531 case CAM_CMD_RESET:
10532 error = dorescan_or_reset(argc, argv, 0);
10534 case CAM_CMD_READ_DEFECTS:
10535 error = readdefects(cam_dev, argc, argv, combinedopt,
10536 task_attr, retry_count, timeout);
10538 case CAM_CMD_MODE_PAGE:
10539 modepage(cam_dev, argc, argv, combinedopt,
10540 task_attr, retry_count, timeout);
10542 case CAM_CMD_SCSI_CMD:
10543 error = scsicmd(cam_dev, argc, argv, combinedopt,
10544 task_attr, retry_count, timeout);
10546 case CAM_CMD_MMCSD_CMD:
10547 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10548 retry_count, timeout);
10550 case CAM_CMD_SMP_CMD:
10551 error = smpcmd(cam_dev, argc, argv, combinedopt,
10552 retry_count, timeout);
10554 case CAM_CMD_SMP_RG:
10555 error = smpreportgeneral(cam_dev, argc, argv,
10556 combinedopt, retry_count,
10559 case CAM_CMD_SMP_PC:
10560 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10561 retry_count, timeout);
10563 case CAM_CMD_SMP_PHYLIST:
10564 error = smpphylist(cam_dev, argc, argv, combinedopt,
10565 retry_count, timeout);
10567 case CAM_CMD_SMP_MANINFO:
10568 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10569 retry_count, timeout);
10571 case CAM_CMD_DEBUG:
10572 error = camdebug(argc, argv, combinedopt);
10575 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10578 error = ratecontrol(cam_dev, task_attr, retry_count,
10579 timeout, argc, argv, combinedopt);
10581 case CAM_CMD_FORMAT:
10582 error = scsiformat(cam_dev, argc, argv,
10583 combinedopt, task_attr, retry_count,
10586 case CAM_CMD_REPORTLUNS:
10587 error = scsireportluns(cam_dev, argc, argv,
10588 combinedopt, task_attr,
10589 retry_count, timeout);
10591 case CAM_CMD_READCAP:
10592 error = scsireadcapacity(cam_dev, argc, argv,
10593 combinedopt, task_attr,
10594 retry_count, timeout);
10597 case CAM_CMD_STANDBY:
10598 case CAM_CMD_SLEEP:
10599 case CAM_CMD_POWER_MODE:
10600 error = atapm(cam_dev, argc, argv,
10601 combinedopt, retry_count, timeout);
10605 error = ataaxm(cam_dev, argc, argv,
10606 combinedopt, retry_count, timeout);
10608 case CAM_CMD_SECURITY:
10609 error = atasecurity(cam_dev, retry_count, timeout,
10610 argc, argv, combinedopt);
10612 case CAM_CMD_DOWNLOAD_FW:
10613 error = fwdownload(cam_dev, argc, argv, combinedopt,
10614 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10617 case CAM_CMD_SANITIZE:
10618 error = sanitize(cam_dev, argc, argv, combinedopt, task_attr,
10619 retry_count, timeout);
10621 case CAM_CMD_PERSIST:
10622 error = scsipersist(cam_dev, argc, argv, combinedopt,
10623 task_attr, retry_count, timeout,
10624 arglist & CAM_ARG_VERBOSE,
10625 arglist & CAM_ARG_ERR_RECOVER);
10627 case CAM_CMD_ATTRIB:
10628 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10629 task_attr, retry_count, timeout,
10630 arglist & CAM_ARG_VERBOSE,
10631 arglist & CAM_ARG_ERR_RECOVER);
10633 case CAM_CMD_OPCODES:
10634 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10635 task_attr, retry_count, timeout,
10636 arglist & CAM_ARG_VERBOSE);
10638 case CAM_CMD_REPROBE:
10639 error = reprobe(cam_dev);
10642 error = zone(cam_dev, argc, argv, combinedopt,
10643 task_attr, retry_count, timeout,
10644 arglist & CAM_ARG_VERBOSE);
10647 error = epc(cam_dev, argc, argv, combinedopt,
10648 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10650 case CAM_CMD_TIMESTAMP:
10651 error = timestamp(cam_dev, argc, argv, combinedopt,
10652 task_attr, retry_count, timeout,
10653 arglist & CAM_ARG_VERBOSE);
10655 case CAM_CMD_USAGE:
10664 if (cam_dev != NULL)
10665 cam_close_device(cam_dev);