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_res_pass16 {
157 u_int16_t reserved[5];
160 u_int8_t sector_count_exp;
161 u_int8_t sector_count;
162 u_int8_t lba_low_exp;
164 u_int8_t lba_mid_exp;
166 u_int8_t lba_high_exp;
172 struct ata_set_max_pwd
175 u_int8_t password[32];
176 u_int16_t reserved2[239];
179 static struct scsi_nv task_attrs[] = {
180 { "simple", MSG_SIMPLE_Q_TAG },
181 { "head", MSG_HEAD_OF_Q_TAG },
182 { "ordered", MSG_ORDERED_Q_TAG },
183 { "iwr", MSG_IGN_WIDE_RESIDUE },
184 { "aca", MSG_ACA_TASK }
187 static const char scsicmd_opts[] = "a:c:dfi:o:r";
188 static const char readdefect_opts[] = "f:GPqsS:X";
189 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
190 static const char smprg_opts[] = "l";
191 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
192 static const char smpphylist_opts[] = "lq";
195 static struct camcontrol_opts option_table[] = {
196 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
197 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
198 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
199 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
200 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
201 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
202 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
203 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
204 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHlNqs"},
205 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
206 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
207 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
208 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
209 {"mmcsdcmd", CAM_CMD_MMCSD_CMD, CAM_ARG_NONE, "c:a:f:Wb:l:41S:I"},
210 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
211 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
212 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
213 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
214 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
215 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
216 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
217 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
218 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
219 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
220 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
221 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
222 {"devtype", CAM_CMD_DEVTYPE, CAM_ARG_NONE, ""},
223 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
224 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "6bdelm:DLP:"},
225 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
226 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
227 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
228 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
229 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
230 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
231 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
232 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
233 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
234 {"powermode", CAM_CMD_POWER_MODE, CAM_ARG_NONE, ""},
235 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
236 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
237 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
238 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
239 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
240 {"ama", CAM_CMD_AMA, CAM_ARG_NONE, "fqs:"},
241 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
242 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
243 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
244 {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
245 {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
246 {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
247 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
248 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
249 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
254 struct device_match_result dev_match;
256 struct periph_match_result *periph_matches;
257 struct scsi_vpd_device_id *device_id;
259 STAILQ_ENTRY(cam_devitem) links;
263 STAILQ_HEAD(, cam_devitem) dev_queue;
267 static cam_cmdmask cmdlist;
268 static cam_argmask arglist;
270 static const char *devtype_names[] = {
280 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
281 uint32_t *cmdnum, cam_argmask *argnum,
282 const char **subopt);
283 static int getdevlist(struct cam_device *device);
284 static int getdevtree(int argc, char **argv, char *combinedopt);
285 static int getdevtype(struct cam_device *device);
286 static int print_dev_scsi(struct device_match_result *dev_result, char *tmpstr);
287 static int print_dev_ata(struct device_match_result *dev_result, char *tmpstr);
288 static int print_dev_semb(struct device_match_result *dev_result, char *tmpstr);
289 static int print_dev_mmcsd(struct device_match_result *dev_result,
292 static int print_dev_nvme(struct device_match_result *dev_result, char *tmpstr);
294 static int testunitready(struct cam_device *device, int task_attr,
295 int retry_count, int timeout, int quiet);
296 static int scsistart(struct cam_device *device, int startstop, int loadeject,
297 int task_attr, int retry_count, int timeout);
298 static int scsiinquiry(struct cam_device *device, int task_attr,
299 int retry_count, int timeout);
300 static int scsiserial(struct cam_device *device, int task_attr,
301 int retry_count, int timeout);
302 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
303 lun_id_t *lun, cam_argmask *arglst);
304 static int reprobe(struct cam_device *device);
305 static int dorescan_or_reset(int argc, char **argv, int rescan);
306 static int rescan_or_reset_bus(path_id_t bus, int rescan);
307 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
308 lun_id_t lun, int scan);
309 static int readdefects(struct cam_device *device, int argc, char **argv,
310 char *combinedopt, int task_attr, int retry_count,
312 static void modepage(struct cam_device *device, int argc, char **argv,
313 char *combinedopt, int task_attr, int retry_count,
315 static int scsicmd(struct cam_device *device, int argc, char **argv,
316 char *combinedopt, int task_attr, int retry_count,
318 static int smpcmd(struct cam_device *device, int argc, char **argv,
319 char *combinedopt, int retry_count, int timeout);
320 static int mmcsdcmd(struct cam_device *device, int argc, char **argv,
321 char *combinedopt, int retry_count, int timeout);
322 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
323 char *combinedopt, int retry_count, int timeout);
324 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
325 char *combinedopt, int retry_count, int timeout);
326 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
327 char *combinedopt, int retry_count, int timeout);
328 static int getdevid(struct cam_devitem *item);
329 static int buildbusdevlist(struct cam_devlist *devlist);
330 static void freebusdevlist(struct cam_devlist *devlist);
331 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
333 static int smpphylist(struct cam_device *device, int argc, char **argv,
334 char *combinedopt, int retry_count, int timeout);
335 static int tagcontrol(struct cam_device *device, int argc, char **argv,
337 static void cts_print(struct cam_device *device,
338 struct ccb_trans_settings *cts);
339 static void cpi_print(struct ccb_pathinq *cpi);
340 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
341 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
342 static int get_print_cts(struct cam_device *device, int user_settings,
343 int quiet, struct ccb_trans_settings *cts);
344 static int ratecontrol(struct cam_device *device, int task_attr,
345 int retry_count, int timeout, int argc, char **argv,
347 static int scsiformat(struct cam_device *device, int argc, char **argv,
348 char *combinedopt, int task_attr, int retry_count,
350 static int sanitize(struct cam_device *device, int argc, char **argv,
351 char *combinedopt, int task_attr, int retry_count,
353 static int scsireportluns(struct cam_device *device, int argc, char **argv,
354 char *combinedopt, int task_attr, int retry_count,
356 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
357 char *combinedopt, int task_attr, int retry_count,
359 static int atapm(struct cam_device *device, int argc, char **argv,
360 char *combinedopt, int retry_count, int timeout);
361 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
362 int argc, char **argv, char *combinedopt);
363 static int atahpa(struct cam_device *device, int retry_count, int timeout,
364 int argc, char **argv, char *combinedopt);
365 static int ataama(struct cam_device *device, int retry_count, int timeout,
366 int argc, char **argv, char *combinedopt);
367 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
368 int sa_set, int req_sa, uint8_t *buf,
370 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
372 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
373 char *combinedopt, int task_attr, int retry_count,
374 int timeout, int verbose);
377 #define min(a,b) (((a)<(b))?(a):(b))
380 #define max(a,b) (((a)>(b))?(a):(b))
384 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
385 cam_argmask *argnum, const char **subopt)
387 struct camcontrol_opts *opts;
390 for (opts = table; (opts != NULL) && (opts->optname != NULL);
392 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
393 *cmdnum = opts->cmdnum;
394 *argnum = opts->argnum;
395 *subopt = opts->subopt;
396 if (++num_matches > 1)
397 return (CC_OR_AMBIGUOUS);
402 return (CC_OR_FOUND);
404 return (CC_OR_NOT_FOUND);
408 getdevlist(struct cam_device *device)
414 ccb = cam_getccb(device);
416 ccb->ccb_h.func_code = XPT_GDEVLIST;
417 ccb->ccb_h.flags = CAM_DIR_NONE;
418 ccb->ccb_h.retry_count = 1;
420 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
421 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
422 if (cam_send_ccb(device, ccb) < 0) {
423 warn("error getting device list");
430 switch (ccb->cgdl.status) {
431 case CAM_GDEVLIST_MORE_DEVS:
432 strcpy(status, "MORE");
434 case CAM_GDEVLIST_LAST_DEVICE:
435 strcpy(status, "LAST");
437 case CAM_GDEVLIST_LIST_CHANGED:
438 strcpy(status, "CHANGED");
440 case CAM_GDEVLIST_ERROR:
441 strcpy(status, "ERROR");
446 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
447 ccb->cgdl.periph_name,
448 ccb->cgdl.unit_number,
449 ccb->cgdl.generation,
454 * If the list has changed, we need to start over from the
457 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
467 getdevtree(int argc, char **argv, char *combinedopt)
478 while ((c = getopt(argc, argv, combinedopt)) != -1) {
481 if ((arglist & CAM_ARG_VERBOSE) == 0)
489 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
490 warn("couldn't open %s", XPT_DEVICE);
494 bzero(&ccb, sizeof(union ccb));
496 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
497 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
498 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
500 ccb.ccb_h.func_code = XPT_DEV_MATCH;
501 bufsize = sizeof(struct dev_match_result) * 100;
502 ccb.cdm.match_buf_len = bufsize;
503 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
504 if (ccb.cdm.matches == NULL) {
505 warnx("can't malloc memory for matches");
509 ccb.cdm.num_matches = 0;
512 * We fetch all nodes, since we display most of them in the default
513 * case, and all in the verbose case.
515 ccb.cdm.num_patterns = 0;
516 ccb.cdm.pattern_buf_len = 0;
519 * We do the ioctl multiple times if necessary, in case there are
520 * more than 100 nodes in the EDT.
523 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
524 warn("error sending CAMIOCOMMAND ioctl");
529 if ((ccb.ccb_h.status != CAM_REQ_CMP)
530 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
531 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
532 warnx("got CAM error %#x, CDM error %d\n",
533 ccb.ccb_h.status, ccb.cdm.status);
538 for (i = 0; i < ccb.cdm.num_matches; i++) {
539 switch (ccb.cdm.matches[i].type) {
540 case DEV_MATCH_BUS: {
541 struct bus_match_result *bus_result;
544 * Only print the bus information if the
545 * user turns on the verbose flag.
547 if ((busonly == 0) &&
548 (arglist & CAM_ARG_VERBOSE) == 0)
552 &ccb.cdm.matches[i].result.bus_result;
555 fprintf(stdout, ")\n");
559 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
561 bus_result->dev_name,
562 bus_result->unit_number,
564 (busonly ? "" : ":"));
567 case DEV_MATCH_DEVICE: {
568 struct device_match_result *dev_result;
575 &ccb.cdm.matches[i].result.device_result;
577 if ((dev_result->flags
578 & DEV_RESULT_UNCONFIGURED)
579 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
585 if (dev_result->protocol == PROTO_SCSI) {
586 if (print_dev_scsi(dev_result,
591 } else if (dev_result->protocol == PROTO_ATA ||
592 dev_result->protocol == PROTO_SATAPM) {
593 if (print_dev_ata(dev_result,
598 } else if (dev_result->protocol == PROTO_MMCSD){
599 if (print_dev_mmcsd(dev_result,
604 } else if (dev_result->protocol == PROTO_SEMB) {
605 if (print_dev_semb(dev_result,
611 } else if (dev_result->protocol == PROTO_NVME) {
612 if (print_dev_nvme(dev_result,
619 sprintf(tmpstr, "<>");
622 fprintf(stdout, ")\n");
626 fprintf(stdout, "%-33s at scbus%d "
627 "target %d lun %jx (",
630 dev_result->target_id,
631 (uintmax_t)dev_result->target_lun);
637 case DEV_MATCH_PERIPH: {
638 struct periph_match_result *periph_result;
641 &ccb.cdm.matches[i].result.periph_result;
643 if (busonly || skip_device != 0)
647 fprintf(stdout, ",");
649 fprintf(stdout, "%s%d",
650 periph_result->periph_name,
651 periph_result->unit_number);
657 fprintf(stdout, "unknown match type\n");
662 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
663 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
666 fprintf(stdout, ")\n");
674 getdevtype(struct cam_device *cam_dev)
676 camcontrol_devtype dt;
680 * Get the device type and report it, request no I/O be done to do this.
682 error = get_device_type(cam_dev, -1, 0, 0, &dt);
683 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
684 fprintf(stdout, "illegal\n");
687 fprintf(stdout, "%s\n", devtype_names[dt]);
692 print_dev_scsi(struct device_match_result *dev_result, char *tmpstr)
694 char vendor[16], product[48], revision[16];
696 cam_strvis(vendor, dev_result->inq_data.vendor,
697 sizeof(dev_result->inq_data.vendor), sizeof(vendor));
698 cam_strvis(product, dev_result->inq_data.product,
699 sizeof(dev_result->inq_data.product), sizeof(product));
700 cam_strvis(revision, dev_result->inq_data.revision,
701 sizeof(dev_result->inq_data.revision), sizeof(revision));
702 sprintf(tmpstr, "<%s %s %s>", vendor, product, revision);
708 print_dev_ata(struct device_match_result *dev_result, char *tmpstr)
710 char product[48], revision[16];
712 cam_strvis(product, dev_result->ident_data.model,
713 sizeof(dev_result->ident_data.model), sizeof(product));
714 cam_strvis(revision, dev_result->ident_data.revision,
715 sizeof(dev_result->ident_data.revision), sizeof(revision));
716 sprintf(tmpstr, "<%s %s>", product, revision);
722 print_dev_semb(struct device_match_result *dev_result, char *tmpstr)
724 struct sep_identify_data *sid;
725 char vendor[16], product[48], revision[16], fw[5];
727 sid = (struct sep_identify_data *)&dev_result->ident_data;
728 cam_strvis(vendor, sid->vendor_id,
729 sizeof(sid->vendor_id), sizeof(vendor));
730 cam_strvis(product, sid->product_id,
731 sizeof(sid->product_id), sizeof(product));
732 cam_strvis(revision, sid->product_rev,
733 sizeof(sid->product_rev), sizeof(revision));
734 cam_strvis(fw, sid->firmware_rev,
735 sizeof(sid->firmware_rev), sizeof(fw));
736 sprintf(tmpstr, "<%s %s %s %s>", vendor, product, revision, fw);
742 print_dev_mmcsd(struct device_match_result *dev_result, char *tmpstr)
745 struct ccb_dev_advinfo *advi;
746 struct cam_device *dev;
747 struct mmc_params mmc_ident_data;
749 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
750 dev_result->target_lun, O_RDWR, NULL);
752 warnx("%s", cam_errbuf);
756 ccb = cam_getccb(dev);
758 warnx("couldn't allocate CCB");
759 cam_close_device(dev);
764 advi->ccb_h.flags = CAM_DIR_IN;
765 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
766 advi->flags = CDAI_FLAG_NONE;
767 advi->buftype = CDAI_TYPE_MMC_PARAMS;
768 advi->bufsiz = sizeof(struct mmc_params);
769 advi->buf = (uint8_t *)&mmc_ident_data;
771 if (cam_send_ccb(dev, ccb) < 0) {
772 warn("error sending XPT_DEV_ADVINFO CCB");
774 cam_close_device(dev);
778 if (strlen(mmc_ident_data.model) > 0) {
779 sprintf(tmpstr, "<%s>", mmc_ident_data.model);
781 sprintf(tmpstr, "<%s card>",
782 mmc_ident_data.card_features &
783 CARD_FEATURE_SDIO ? "SDIO" : "unknown");
787 cam_close_device(dev);
793 nvme_get_cdata(struct cam_device *dev, struct nvme_controller_data *cdata)
796 struct ccb_dev_advinfo *advi;
798 ccb = cam_getccb(dev);
800 warnx("couldn't allocate CCB");
801 cam_close_device(dev);
806 advi->ccb_h.flags = CAM_DIR_IN;
807 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
808 advi->flags = CDAI_FLAG_NONE;
809 advi->buftype = CDAI_TYPE_NVME_CNTRL;
810 advi->bufsiz = sizeof(struct nvme_controller_data);
811 advi->buf = (uint8_t *)cdata;
813 if (cam_send_ccb(dev, ccb) < 0) {
814 warn("error sending XPT_DEV_ADVINFO CCB");
816 cam_close_device(dev);
819 if (advi->ccb_h.status != CAM_REQ_CMP) {
820 warnx("got CAM error %#x", advi->ccb_h.status);
822 cam_close_device(dev);
830 print_dev_nvme(struct device_match_result *dev_result, char *tmpstr)
832 struct cam_device *dev;
833 struct nvme_controller_data cdata;
834 char vendor[64], product[64];
836 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
837 dev_result->target_lun, O_RDWR, NULL);
839 warnx("%s", cam_errbuf);
843 if (nvme_get_cdata(dev, &cdata))
846 cam_strvis(vendor, cdata.mn, sizeof(cdata.mn), sizeof(vendor));
847 cam_strvis(product, cdata.fr, sizeof(cdata.fr), sizeof(product));
848 sprintf(tmpstr, "<%s %s>", vendor, product);
850 cam_close_device(dev);
856 testunitready(struct cam_device *device, int task_attr, int retry_count,
857 int timeout, int quiet)
862 ccb = cam_getccb(device);
864 scsi_test_unit_ready(&ccb->csio,
865 /* retries */ retry_count,
867 /* tag_action */ task_attr,
868 /* sense_len */ SSD_FULL_SIZE,
869 /* timeout */ timeout ? timeout : 5000);
871 /* Disable freezing the device queue */
872 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
874 if (arglist & CAM_ARG_ERR_RECOVER)
875 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
877 if (cam_send_ccb(device, ccb) < 0) {
879 warn("error sending TEST UNIT READY command");
884 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
886 fprintf(stdout, "Unit is ready\n");
889 fprintf(stdout, "Unit is not ready\n");
892 if (arglist & CAM_ARG_VERBOSE) {
893 cam_error_print(device, ccb, CAM_ESF_ALL,
894 CAM_EPF_ALL, stderr);
904 scsistart(struct cam_device *device, int startstop, int loadeject,
905 int task_attr, int retry_count, int timeout)
910 ccb = cam_getccb(device);
913 * If we're stopping, send an ordered tag so the drive in question
914 * will finish any previously queued writes before stopping. If
915 * the device isn't capable of tagged queueing, or if tagged
916 * queueing is turned off, the tag action is a no-op. We override
917 * the default simple tag, although this also has the effect of
918 * overriding the user's wishes if he wanted to specify a simple
922 && (task_attr == MSG_SIMPLE_Q_TAG))
923 task_attr = MSG_ORDERED_Q_TAG;
925 scsi_start_stop(&ccb->csio,
926 /* retries */ retry_count,
928 /* tag_action */ task_attr,
929 /* start/stop */ startstop,
930 /* load_eject */ loadeject,
932 /* sense_len */ SSD_FULL_SIZE,
933 /* timeout */ timeout ? timeout : 120000);
935 /* Disable freezing the device queue */
936 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
938 if (arglist & CAM_ARG_ERR_RECOVER)
939 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
941 if (cam_send_ccb(device, ccb) < 0) {
942 warn("error sending START STOP UNIT command");
947 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
949 fprintf(stdout, "Unit started successfully");
951 fprintf(stdout,", Media loaded\n");
953 fprintf(stdout,"\n");
955 fprintf(stdout, "Unit stopped successfully");
957 fprintf(stdout, ", Media ejected\n");
959 fprintf(stdout, "\n");
965 "Error received from start unit command\n");
968 "Error received from stop unit command\n");
970 if (arglist & CAM_ARG_VERBOSE) {
971 cam_error_print(device, ccb, CAM_ESF_ALL,
972 CAM_EPF_ALL, stderr);
982 scsidoinquiry(struct cam_device *device, int argc, char **argv,
983 char *combinedopt, int task_attr, int retry_count, int timeout)
988 while ((c = getopt(argc, argv, combinedopt)) != -1) {
991 arglist |= CAM_ARG_GET_STDINQ;
994 arglist |= CAM_ARG_GET_XFERRATE;
997 arglist |= CAM_ARG_GET_SERIAL;
1005 * If the user didn't specify any inquiry options, he wants all of
1008 if ((arglist & CAM_ARG_INQ_MASK) == 0)
1009 arglist |= CAM_ARG_INQ_MASK;
1011 if (arglist & CAM_ARG_GET_STDINQ)
1012 error = scsiinquiry(device, task_attr, retry_count, timeout);
1017 if (arglist & CAM_ARG_GET_SERIAL)
1018 scsiserial(device, task_attr, retry_count, timeout);
1020 if (arglist & CAM_ARG_GET_XFERRATE)
1021 error = camxferrate(device);
1027 scsiinquiry(struct cam_device *device, int task_attr, int retry_count,
1031 struct scsi_inquiry_data *inq_buf;
1034 ccb = cam_getccb(device);
1037 warnx("couldn't allocate CCB");
1041 /* cam_getccb cleans up the header, caller has to zero the payload */
1042 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1044 inq_buf = (struct scsi_inquiry_data *)malloc(
1045 sizeof(struct scsi_inquiry_data));
1047 if (inq_buf == NULL) {
1049 warnx("can't malloc memory for inquiry\n");
1052 bzero(inq_buf, sizeof(*inq_buf));
1055 * Note that although the size of the inquiry buffer is the full
1056 * 256 bytes specified in the SCSI spec, we only tell the device
1057 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
1058 * two reasons for this:
1060 * - The SCSI spec says that when a length field is only 1 byte,
1061 * a value of 0 will be interpreted as 256. Therefore
1062 * scsi_inquiry() will convert an inq_len (which is passed in as
1063 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
1064 * to 0. Evidently, very few devices meet the spec in that
1065 * regard. Some devices, like many Seagate disks, take the 0 as
1066 * 0, and don't return any data. One Pioneer DVD-R drive
1067 * returns more data than the command asked for.
1069 * So, since there are numerous devices that just don't work
1070 * right with the full inquiry size, we don't send the full size.
1072 * - The second reason not to use the full inquiry data length is
1073 * that we don't need it here. The only reason we issue a
1074 * standard inquiry is to get the vendor name, device name,
1075 * and revision so scsi_print_inquiry() can print them.
1077 * If, at some point in the future, more inquiry data is needed for
1078 * some reason, this code should use a procedure similar to the
1079 * probe code. i.e., issue a short inquiry, and determine from
1080 * the additional length passed back from the device how much
1081 * inquiry data the device supports. Once the amount the device
1082 * supports is determined, issue an inquiry for that amount and no
1087 scsi_inquiry(&ccb->csio,
1088 /* retries */ retry_count,
1090 /* tag_action */ task_attr,
1091 /* inq_buf */ (u_int8_t *)inq_buf,
1092 /* inq_len */ SHORT_INQUIRY_LENGTH,
1095 /* sense_len */ SSD_FULL_SIZE,
1096 /* timeout */ timeout ? timeout : 5000);
1098 /* Disable freezing the device queue */
1099 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1101 if (arglist & CAM_ARG_ERR_RECOVER)
1102 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1104 if (cam_send_ccb(device, ccb) < 0) {
1105 warn("error sending INQUIRY command");
1110 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1113 if (arglist & CAM_ARG_VERBOSE) {
1114 cam_error_print(device, ccb, CAM_ESF_ALL,
1115 CAM_EPF_ALL, stderr);
1126 fprintf(stdout, "%s%d: ", device->device_name,
1127 device->dev_unit_num);
1128 scsi_print_inquiry(inq_buf);
1136 scsiserial(struct cam_device *device, int task_attr, int retry_count,
1140 struct scsi_vpd_unit_serial_number *serial_buf;
1141 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
1144 ccb = cam_getccb(device);
1147 warnx("couldn't allocate CCB");
1151 /* cam_getccb cleans up the header, caller has to zero the payload */
1152 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1154 serial_buf = (struct scsi_vpd_unit_serial_number *)
1155 malloc(sizeof(*serial_buf));
1157 if (serial_buf == NULL) {
1159 warnx("can't malloc memory for serial number");
1163 scsi_inquiry(&ccb->csio,
1164 /*retries*/ retry_count,
1166 /* tag_action */ task_attr,
1167 /* inq_buf */ (u_int8_t *)serial_buf,
1168 /* inq_len */ sizeof(*serial_buf),
1170 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
1171 /* sense_len */ SSD_FULL_SIZE,
1172 /* timeout */ timeout ? timeout : 5000);
1174 /* Disable freezing the device queue */
1175 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1177 if (arglist & CAM_ARG_ERR_RECOVER)
1178 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1180 if (cam_send_ccb(device, ccb) < 0) {
1181 warn("error sending INQUIRY command");
1187 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1190 if (arglist & CAM_ARG_VERBOSE) {
1191 cam_error_print(device, ccb, CAM_ESF_ALL,
1192 CAM_EPF_ALL, stderr);
1203 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1204 serial_num[serial_buf->length] = '\0';
1206 if ((arglist & CAM_ARG_GET_STDINQ)
1207 || (arglist & CAM_ARG_GET_XFERRATE))
1208 fprintf(stdout, "%s%d: Serial Number ",
1209 device->device_name, device->dev_unit_num);
1211 fprintf(stdout, "%.60s\n", serial_num);
1219 camxferrate(struct cam_device *device)
1221 struct ccb_pathinq cpi;
1223 u_int32_t speed = 0;
1228 if ((retval = get_cpi(device, &cpi)) != 0)
1231 ccb = cam_getccb(device);
1234 warnx("couldn't allocate CCB");
1238 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
1240 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1241 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1243 if (((retval = cam_send_ccb(device, ccb)) < 0)
1244 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1245 const char error_string[] = "error getting transfer settings";
1250 warnx(error_string);
1252 if (arglist & CAM_ARG_VERBOSE)
1253 cam_error_print(device, ccb, CAM_ESF_ALL,
1254 CAM_EPF_ALL, stderr);
1258 goto xferrate_bailout;
1262 speed = cpi.base_transfer_speed;
1264 if (ccb->cts.transport == XPORT_SPI) {
1265 struct ccb_trans_settings_spi *spi =
1266 &ccb->cts.xport_specific.spi;
1268 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1269 freq = scsi_calc_syncsrate(spi->sync_period);
1272 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1273 speed *= (0x01 << spi->bus_width);
1275 } else if (ccb->cts.transport == XPORT_FC) {
1276 struct ccb_trans_settings_fc *fc =
1277 &ccb->cts.xport_specific.fc;
1279 if (fc->valid & CTS_FC_VALID_SPEED)
1280 speed = fc->bitrate;
1281 } else if (ccb->cts.transport == XPORT_SAS) {
1282 struct ccb_trans_settings_sas *sas =
1283 &ccb->cts.xport_specific.sas;
1285 if (sas->valid & CTS_SAS_VALID_SPEED)
1286 speed = sas->bitrate;
1287 } else if (ccb->cts.transport == XPORT_ATA) {
1288 struct ccb_trans_settings_pata *pata =
1289 &ccb->cts.xport_specific.ata;
1291 if (pata->valid & CTS_ATA_VALID_MODE)
1292 speed = ata_mode2speed(pata->mode);
1293 } else if (ccb->cts.transport == XPORT_SATA) {
1294 struct ccb_trans_settings_sata *sata =
1295 &ccb->cts.xport_specific.sata;
1297 if (sata->valid & CTS_SATA_VALID_REVISION)
1298 speed = ata_revision2speed(sata->revision);
1303 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1304 device->device_name, device->dev_unit_num,
1307 fprintf(stdout, "%s%d: %dKB/s transfers",
1308 device->device_name, device->dev_unit_num,
1312 if (ccb->cts.transport == XPORT_SPI) {
1313 struct ccb_trans_settings_spi *spi =
1314 &ccb->cts.xport_specific.spi;
1316 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1317 && (spi->sync_offset != 0))
1318 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1319 freq % 1000, spi->sync_offset);
1321 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1322 && (spi->bus_width > 0)) {
1323 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1324 && (spi->sync_offset != 0)) {
1325 fprintf(stdout, ", ");
1327 fprintf(stdout, " (");
1329 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1330 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1331 && (spi->sync_offset != 0)) {
1332 fprintf(stdout, ")");
1334 } else if (ccb->cts.transport == XPORT_ATA) {
1335 struct ccb_trans_settings_pata *pata =
1336 &ccb->cts.xport_specific.ata;
1339 if (pata->valid & CTS_ATA_VALID_MODE)
1340 printf("%s, ", ata_mode2string(pata->mode));
1341 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1342 printf("ATAPI %dbytes, ", pata->atapi);
1343 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1344 printf("PIO %dbytes", pata->bytecount);
1346 } else if (ccb->cts.transport == XPORT_SATA) {
1347 struct ccb_trans_settings_sata *sata =
1348 &ccb->cts.xport_specific.sata;
1351 if (sata->valid & CTS_SATA_VALID_REVISION)
1352 printf("SATA %d.x, ", sata->revision);
1355 if (sata->valid & CTS_SATA_VALID_MODE)
1356 printf("%s, ", ata_mode2string(sata->mode));
1357 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1358 printf("ATAPI %dbytes, ", sata->atapi);
1359 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1360 printf("PIO %dbytes", sata->bytecount);
1364 if (ccb->cts.protocol == PROTO_SCSI) {
1365 struct ccb_trans_settings_scsi *scsi =
1366 &ccb->cts.proto_specific.scsi;
1367 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1368 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1369 fprintf(stdout, ", Command Queueing Enabled");
1374 fprintf(stdout, "\n");
1384 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1386 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1387 ((u_int32_t)parm->lba_size_2 << 16);
1389 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1390 ((u_int64_t)parm->lba_size48_2 << 16) |
1391 ((u_int64_t)parm->lba_size48_3 << 32) |
1392 ((u_int64_t)parm->lba_size48_4 << 48);
1396 "Support Enabled Value\n");
1399 printf("Host Protected Area (HPA) ");
1400 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1401 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1402 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1405 printf("HPA - Security ");
1406 if (parm->support.command2 & ATA_SUPPORT_MAXSECURITY)
1407 printf("yes %s\n", (parm->enabled.command2 &
1408 ATA_SUPPORT_MAXSECURITY) ? "yes" : "no ");
1417 ataama_print(struct ata_params *parm, u_int64_t nativesize, int header)
1419 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1420 ((u_int32_t)parm->lba_size_2 << 16);
1422 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1423 ((u_int64_t)parm->lba_size48_2 << 16) |
1424 ((u_int64_t)parm->lba_size48_3 << 32) |
1425 ((u_int64_t)parm->lba_size48_4 << 48);
1429 "Support Enabled Value\n");
1432 printf("Accessible Max Address Config ");
1433 if (parm->support2 & ATA_SUPPORT_AMAX_ADDR) {
1434 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1435 printf("yes %s %ju/%ju\n",
1436 (nativesize > lba) ? "yes" : "no ", lba, nativesize);
1443 atasata(struct ata_params *parm)
1447 if (parm->satacapabilities != 0xffff &&
1448 parm->satacapabilities != 0x0000)
1455 atacapprint(struct ata_params *parm)
1458 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1459 ((u_int32_t)parm->lba_size_2 << 16);
1461 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1462 ((u_int64_t)parm->lba_size48_2 << 16) |
1463 ((u_int64_t)parm->lba_size48_3 << 32) |
1464 ((u_int64_t)parm->lba_size48_4 << 48);
1467 printf("protocol ");
1468 proto = (parm->config == ATA_PROTO_CFA) ? "CFA" :
1469 (parm->config & ATA_PROTO_ATAPI) ? "ATAPI" : "ATA";
1470 if (ata_version(parm->version_major) == 0) {
1471 printf("%s", proto);
1472 } else if (ata_version(parm->version_major) <= 7) {
1473 printf("%s-%d", proto,
1474 ata_version(parm->version_major));
1475 } else if (ata_version(parm->version_major) == 8) {
1476 printf("%s8-ACS", proto);
1479 ata_version(parm->version_major) - 7, proto);
1481 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1482 if (parm->satacapabilities & ATA_SATA_GEN3)
1483 printf(" SATA 3.x\n");
1484 else if (parm->satacapabilities & ATA_SATA_GEN2)
1485 printf(" SATA 2.x\n");
1486 else if (parm->satacapabilities & ATA_SATA_GEN1)
1487 printf(" SATA 1.x\n");
1493 printf("device model %.40s\n", parm->model);
1494 printf("firmware revision %.8s\n", parm->revision);
1495 printf("serial number %.20s\n", parm->serial);
1496 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1497 printf("WWN %04x%04x%04x%04x\n",
1498 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1500 printf("additional product id %.8s\n", parm->product_id);
1501 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1502 printf("media serial number %.30s\n",
1503 parm->media_serial);
1506 printf("cylinders %d\n", parm->cylinders);
1507 printf("heads %d\n", parm->heads);
1508 printf("sectors/track %d\n", parm->sectors);
1509 printf("sector size logical %u, physical %lu, offset %lu\n",
1510 ata_logical_sector_size(parm),
1511 (unsigned long)ata_physical_sector_size(parm),
1512 (unsigned long)ata_logical_sector_offset(parm));
1514 if (parm->config == ATA_PROTO_CFA ||
1515 (parm->support.command2 & ATA_SUPPORT_CFA))
1516 printf("CFA supported\n");
1518 printf("LBA%ssupported ",
1519 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1521 printf("%d sectors\n", lbasize);
1525 printf("LBA48%ssupported ",
1526 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1528 printf("%ju sectors\n", (uintmax_t)lbasize48);
1532 printf("PIO supported PIO");
1533 switch (ata_max_pmode(parm)) {
1549 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1550 printf(" w/o IORDY");
1553 printf("DMA%ssupported ",
1554 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1555 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1556 if (parm->mwdmamodes & 0xff) {
1558 if (parm->mwdmamodes & 0x04)
1560 else if (parm->mwdmamodes & 0x02)
1562 else if (parm->mwdmamodes & 0x01)
1566 if ((parm->atavalid & ATA_FLAG_88) &&
1567 (parm->udmamodes & 0xff)) {
1569 if (parm->udmamodes & 0x40)
1571 else if (parm->udmamodes & 0x20)
1573 else if (parm->udmamodes & 0x10)
1575 else if (parm->udmamodes & 0x08)
1577 else if (parm->udmamodes & 0x04)
1579 else if (parm->udmamodes & 0x02)
1581 else if (parm->udmamodes & 0x01)
1588 if (parm->media_rotation_rate == 1) {
1589 printf("media RPM non-rotating\n");
1590 } else if (parm->media_rotation_rate >= 0x0401 &&
1591 parm->media_rotation_rate <= 0xFFFE) {
1592 printf("media RPM %d\n",
1593 parm->media_rotation_rate);
1596 printf("Zoned-Device Commands ");
1597 switch (parm->support3 & ATA_SUPPORT_ZONE_MASK) {
1598 case ATA_SUPPORT_ZONE_DEV_MANAGED:
1599 printf("device managed\n");
1601 case ATA_SUPPORT_ZONE_HOST_AWARE:
1602 printf("host aware\n");
1609 "Support Enabled Value Vendor\n");
1610 printf("read ahead %s %s\n",
1611 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1612 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1613 printf("write cache %s %s\n",
1614 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1615 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1616 printf("flush cache %s %s\n",
1617 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1618 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1619 printf("overlap %s\n",
1620 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1621 printf("Tagged Command Queuing (TCQ) %s %s",
1622 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1623 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1624 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1625 printf(" %d tags\n",
1626 ATA_QUEUE_LEN(parm->queue) + 1);
1629 printf("Native Command Queuing (NCQ) ");
1630 if (atasata(parm) && (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1631 printf("yes %d tags\n",
1632 ATA_QUEUE_LEN(parm->queue) + 1);
1633 printf("NCQ Priority Information %s\n",
1634 parm->satacapabilities & ATA_SUPPORT_NCQ_PRIO ?
1636 printf("NCQ Non-Data Command %s\n",
1637 parm->satacapabilities2 & ATA_SUPPORT_NCQ_NON_DATA ?
1639 printf("NCQ Streaming %s\n",
1640 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1642 printf("Receive & Send FPDMA Queued %s\n",
1643 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1645 printf("NCQ Autosense %s\n",
1646 parm->satasupport & ATA_SUPPORT_NCQ_AUTOSENSE ?
1651 printf("SMART %s %s\n",
1652 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1653 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1654 printf("security %s %s\n",
1655 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1656 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1657 printf("power management %s %s\n",
1658 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1659 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1660 printf("microcode download %s %s\n",
1661 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1662 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1663 printf("advanced power management %s %s",
1664 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1665 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1666 if (parm->support.command2 & ATA_SUPPORT_APM) {
1667 printf(" %d/0x%02X\n",
1668 parm->apm_value & 0xff, parm->apm_value & 0xff);
1671 printf("automatic acoustic management %s %s",
1672 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1673 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1674 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1675 printf(" %d/0x%02X %d/0x%02X\n",
1676 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1677 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1678 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1679 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1682 printf("media status notification %s %s\n",
1683 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1684 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1685 printf("power-up in Standby %s %s\n",
1686 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1687 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1688 printf("write-read-verify %s %s",
1689 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1690 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1691 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1692 printf(" %d/0x%x\n",
1693 parm->wrv_mode, parm->wrv_mode);
1696 printf("unload %s %s\n",
1697 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1698 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1699 printf("general purpose logging %s %s\n",
1700 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1701 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1702 printf("free-fall %s %s\n",
1703 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1704 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1705 printf("sense data reporting %s %s\n",
1706 parm->support2 & ATA_SUPPORT_SENSE_REPORT ? "yes" : "no",
1707 parm->enabled2 & ATA_SUPPORT_SENSE_REPORT ? "yes" : "no");
1708 printf("extended power conditions %s %s\n",
1709 parm->support2 & ATA_SUPPORT_EPC ? "yes" : "no",
1710 parm->enabled2 & ATA_SUPPORT_EPC ? "yes" : "no");
1711 printf("device statistics notification %s %s\n",
1712 parm->support2 & ATA_SUPPORT_DSN ? "yes" : "no",
1713 parm->enabled2 & ATA_SUPPORT_DSN ? "yes" : "no");
1714 printf("Data Set Management (DSM/TRIM) ");
1715 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1717 printf("DSM - max 512byte blocks ");
1718 if (parm->max_dsm_blocks == 0x00)
1719 printf("yes not specified\n");
1722 parm->max_dsm_blocks);
1724 printf("DSM - deterministic read ");
1725 if (parm->support3 & ATA_SUPPORT_DRAT) {
1726 if (parm->support3 & ATA_SUPPORT_RZAT)
1727 printf("yes zeroed\n");
1729 printf("yes any value\n");
1736 printf("encrypts all user data %s\n",
1737 parm->support3 & ATA_ENCRYPTS_ALL_USER_DATA ? "yes" : "no");
1738 printf("Sanitize ");
1739 if (parm->multi & ATA_SUPPORT_SANITIZE) {
1740 printf("yes\t\t%s%s%s\n",
1741 parm->multi & ATA_SUPPORT_BLOCK_ERASE_EXT ? "block, " : "",
1742 parm->multi & ATA_SUPPORT_OVERWRITE_EXT ? "overwrite, " : "",
1743 parm->multi & ATA_SUPPORT_CRYPTO_SCRAMBLE_EXT ? "crypto" : "");
1744 printf("Sanitize - commands allowed %s\n",
1745 parm->multi & ATA_SUPPORT_SANITIZE_ALLOWED ? "yes" : "no");
1746 printf("Sanitize - antifreeze lock %s\n",
1747 parm->multi & ATA_SUPPORT_ANTIFREEZE_LOCK_EXT ? "yes" : "no");
1754 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb)
1756 struct ata_pass_16 *ata_pass_16;
1757 struct ata_cmd ata_cmd;
1759 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1760 ata_cmd.command = ata_pass_16->command;
1761 ata_cmd.control = ata_pass_16->control;
1762 ata_cmd.features = ata_pass_16->features;
1764 if (arglist & CAM_ARG_VERBOSE) {
1765 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1766 ata_op_string(&ata_cmd),
1767 ccb->csio.ccb_h.timeout);
1770 /* Disable freezing the device queue */
1771 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1773 if (arglist & CAM_ARG_ERR_RECOVER)
1774 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1776 if (cam_send_ccb(device, ccb) < 0) {
1777 warn("error sending ATA %s via pass_16", ata_op_string(&ata_cmd));
1782 * Consider any non-CAM_REQ_CMP status as error and report it here,
1783 * unless caller set AP_FLAG_CHK_COND, in which case it is reponsible.
1785 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1786 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1787 warnx("ATA %s via pass_16 failed", ata_op_string(&ata_cmd));
1788 if (arglist & CAM_ARG_VERBOSE) {
1789 cam_error_print(device, ccb, CAM_ESF_ALL,
1790 CAM_EPF_ALL, stderr);
1800 ata_cam_send(struct cam_device *device, union ccb *ccb)
1802 if (arglist & CAM_ARG_VERBOSE) {
1803 warnx("sending ATA %s with timeout of %u msecs",
1804 ata_op_string(&(ccb->ataio.cmd)),
1805 ccb->ataio.ccb_h.timeout);
1808 /* Disable freezing the device queue */
1809 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1811 if (arglist & CAM_ARG_ERR_RECOVER)
1812 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1814 if (cam_send_ccb(device, ccb) < 0) {
1815 warn("error sending ATA %s", ata_op_string(&(ccb->ataio.cmd)));
1820 * Consider any non-CAM_REQ_CMP status as error and report it here,
1821 * unless caller set AP_FLAG_CHK_COND, in which case it is reponsible.
1823 if (!(ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT) &&
1824 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1825 warnx("ATA %s failed", ata_op_string(&(ccb->ataio.cmd)));
1826 if (arglist & CAM_ARG_VERBOSE) {
1827 cam_error_print(device, ccb, CAM_ESF_ALL,
1828 CAM_EPF_ALL, stderr);
1837 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1838 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1839 u_int8_t tag_action, u_int8_t command, u_int16_t features,
1840 u_int64_t lba, u_int16_t sector_count, u_int8_t *data_ptr,
1841 u_int16_t dxfer_len, int timeout)
1843 if (data_ptr != NULL) {
1844 if (flags & CAM_DIR_OUT)
1845 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1847 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1849 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1852 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1854 scsi_ata_pass_16(&ccb->csio,
1868 /*sense_len*/SSD_FULL_SIZE,
1871 return scsi_cam_pass_16_send(device, ccb);
1875 ata_try_pass_16(struct cam_device *device)
1877 struct ccb_pathinq cpi;
1879 if (get_cpi(device, &cpi) != 0) {
1880 warnx("couldn't get CPI");
1884 if (cpi.protocol == PROTO_SCSI) {
1885 /* possibly compatible with pass_16 */
1889 /* likely not compatible with pass_16 */
1894 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1895 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1896 u_int8_t tag_action, u_int8_t command, u_int16_t features,
1897 u_int64_t lba, u_int16_t sector_count, u_int8_t *data_ptr,
1898 u_int16_t dxfer_len, int timeout, int force48bit)
1902 retval = ata_try_pass_16(device);
1907 return (ata_do_pass_16(device, ccb, retries, flags, protocol,
1908 ata_flags, tag_action, command, features,
1909 lba, sector_count, data_ptr, dxfer_len,
1913 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1914 cam_fill_ataio(&ccb->ataio,
1923 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1924 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1926 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1928 if (ata_flags & AP_FLAG_CHK_COND)
1929 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1931 return ata_cam_send(device, ccb);
1935 dump_data(uint16_t *ptr, uint32_t len)
1939 for (i = 0; i < len / 2; i++) {
1941 printf(" %3d: ", i);
1942 printf("%04hx ", ptr[i]);
1951 atahpa_proc_resp(struct cam_device *device, union ccb *ccb, u_int64_t *hpasize)
1953 uint8_t error = 0, ata_device = 0, status = 0;
1958 retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
1961 if (arglist & CAM_ARG_VERBOSE) {
1962 cam_error_print(device, ccb, CAM_ESF_ALL,
1963 CAM_EPF_ALL, stderr);
1965 warnx("Can't get ATA command status");
1969 if (status & ATA_STATUS_ERROR) {
1970 if (arglist & CAM_ARG_VERBOSE) {
1971 cam_error_print(device, ccb, CAM_ESF_ALL,
1972 CAM_EPF_ALL, stderr);
1975 if (error & ATA_ERROR_ID_NOT_FOUND) {
1976 warnx("Max address has already been set since "
1977 "last power-on or hardware reset");
1978 } else if (hpasize == NULL)
1979 warnx("Command failed with ATA error");
1984 if (hpasize != NULL) {
1985 if (retval == 2 || retval == 6)
1994 ata_read_native_max(struct cam_device *device, int retry_count,
1995 u_int32_t timeout, union ccb *ccb,
1996 struct ata_params *parm, u_int64_t *hpasize)
2002 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
2003 protocol = AP_PROTO_NON_DATA;
2006 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
2007 protocol |= AP_EXTEND;
2009 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
2012 error = ata_do_cmd(device,
2015 /*flags*/CAM_DIR_NONE,
2016 /*protocol*/protocol,
2017 /*ata_flags*/AP_FLAG_CHK_COND,
2018 /*tag_action*/MSG_SIMPLE_Q_TAG,
2025 timeout ? timeout : 5000,
2031 return atahpa_proc_resp(device, ccb, hpasize);
2035 atahpa_set_max(struct cam_device *device, int retry_count,
2036 u_int32_t timeout, union ccb *ccb,
2037 int is48bit, u_int64_t maxsize, int persist)
2043 protocol = AP_PROTO_NON_DATA;
2046 cmd = ATA_SET_MAX_ADDRESS48;
2047 protocol |= AP_EXTEND;
2049 cmd = ATA_SET_MAX_ADDRESS;
2052 /* lba's are zero indexed so the max lba is requested max - 1 */
2056 error = ata_do_cmd(device,
2059 /*flags*/CAM_DIR_NONE,
2060 /*protocol*/protocol,
2061 /*ata_flags*/AP_FLAG_CHK_COND,
2062 /*tag_action*/MSG_SIMPLE_Q_TAG,
2064 /*features*/ATA_HPA_FEAT_MAX_ADDR,
2066 /*sector_count*/persist,
2069 timeout ? timeout : 1000,
2075 return atahpa_proc_resp(device, ccb, NULL);
2079 atahpa_password(struct cam_device *device, int retry_count,
2080 u_int32_t timeout, union ccb *ccb,
2081 int is48bit, struct ata_set_max_pwd *pwd)
2086 protocol = AP_PROTO_PIO_OUT;
2087 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2089 return (ata_do_cmd(device,
2092 /*flags*/CAM_DIR_OUT,
2093 /*protocol*/protocol,
2094 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2095 AP_FLAG_TLEN_SECT_CNT,
2096 /*tag_action*/MSG_SIMPLE_Q_TAG,
2098 /*features*/ATA_HPA_FEAT_SET_PWD,
2100 /*sector_count*/sizeof(*pwd) / 512,
2101 /*data_ptr*/(u_int8_t*)pwd,
2102 /*dxfer_len*/sizeof(*pwd),
2103 timeout ? timeout : 1000,
2108 atahpa_lock(struct cam_device *device, int retry_count,
2109 u_int32_t timeout, union ccb *ccb, int is48bit)
2114 protocol = AP_PROTO_NON_DATA;
2115 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2117 return (ata_do_cmd(device,
2120 /*flags*/CAM_DIR_NONE,
2121 /*protocol*/protocol,
2123 /*tag_action*/MSG_SIMPLE_Q_TAG,
2125 /*features*/ATA_HPA_FEAT_LOCK,
2130 timeout ? timeout : 1000,
2135 atahpa_unlock(struct cam_device *device, int retry_count,
2136 u_int32_t timeout, union ccb *ccb,
2137 int is48bit, struct ata_set_max_pwd *pwd)
2142 protocol = AP_PROTO_PIO_OUT;
2143 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2145 return (ata_do_cmd(device,
2148 /*flags*/CAM_DIR_OUT,
2149 /*protocol*/protocol,
2150 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2151 AP_FLAG_TLEN_SECT_CNT,
2152 /*tag_action*/MSG_SIMPLE_Q_TAG,
2154 /*features*/ATA_HPA_FEAT_UNLOCK,
2156 /*sector_count*/sizeof(*pwd) / 512,
2157 /*data_ptr*/(u_int8_t*)pwd,
2158 /*dxfer_len*/sizeof(*pwd),
2159 timeout ? timeout : 1000,
2164 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2165 u_int32_t timeout, union ccb *ccb, int is48bit)
2170 protocol = AP_PROTO_NON_DATA;
2171 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2173 return (ata_do_cmd(device,
2176 /*flags*/CAM_DIR_NONE,
2177 /*protocol*/protocol,
2179 /*tag_action*/MSG_SIMPLE_Q_TAG,
2181 /*features*/ATA_HPA_FEAT_FREEZE,
2186 timeout ? timeout : 1000,
2191 ata_get_native_max(struct cam_device *device, int retry_count,
2192 u_int32_t timeout, union ccb *ccb,
2193 u_int64_t *nativesize)
2197 error = ata_do_cmd(device,
2200 /*flags*/CAM_DIR_NONE,
2201 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2202 /*ata_flags*/AP_FLAG_CHK_COND,
2203 /*tag_action*/MSG_SIMPLE_Q_TAG,
2204 /*command*/ATA_AMAX_ADDR,
2205 /*features*/ATA_AMAX_ADDR_GET,
2210 timeout ? timeout : 30 * 1000,
2216 return atahpa_proc_resp(device, ccb, nativesize);
2220 ataama_set(struct cam_device *device, int retry_count,
2221 u_int32_t timeout, union ccb *ccb, u_int64_t maxsize)
2225 /* lba's are zero indexed so the max lba is requested max - 1 */
2229 error = ata_do_cmd(device,
2232 /*flags*/CAM_DIR_NONE,
2233 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2234 /*ata_flags*/AP_FLAG_CHK_COND,
2235 /*tag_action*/MSG_SIMPLE_Q_TAG,
2236 /*command*/ATA_AMAX_ADDR,
2237 /*features*/ATA_AMAX_ADDR_SET,
2242 timeout ? timeout : 30 * 1000,
2248 return atahpa_proc_resp(device, ccb, NULL);
2252 ataama_freeze(struct cam_device *device, int retry_count,
2253 u_int32_t timeout, union ccb *ccb)
2256 return (ata_do_cmd(device,
2259 /*flags*/CAM_DIR_NONE,
2260 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2262 /*tag_action*/MSG_SIMPLE_Q_TAG,
2263 /*command*/ATA_AMAX_ADDR,
2264 /*features*/ATA_AMAX_ADDR_FREEZE,
2269 timeout ? timeout : 30 * 1000,
2274 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2275 union ccb *ccb, struct ata_params** ident_bufp)
2277 struct ata_params *ident_buf;
2278 struct ccb_pathinq cpi;
2279 struct ccb_getdev cgd;
2282 u_int8_t command, retry_command;
2284 if (get_cpi(device, &cpi) != 0) {
2285 warnx("couldn't get CPI");
2289 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2290 if (cpi.protocol == PROTO_ATA) {
2291 if (get_cgd(device, &cgd) != 0) {
2292 warnx("couldn't get CGD");
2296 command = (cgd.protocol == PROTO_ATA) ?
2297 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2300 /* We don't know which for sure so try both */
2301 command = ATA_ATA_IDENTIFY;
2302 retry_command = ATA_ATAPI_IDENTIFY;
2305 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2307 warnx("can't calloc memory for identify\n");
2312 error = ata_do_cmd(device,
2314 /*retries*/retry_count,
2315 /*flags*/CAM_DIR_IN,
2316 /*protocol*/AP_PROTO_PIO_IN,
2317 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2318 AP_FLAG_TLEN_SECT_CNT,
2319 /*tag_action*/MSG_SIMPLE_Q_TAG,
2323 /*sector_count*/sizeof(struct ata_params) / 512,
2324 /*data_ptr*/(u_int8_t *)ptr,
2325 /*dxfer_len*/sizeof(struct ata_params),
2326 /*timeout*/timeout ? timeout : 30 * 1000,
2330 if (retry_command != 0) {
2331 command = retry_command;
2339 ident_buf = (struct ata_params *)ptr;
2340 ata_param_fixup(ident_buf);
2343 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2348 /* check for invalid (all zero) response */
2350 warnx("Invalid identify response detected");
2355 *ident_bufp = ident_buf;
2362 ataidentify(struct cam_device *device, int retry_count, int timeout)
2365 struct ata_params *ident_buf;
2366 u_int64_t hpasize = 0, nativesize = 0;
2368 if ((ccb = cam_getccb(device)) == NULL) {
2369 warnx("couldn't allocate CCB");
2373 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2378 if (arglist & CAM_ARG_VERBOSE) {
2379 printf("%s%d: Raw identify data:\n",
2380 device->device_name, device->dev_unit_num);
2381 dump_data((void*)ident_buf, sizeof(struct ata_params));
2384 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2385 ata_read_native_max(device, retry_count, timeout, ccb,
2386 ident_buf, &hpasize);
2388 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR) {
2389 ata_get_native_max(device, retry_count, timeout, ccb,
2393 printf("%s%d: ", device->device_name, device->dev_unit_num);
2394 ata_print_ident(ident_buf);
2395 camxferrate(device);
2396 atacapprint(ident_buf);
2397 atahpa_print(ident_buf, hpasize, 0);
2398 ataama_print(ident_buf, nativesize, 0);
2408 nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused)
2410 struct nvme_controller_data cdata;
2412 if (nvme_get_cdata(device, &cdata))
2414 nvme_print_controller(&cdata);
2421 identify(struct cam_device *device, int retry_count, int timeout)
2424 struct ccb_pathinq cpi;
2426 if (get_cpi(device, &cpi) != 0) {
2427 warnx("couldn't get CPI");
2431 if (cpi.protocol == PROTO_NVME) {
2432 return (nvmeidentify(device, retry_count, timeout));
2435 return (ataidentify(device, retry_count, timeout));
2440 ATA_SECURITY_ACTION_PRINT,
2441 ATA_SECURITY_ACTION_FREEZE,
2442 ATA_SECURITY_ACTION_UNLOCK,
2443 ATA_SECURITY_ACTION_DISABLE,
2444 ATA_SECURITY_ACTION_ERASE,
2445 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2446 ATA_SECURITY_ACTION_SET_PASSWORD
2450 atasecurity_print_time(u_int16_t tw)
2454 printf("unspecified");
2456 printf("> 508 min");
2458 printf("%i min", 2 * tw);
2462 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2466 return 2 * 3600 * 1000; /* default: two hours */
2467 else if (timeout > 255)
2468 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2470 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2475 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2479 bzero(&cmd, sizeof(cmd));
2480 cmd.command = command;
2481 printf("Issuing %s", ata_op_string(&cmd));
2484 char pass[sizeof(pwd->password)+1];
2486 /* pwd->password may not be null terminated */
2487 pass[sizeof(pwd->password)] = '\0';
2488 strncpy(pass, pwd->password, sizeof(pwd->password));
2489 printf(" password='%s', user='%s'",
2491 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2494 if (command == ATA_SECURITY_SET_PASSWORD) {
2495 printf(", mode='%s'",
2496 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2497 "maximum" : "high");
2505 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2506 int retry_count, u_int32_t timeout, int quiet)
2510 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2512 return ata_do_cmd(device,
2515 /*flags*/CAM_DIR_NONE,
2516 /*protocol*/AP_PROTO_NON_DATA,
2518 /*tag_action*/MSG_SIMPLE_Q_TAG,
2519 /*command*/ATA_SECURITY_FREEZE_LOCK,
2530 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2531 int retry_count, u_int32_t timeout,
2532 struct ata_security_password *pwd, int quiet)
2536 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2538 return ata_do_cmd(device,
2541 /*flags*/CAM_DIR_OUT,
2542 /*protocol*/AP_PROTO_PIO_OUT,
2543 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2544 AP_FLAG_TLEN_SECT_CNT,
2545 /*tag_action*/MSG_SIMPLE_Q_TAG,
2546 /*command*/ATA_SECURITY_UNLOCK,
2549 /*sector_count*/sizeof(*pwd) / 512,
2550 /*data_ptr*/(u_int8_t *)pwd,
2551 /*dxfer_len*/sizeof(*pwd),
2557 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2558 int retry_count, u_int32_t timeout,
2559 struct ata_security_password *pwd, int quiet)
2563 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2564 return ata_do_cmd(device,
2567 /*flags*/CAM_DIR_OUT,
2568 /*protocol*/AP_PROTO_PIO_OUT,
2569 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2570 AP_FLAG_TLEN_SECT_CNT,
2571 /*tag_action*/MSG_SIMPLE_Q_TAG,
2572 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2575 /*sector_count*/sizeof(*pwd) / 512,
2576 /*data_ptr*/(u_int8_t *)pwd,
2577 /*dxfer_len*/sizeof(*pwd),
2584 atasecurity_erase_confirm(struct cam_device *device,
2585 struct ata_params* ident_buf)
2588 printf("\nYou are about to ERASE ALL DATA from the following"
2589 " device:\n%s%d,%s%d: ", device->device_name,
2590 device->dev_unit_num, device->given_dev_name,
2591 device->given_unit_number);
2592 ata_print_ident(ident_buf);
2596 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2598 if (fgets(str, sizeof(str), stdin) != NULL) {
2599 if (strncasecmp(str, "yes", 3) == 0) {
2601 } else if (strncasecmp(str, "no", 2) == 0) {
2604 printf("Please answer \"yes\" or "
2615 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2616 int retry_count, u_int32_t timeout,
2617 u_int32_t erase_timeout,
2618 struct ata_security_password *pwd, int quiet)
2623 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2625 error = ata_do_cmd(device,
2628 /*flags*/CAM_DIR_NONE,
2629 /*protocol*/AP_PROTO_NON_DATA,
2631 /*tag_action*/MSG_SIMPLE_Q_TAG,
2632 /*command*/ATA_SECURITY_ERASE_PREPARE,
2645 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2647 error = ata_do_cmd(device,
2650 /*flags*/CAM_DIR_OUT,
2651 /*protocol*/AP_PROTO_PIO_OUT,
2652 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2653 AP_FLAG_TLEN_SECT_CNT,
2654 /*tag_action*/MSG_SIMPLE_Q_TAG,
2655 /*command*/ATA_SECURITY_ERASE_UNIT,
2658 /*sector_count*/sizeof(*pwd) / 512,
2659 /*data_ptr*/(u_int8_t *)pwd,
2660 /*dxfer_len*/sizeof(*pwd),
2661 /*timeout*/erase_timeout,
2664 if (error == 0 && quiet == 0)
2665 printf("\nErase Complete\n");
2671 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2672 int retry_count, u_int32_t timeout,
2673 struct ata_security_password *pwd, int quiet)
2677 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2679 return ata_do_cmd(device,
2682 /*flags*/CAM_DIR_OUT,
2683 /*protocol*/AP_PROTO_PIO_OUT,
2684 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2685 AP_FLAG_TLEN_SECT_CNT,
2686 /*tag_action*/MSG_SIMPLE_Q_TAG,
2687 /*command*/ATA_SECURITY_SET_PASSWORD,
2690 /*sector_count*/sizeof(*pwd) / 512,
2691 /*data_ptr*/(u_int8_t *)pwd,
2692 /*dxfer_len*/sizeof(*pwd),
2698 atasecurity_print(struct ata_params *parm)
2701 printf("\nSecurity Option Value\n");
2702 if (arglist & CAM_ARG_VERBOSE) {
2703 printf("status %04x\n",
2704 parm->security_status);
2706 printf("supported %s\n",
2707 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2708 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2710 printf("enabled %s\n",
2711 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2712 printf("drive locked %s\n",
2713 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2714 printf("security config frozen %s\n",
2715 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2716 printf("count expired %s\n",
2717 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2718 printf("security level %s\n",
2719 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2720 printf("enhanced erase supported %s\n",
2721 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2722 printf("erase time ");
2723 atasecurity_print_time(parm->erase_time);
2725 printf("enhanced erase time ");
2726 atasecurity_print_time(parm->enhanced_erase_time);
2728 printf("master password rev %04x%s\n",
2729 parm->master_passwd_revision,
2730 parm->master_passwd_revision == 0x0000 ||
2731 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2735 * Validates and copies the password in optarg to the passed buffer.
2736 * If the password in optarg is the same length as the buffer then
2737 * the data will still be copied but no null termination will occur.
2740 ata_getpwd(u_int8_t *passwd, int max, char opt)
2744 len = strlen(optarg);
2746 warnx("-%c password is too long", opt);
2748 } else if (len == 0) {
2749 warnx("-%c password is missing", opt);
2751 } else if (optarg[0] == '-'){
2752 warnx("-%c password starts with '-' (generic arg?)", opt);
2754 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2755 warnx("-%c password conflicts with existing password from -%c",
2760 /* Callers pass in a buffer which does NOT need to be terminated */
2761 strncpy(passwd, optarg, max);
2768 ATA_HPA_ACTION_PRINT,
2769 ATA_HPA_ACTION_SET_MAX,
2770 ATA_HPA_ACTION_SET_PWD,
2771 ATA_HPA_ACTION_LOCK,
2772 ATA_HPA_ACTION_UNLOCK,
2773 ATA_HPA_ACTION_FREEZE_LOCK
2777 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2778 u_int64_t maxsize, int persist)
2780 printf("\nYou are about to configure HPA to limit the user accessible\n"
2781 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2782 persist ? "persistently" : "temporarily",
2783 device->device_name, device->dev_unit_num,
2784 device->given_dev_name, device->given_unit_number);
2785 ata_print_ident(ident_buf);
2789 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2791 if (NULL != fgets(str, sizeof(str), stdin)) {
2792 if (0 == strncasecmp(str, "yes", 3)) {
2794 } else if (0 == strncasecmp(str, "no", 2)) {
2797 printf("Please answer \"yes\" or "
2808 atahpa(struct cam_device *device, int retry_count, int timeout,
2809 int argc, char **argv, char *combinedopt)
2812 struct ata_params *ident_buf;
2813 struct ccb_getdev cgd;
2814 struct ata_set_max_pwd pwd;
2815 int error, confirm, quiet, c, action, actions, persist;
2816 int security, is48bit, pwdsize;
2817 u_int64_t hpasize, maxsize;
2826 memset(&pwd, 0, sizeof(pwd));
2828 /* default action is to print hpa information */
2829 action = ATA_HPA_ACTION_PRINT;
2830 pwdsize = sizeof(pwd.password);
2832 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2835 action = ATA_HPA_ACTION_SET_MAX;
2836 maxsize = strtoumax(optarg, NULL, 0);
2841 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2843 action = ATA_HPA_ACTION_SET_PWD;
2849 action = ATA_HPA_ACTION_LOCK;
2855 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2857 action = ATA_HPA_ACTION_UNLOCK;
2863 action = ATA_HPA_ACTION_FREEZE_LOCK;
2883 warnx("too many hpa actions specified");
2887 if (get_cgd(device, &cgd) != 0) {
2888 warnx("couldn't get CGD");
2892 ccb = cam_getccb(device);
2894 warnx("couldn't allocate CCB");
2898 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2905 printf("%s%d: ", device->device_name, device->dev_unit_num);
2906 ata_print_ident(ident_buf);
2907 camxferrate(device);
2910 if (action == ATA_HPA_ACTION_PRINT) {
2912 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)
2913 ata_read_native_max(device, retry_count, timeout, ccb,
2914 ident_buf, &hpasize);
2915 atahpa_print(ident_buf, hpasize, 1);
2922 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2923 warnx("HPA is not supported by this device");
2929 if (security && !(ident_buf->support.command2 & ATA_SUPPORT_MAXSECURITY)) {
2930 warnx("HPA Security is not supported by this device");
2936 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2939 * The ATA spec requires:
2940 * 1. Read native max addr is called directly before set max addr
2941 * 2. Read native max addr is NOT called before any other set max call
2944 case ATA_HPA_ACTION_SET_MAX:
2946 atahpa_set_confirm(device, ident_buf, maxsize,
2953 error = ata_read_native_max(device, retry_count, timeout,
2954 ccb, ident_buf, &hpasize);
2956 error = atahpa_set_max(device, retry_count, timeout,
2957 ccb, is48bit, maxsize, persist);
2960 /* redo identify to get new values */
2961 error = ata_do_identify(device,
2962 retry_count, timeout, ccb,
2964 atahpa_print(ident_buf, hpasize, 1);
2966 /* Hint CAM to reprobe the device. */
2972 case ATA_HPA_ACTION_SET_PWD:
2973 error = atahpa_password(device, retry_count, timeout,
2974 ccb, is48bit, &pwd);
2975 if (error == 0 && quiet == 0)
2976 printf("HPA password has been set\n");
2979 case ATA_HPA_ACTION_LOCK:
2980 error = atahpa_lock(device, retry_count, timeout,
2982 if (error == 0 && quiet == 0)
2983 printf("HPA has been locked\n");
2986 case ATA_HPA_ACTION_UNLOCK:
2987 error = atahpa_unlock(device, retry_count, timeout,
2988 ccb, is48bit, &pwd);
2989 if (error == 0 && quiet == 0)
2990 printf("HPA has been unlocked\n");
2993 case ATA_HPA_ACTION_FREEZE_LOCK:
2994 error = atahpa_freeze_lock(device, retry_count, timeout,
2996 if (error == 0 && quiet == 0)
2997 printf("HPA has been frozen\n");
3001 errx(1, "Option currently not supported");
3011 ATA_AMA_ACTION_PRINT,
3012 ATA_AMA_ACTION_SET_MAX,
3013 ATA_AMA_ACTION_FREEZE_LOCK
3017 ataama(struct cam_device *device, int retry_count, int timeout,
3018 int argc, char **argv, char *combinedopt)
3021 struct ata_params *ident_buf;
3022 struct ccb_getdev cgd;
3023 int error, quiet, c, action, actions;
3024 u_int64_t nativesize, maxsize;
3030 /* default action is to print AMA information */
3031 action = ATA_AMA_ACTION_PRINT;
3033 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3036 action = ATA_AMA_ACTION_SET_MAX;
3037 maxsize = strtoumax(optarg, NULL, 0);
3042 action = ATA_AMA_ACTION_FREEZE_LOCK;
3053 warnx("too many AMA actions specified");
3057 if (get_cgd(device, &cgd) != 0) {
3058 warnx("couldn't get CGD");
3062 ccb = cam_getccb(device);
3064 warnx("couldn't allocate CCB");
3068 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3075 printf("%s%d: ", device->device_name, device->dev_unit_num);
3076 ata_print_ident(ident_buf);
3077 camxferrate(device);
3080 if (action == ATA_AMA_ACTION_PRINT) {
3082 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)
3083 ata_get_native_max(device, retry_count, timeout, ccb,
3085 ataama_print(ident_buf, nativesize, 1);
3092 if (!(ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)) {
3093 warnx("Accessible Max Address is not supported by this device");
3100 case ATA_AMA_ACTION_SET_MAX:
3101 error = ata_get_native_max(device, retry_count, timeout, ccb,
3104 error = ataama_set(device, retry_count, timeout,
3108 /* redo identify to get new values */
3109 error = ata_do_identify(device,
3110 retry_count, timeout, ccb,
3112 ataama_print(ident_buf, nativesize, 1);
3114 /* Hint CAM to reprobe the device. */
3120 case ATA_AMA_ACTION_FREEZE_LOCK:
3121 error = ataama_freeze(device, retry_count, timeout,
3123 if (error == 0 && quiet == 0)
3124 printf("Accessible Max Address has been frozen\n");
3128 errx(1, "Option currently not supported");
3138 atasecurity(struct cam_device *device, int retry_count, int timeout,
3139 int argc, char **argv, char *combinedopt)
3142 struct ata_params *ident_buf;
3143 int error, confirm, quiet, c, action, actions, setpwd;
3144 int security_enabled, erase_timeout, pwdsize;
3145 struct ata_security_password pwd;
3153 memset(&pwd, 0, sizeof(pwd));
3155 /* default action is to print security information */
3156 action = ATA_SECURITY_ACTION_PRINT;
3158 /* user is master by default as its safer that way */
3159 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3160 pwdsize = sizeof(pwd.password);
3162 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3165 action = ATA_SECURITY_ACTION_FREEZE;
3170 if (strcasecmp(optarg, "user") == 0) {
3171 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
3172 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
3173 } else if (strcasecmp(optarg, "master") == 0) {
3174 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3175 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
3177 warnx("-U argument '%s' is invalid (must be "
3178 "'user' or 'master')", optarg);
3184 if (strcasecmp(optarg, "high") == 0) {
3185 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3186 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3187 } else if (strcasecmp(optarg, "maximum") == 0) {
3188 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3189 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3191 warnx("-l argument '%s' is unknown (must be "
3192 "'high' or 'maximum')", optarg);
3198 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3200 action = ATA_SECURITY_ACTION_UNLOCK;
3205 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3207 action = ATA_SECURITY_ACTION_DISABLE;
3212 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3214 action = ATA_SECURITY_ACTION_ERASE;
3219 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3221 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3222 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3227 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3230 if (action == ATA_SECURITY_ACTION_PRINT)
3231 action = ATA_SECURITY_ACTION_SET_PASSWORD;
3233 * Don't increment action as this can be combined
3234 * with other actions.
3247 erase_timeout = atoi(optarg) * 1000;
3253 warnx("too many security actions specified");
3257 if ((ccb = cam_getccb(device)) == NULL) {
3258 warnx("couldn't allocate CCB");
3262 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3269 printf("%s%d: ", device->device_name, device->dev_unit_num);
3270 ata_print_ident(ident_buf);
3271 camxferrate(device);
3274 if (action == ATA_SECURITY_ACTION_PRINT) {
3275 atasecurity_print(ident_buf);
3281 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3282 warnx("Security not supported");
3288 /* default timeout 15 seconds the same as linux hdparm */
3289 timeout = timeout ? timeout : 15 * 1000;
3291 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3293 /* first set the password if requested */
3295 /* confirm we can erase before setting the password if erasing */
3297 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3298 action == ATA_SECURITY_ACTION_ERASE) &&
3299 atasecurity_erase_confirm(device, ident_buf) == 0) {
3305 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3306 pwd.revision = ident_buf->master_passwd_revision;
3307 if (pwd.revision != 0 && pwd.revision != 0xfff &&
3308 --pwd.revision == 0) {
3309 pwd.revision = 0xfffe;
3312 error = atasecurity_set_password(device, ccb, retry_count,
3313 timeout, &pwd, quiet);
3319 security_enabled = 1;
3323 case ATA_SECURITY_ACTION_FREEZE:
3324 error = atasecurity_freeze(device, ccb, retry_count,
3328 case ATA_SECURITY_ACTION_UNLOCK:
3329 if (security_enabled) {
3330 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3331 error = atasecurity_unlock(device, ccb,
3332 retry_count, timeout, &pwd, quiet);
3334 warnx("Can't unlock, drive is not locked");
3338 warnx("Can't unlock, security is disabled");
3343 case ATA_SECURITY_ACTION_DISABLE:
3344 if (security_enabled) {
3345 /* First unlock the drive if its locked */
3346 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3347 error = atasecurity_unlock(device, ccb,
3355 error = atasecurity_disable(device,
3363 warnx("Can't disable security (already disabled)");
3368 case ATA_SECURITY_ACTION_ERASE:
3369 if (security_enabled) {
3370 if (erase_timeout == 0) {
3371 erase_timeout = atasecurity_erase_timeout_msecs(
3372 ident_buf->erase_time);
3375 error = atasecurity_erase(device, ccb, retry_count,
3376 timeout, erase_timeout, &pwd, quiet);
3378 warnx("Can't secure erase (security is disabled)");
3383 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3384 if (security_enabled) {
3385 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3386 if (erase_timeout == 0) {
3388 atasecurity_erase_timeout_msecs(
3389 ident_buf->enhanced_erase_time);
3392 error = atasecurity_erase(device, ccb,
3393 retry_count, timeout,
3394 erase_timeout, &pwd,
3397 warnx("Enhanced erase is not supported");
3401 warnx("Can't secure erase (enhanced), "
3402 "(security is disabled)");
3415 * Convert periph name into a bus, target and lun.
3417 * Returns the number of parsed components, or 0.
3420 parse_btl_name(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3421 cam_argmask *arglst)
3426 bzero(&ccb, sizeof(ccb));
3427 ccb.ccb_h.func_code = XPT_GDEVLIST;
3428 if (cam_get_device(tstr, ccb.cgdl.periph_name,
3429 sizeof(ccb.cgdl.periph_name), &ccb.cgdl.unit_number) == -1) {
3430 warnx("%s", cam_errbuf);
3435 * Attempt to get the passthrough device. This ioctl will
3436 * fail if the device name is null, if the device doesn't
3437 * exist, or if the passthrough driver isn't in the kernel.
3439 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3440 warn("Unable to open %s", XPT_DEVICE);
3443 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3444 warn("Unable to find bus:target:lun for device %s%d",
3445 ccb.cgdl.periph_name, ccb.cgdl.unit_number);
3450 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3451 const struct cam_status_entry *entry;
3453 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3454 warnx("Unable to find bus:target_lun for device %s%d, "
3455 "CAM status: %s (%#x)",
3456 ccb.cgdl.periph_name, ccb.cgdl.unit_number,
3457 entry ? entry->status_text : "Unknown",
3463 * The kernel fills in the bus/target/lun. We don't
3464 * need the passthrough device name and unit number since
3465 * we aren't going to open it.
3467 *bus = ccb.ccb_h.path_id;
3468 *target = ccb.ccb_h.target_id;
3469 *lun = ccb.ccb_h.target_lun;
3470 *arglst |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3475 * Parse out a bus, or a bus, target and lun in the following
3481 * Returns the number of parsed components, or 0.
3484 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3485 cam_argmask *arglst)
3490 *bus = CAM_BUS_WILDCARD;
3491 *target = CAM_TARGET_WILDCARD;
3492 *lun = CAM_LUN_WILDCARD;
3494 while (isspace(*tstr) && (*tstr != '\0'))
3497 if (strncasecmp(tstr, "all", strlen("all")) == 0) {
3498 arglist |= CAM_ARG_BUS;
3502 if (!isdigit(*tstr))
3503 return (parse_btl_name(tstr, bus, target, lun, arglst));
3505 tmpstr = strsep(&tstr, ":");
3506 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3507 *bus = strtol(tmpstr, &end, 0);
3510 *arglst |= CAM_ARG_BUS;
3512 tmpstr = strsep(&tstr, ":");
3513 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3514 *target = strtol(tmpstr, &end, 0);
3517 *arglst |= CAM_ARG_TARGET;
3519 tmpstr = strsep(&tstr, ":");
3520 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3521 *lun = strtoll(tmpstr, &end, 0);
3524 *arglst |= CAM_ARG_LUN;
3534 dorescan_or_reset(int argc, char **argv, int rescan)
3536 static const char must[] =
3537 "you must specify \"all\", a bus, a bus:target:lun or periph to %s";
3539 path_id_t bus = CAM_BUS_WILDCARD;
3540 target_id_t target = CAM_TARGET_WILDCARD;
3541 lun_id_t lun = CAM_LUN_WILDCARD;
3545 warnx(must, rescan? "rescan" : "reset");
3549 tstr = argv[optind];
3550 while (isspace(*tstr) && (*tstr != '\0'))
3552 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3553 arglist |= CAM_ARG_BUS;
3555 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3556 if (rv != 1 && rv != 3) {
3557 warnx(must, rescan ? "rescan" : "reset");
3562 if (arglist & CAM_ARG_LUN)
3563 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3565 error = rescan_or_reset_bus(bus, rescan);
3571 rescan_or_reset_bus(path_id_t bus, int rescan)
3573 union ccb *ccb = NULL, *matchccb = NULL;
3574 int fd = -1, retval;
3579 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3580 warnx("error opening transport layer device %s", XPT_DEVICE);
3581 warn("%s", XPT_DEVICE);
3585 ccb = malloc(sizeof(*ccb));
3587 warn("failed to allocate CCB");
3591 bzero(ccb, sizeof(*ccb));
3593 if (bus != CAM_BUS_WILDCARD) {
3594 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3595 ccb->ccb_h.path_id = bus;
3596 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3597 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3598 ccb->crcn.flags = CAM_FLAG_NONE;
3600 /* run this at a low priority */
3601 ccb->ccb_h.pinfo.priority = 5;
3603 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3604 warn("CAMIOCOMMAND ioctl failed");
3609 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3610 fprintf(stdout, "%s of bus %d was successful\n",
3611 rescan ? "Re-scan" : "Reset", bus);
3613 fprintf(stdout, "%s of bus %d returned error %#x\n",
3614 rescan ? "Re-scan" : "Reset", bus,
3615 ccb->ccb_h.status & CAM_STATUS_MASK);
3624 * The right way to handle this is to modify the xpt so that it can
3625 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3626 * that isn't implemented, so instead we enumerate the buses and
3627 * send the rescan or reset to those buses in the case where the
3628 * given bus is -1 (wildcard). We don't send a rescan or reset
3629 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3630 * no-op, sending a rescan to the xpt bus would result in a status of
3633 matchccb = malloc(sizeof(*matchccb));
3634 if (matchccb == NULL) {
3635 warn("failed to allocate CCB");
3639 bzero(matchccb, sizeof(*matchccb));
3640 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3641 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3642 bufsize = sizeof(struct dev_match_result) * 20;
3643 matchccb->cdm.match_buf_len = bufsize;
3644 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3645 if (matchccb->cdm.matches == NULL) {
3646 warnx("can't malloc memory for matches");
3650 matchccb->cdm.num_matches = 0;
3652 matchccb->cdm.num_patterns = 1;
3653 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3655 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3656 matchccb->cdm.pattern_buf_len);
3657 if (matchccb->cdm.patterns == NULL) {
3658 warnx("can't malloc memory for patterns");
3662 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3663 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3668 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3669 warn("CAMIOCOMMAND ioctl failed");
3674 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3675 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3676 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3677 warnx("got CAM error %#x, CDM error %d\n",
3678 matchccb->ccb_h.status, matchccb->cdm.status);
3683 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3684 struct bus_match_result *bus_result;
3686 /* This shouldn't happen. */
3687 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3690 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3693 * We don't want to rescan or reset the xpt bus.
3696 if (bus_result->path_id == CAM_XPT_PATH_ID)
3699 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3701 ccb->ccb_h.path_id = bus_result->path_id;
3702 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3703 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3704 ccb->crcn.flags = CAM_FLAG_NONE;
3706 /* run this at a low priority */
3707 ccb->ccb_h.pinfo.priority = 5;
3709 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3710 warn("CAMIOCOMMAND ioctl failed");
3715 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3716 fprintf(stdout, "%s of bus %d was successful\n",
3717 rescan? "Re-scan" : "Reset",
3718 bus_result->path_id);
3721 * Don't bail out just yet, maybe the other
3722 * rescan or reset commands will complete
3725 fprintf(stderr, "%s of bus %d returned error "
3726 "%#x\n", rescan? "Re-scan" : "Reset",
3727 bus_result->path_id,
3728 ccb->ccb_h.status & CAM_STATUS_MASK);
3732 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3733 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3740 if (matchccb != NULL) {
3741 free(matchccb->cdm.patterns);
3742 free(matchccb->cdm.matches);
3751 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3754 struct cam_device *device;
3759 if (bus == CAM_BUS_WILDCARD) {
3760 warnx("invalid bus number %d", bus);
3764 if (target == CAM_TARGET_WILDCARD) {
3765 warnx("invalid target number %d", target);
3769 if (lun == CAM_LUN_WILDCARD) {
3770 warnx("invalid lun number %jx", (uintmax_t)lun);
3776 bzero(&ccb, sizeof(union ccb));
3779 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3780 warnx("error opening transport layer device %s\n",
3782 warn("%s", XPT_DEVICE);
3786 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3787 if (device == NULL) {
3788 warnx("%s", cam_errbuf);
3793 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3794 ccb.ccb_h.path_id = bus;
3795 ccb.ccb_h.target_id = target;
3796 ccb.ccb_h.target_lun = lun;
3797 ccb.ccb_h.timeout = 5000;
3798 ccb.crcn.flags = CAM_FLAG_NONE;
3800 /* run this at a low priority */
3801 ccb.ccb_h.pinfo.priority = 5;
3804 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3805 warn("CAMIOCOMMAND ioctl failed");
3810 if (cam_send_ccb(device, &ccb) < 0) {
3811 warn("error sending XPT_RESET_DEV CCB");
3812 cam_close_device(device);
3820 cam_close_device(device);
3823 * An error code of CAM_BDR_SENT is normal for a BDR request.
3825 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3827 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3828 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3829 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3832 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3833 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3834 ccb.ccb_h.status & CAM_STATUS_MASK);
3840 static struct scsi_nv defect_list_type_map[] = {
3841 { "block", SRDD10_BLOCK_FORMAT },
3842 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3843 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3844 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3845 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3846 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3850 readdefects(struct cam_device *device, int argc, char **argv,
3851 char *combinedopt, int task_attr, int retry_count, int timeout)
3853 union ccb *ccb = NULL;
3854 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3855 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3856 size_t hdr_size = 0, entry_size = 0;
3859 u_int8_t *defect_list = NULL;
3860 u_int8_t list_format = 0;
3861 int list_type_set = 0;
3862 u_int32_t dlist_length = 0;
3863 u_int32_t returned_length = 0, valid_len = 0;
3864 u_int32_t num_returned = 0, num_valid = 0;
3865 u_int32_t max_possible_size = 0, hdr_max = 0;
3866 u_int32_t starting_offset = 0;
3867 u_int8_t returned_format, returned_type;
3869 int summary = 0, quiet = 0;
3871 int lists_specified = 0;
3872 int get_length = 1, first_pass = 1;
3875 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3879 scsi_nv_status status;
3882 status = scsi_get_nv(defect_list_type_map,
3883 sizeof(defect_list_type_map) /
3884 sizeof(defect_list_type_map[0]), optarg,
3885 &entry_num, SCSI_NV_FLAG_IG_CASE);
3887 if (status == SCSI_NV_FOUND) {
3888 list_format = defect_list_type_map[
3892 warnx("%s: %s %s option %s", __func__,
3893 (status == SCSI_NV_AMBIGUOUS) ?
3894 "ambiguous" : "invalid", "defect list type",
3897 goto defect_bailout;
3902 arglist |= CAM_ARG_GLIST;
3905 arglist |= CAM_ARG_PLIST;
3916 starting_offset = strtoul(optarg, &endptr, 0);
3917 if (*endptr != '\0') {
3919 warnx("invalid starting offset %s", optarg);
3920 goto defect_bailout;
3932 if (list_type_set == 0) {
3934 warnx("no defect list format specified");
3935 goto defect_bailout;
3938 if (arglist & CAM_ARG_PLIST) {
3939 list_format |= SRDD10_PLIST;
3943 if (arglist & CAM_ARG_GLIST) {
3944 list_format |= SRDD10_GLIST;
3949 * This implies a summary, and was the previous behavior.
3951 if (lists_specified == 0)
3954 ccb = cam_getccb(device);
3959 * We start off asking for just the header to determine how much
3960 * defect data is available. Some Hitachi drives return an error
3961 * if you ask for more data than the drive has. Once we know the
3962 * length, we retry the command with the returned length.
3964 if (use_12byte == 0)
3965 dlist_length = sizeof(*hdr10);
3967 dlist_length = sizeof(*hdr12);
3970 if (defect_list != NULL) {
3974 defect_list = malloc(dlist_length);
3975 if (defect_list == NULL) {
3976 warnx("can't malloc memory for defect list");
3978 goto defect_bailout;
3982 bzero(defect_list, dlist_length);
3985 * cam_getccb() zeros the CCB header only. So we need to zero the
3986 * payload portion of the ccb.
3988 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3990 scsi_read_defects(&ccb->csio,
3991 /*retries*/ retry_count,
3993 /*tag_action*/ task_attr,
3994 /*list_format*/ list_format,
3995 /*addr_desc_index*/ starting_offset,
3996 /*data_ptr*/ defect_list,
3997 /*dxfer_len*/ dlist_length,
3998 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3999 /*sense_len*/ SSD_FULL_SIZE,
4000 /*timeout*/ timeout ? timeout : 5000);
4002 /* Disable freezing the device queue */
4003 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4005 if (cam_send_ccb(device, ccb) < 0) {
4006 warn("error sending READ DEFECT DATA command");
4008 goto defect_bailout;
4011 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
4013 if (use_12byte == 0) {
4014 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
4015 hdr_size = sizeof(*hdr10);
4016 hdr_max = SRDDH10_MAX_LENGTH;
4018 if (valid_len >= hdr_size) {
4019 returned_length = scsi_2btoul(hdr10->length);
4020 returned_format = hdr10->format;
4022 returned_length = 0;
4023 returned_format = 0;
4026 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
4027 hdr_size = sizeof(*hdr12);
4028 hdr_max = SRDDH12_MAX_LENGTH;
4030 if (valid_len >= hdr_size) {
4031 returned_length = scsi_4btoul(hdr12->length);
4032 returned_format = hdr12->format;
4034 returned_length = 0;
4035 returned_format = 0;
4039 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
4040 switch (returned_type) {
4041 case SRDD10_BLOCK_FORMAT:
4042 entry_size = sizeof(struct scsi_defect_desc_block);
4044 case SRDD10_LONG_BLOCK_FORMAT:
4045 entry_size = sizeof(struct scsi_defect_desc_long_block);
4047 case SRDD10_EXT_PHYS_FORMAT:
4048 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4049 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
4051 case SRDD10_EXT_BFI_FORMAT:
4052 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4053 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
4056 warnx("Unknown defect format 0x%x\n", returned_type);
4058 goto defect_bailout;
4062 max_possible_size = (hdr_max / entry_size) * entry_size;
4063 num_returned = returned_length / entry_size;
4064 num_valid = min(returned_length, valid_len - hdr_size);
4065 num_valid /= entry_size;
4067 if (get_length != 0) {
4070 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
4071 CAM_SCSI_STATUS_ERROR) {
4072 struct scsi_sense_data *sense;
4073 int error_code, sense_key, asc, ascq;
4075 sense = &ccb->csio.sense_data;
4076 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4077 ccb->csio.sense_resid, &error_code, &sense_key,
4078 &asc, &ascq, /*show_errors*/ 1);
4081 * If the drive is reporting that it just doesn't
4082 * support the defect list format, go ahead and use
4083 * the length it reported. Otherwise, the length
4084 * may not be valid, so use the maximum.
4086 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4087 && (asc == 0x1c) && (ascq == 0x00)
4088 && (returned_length > 0)) {
4089 if ((use_12byte == 0)
4090 && (returned_length >= max_possible_size)) {
4095 dlist_length = returned_length + hdr_size;
4096 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4097 && (asc == 0x1f) && (ascq == 0x00)
4098 && (returned_length > 0)) {
4099 /* Partial defect list transfer */
4101 * Hitachi drives return this error
4102 * along with a partial defect list if they
4103 * have more defects than the 10 byte
4104 * command can support. Retry with the 12
4107 if (use_12byte == 0) {
4112 dlist_length = returned_length + hdr_size;
4113 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
4114 && (asc == 0x24) && (ascq == 0x00)) {
4115 /* Invalid field in CDB */
4117 * SBC-3 says that if the drive has more
4118 * defects than can be reported with the
4119 * 10 byte command, it should return this
4120 * error and no data. Retry with the 12
4123 if (use_12byte == 0) {
4128 dlist_length = returned_length + hdr_size;
4131 * If we got a SCSI error and no valid length,
4132 * just use the 10 byte maximum. The 12
4133 * byte maximum is too large.
4135 if (returned_length == 0)
4136 dlist_length = SRDD10_MAX_LENGTH;
4138 if ((use_12byte == 0)
4139 && (returned_length >=
4140 max_possible_size)) {
4145 dlist_length = returned_length +
4149 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4152 warnx("Error reading defect header");
4153 if (arglist & CAM_ARG_VERBOSE)
4154 cam_error_print(device, ccb, CAM_ESF_ALL,
4155 CAM_EPF_ALL, stderr);
4156 goto defect_bailout;
4158 if ((use_12byte == 0)
4159 && (returned_length >= max_possible_size)) {
4164 dlist_length = returned_length + hdr_size;
4167 fprintf(stdout, "%u", num_returned);
4169 fprintf(stdout, " defect%s",
4170 (num_returned != 1) ? "s" : "");
4172 fprintf(stdout, "\n");
4174 goto defect_bailout;
4178 * We always limit the list length to the 10-byte maximum
4179 * length (0xffff). The reason is that some controllers
4180 * can't handle larger I/Os, and we can transfer the entire
4181 * 10 byte list in one shot. For drives that support the 12
4182 * byte read defects command, we'll step through the list
4183 * by specifying a starting offset. For drives that don't
4184 * support the 12 byte command's starting offset, we'll
4185 * just display the first 64K.
4187 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4193 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4194 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4195 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4196 struct scsi_sense_data *sense;
4197 int error_code, sense_key, asc, ascq;
4199 sense = &ccb->csio.sense_data;
4200 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4201 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4202 &ascq, /*show_errors*/ 1);
4205 * According to the SCSI spec, if the disk doesn't support
4206 * the requested format, it will generally return a sense
4207 * key of RECOVERED ERROR, and an additional sense code
4208 * of "DEFECT LIST NOT FOUND". HGST drives also return
4209 * Primary/Grown defect list not found errors. So just
4210 * check for an ASC of 0x1c.
4212 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4214 const char *format_str;
4216 format_str = scsi_nv_to_str(defect_list_type_map,
4217 sizeof(defect_list_type_map) /
4218 sizeof(defect_list_type_map[0]),
4219 list_format & SRDD10_DLIST_FORMAT_MASK);
4220 warnx("requested defect format %s not available",
4221 format_str ? format_str : "unknown");
4223 format_str = scsi_nv_to_str(defect_list_type_map,
4224 sizeof(defect_list_type_map) /
4225 sizeof(defect_list_type_map[0]), returned_type);
4226 if (format_str != NULL) {
4227 warnx("Device returned %s format",
4231 warnx("Device returned unknown defect"
4232 " data format %#x", returned_type);
4233 goto defect_bailout;
4237 warnx("Error returned from read defect data command");
4238 if (arglist & CAM_ARG_VERBOSE)
4239 cam_error_print(device, ccb, CAM_ESF_ALL,
4240 CAM_EPF_ALL, stderr);
4241 goto defect_bailout;
4243 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4245 warnx("Error returned from read defect data command");
4246 if (arglist & CAM_ARG_VERBOSE)
4247 cam_error_print(device, ccb, CAM_ESF_ALL,
4248 CAM_EPF_ALL, stderr);
4249 goto defect_bailout;
4252 if (first_pass != 0) {
4253 fprintf(stderr, "Got %d defect", num_returned);
4255 if ((lists_specified == 0) || (num_returned == 0)) {
4256 fprintf(stderr, "s.\n");
4257 goto defect_bailout;
4258 } else if (num_returned == 1)
4259 fprintf(stderr, ":\n");
4261 fprintf(stderr, "s:\n");
4267 * XXX KDM I should probably clean up the printout format for the
4270 switch (returned_type) {
4271 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4272 case SRDD10_EXT_PHYS_FORMAT:
4274 struct scsi_defect_desc_phys_sector *dlist;
4276 dlist = (struct scsi_defect_desc_phys_sector *)
4277 (defect_list + hdr_size);
4279 for (i = 0; i < num_valid; i++) {
4282 sector = scsi_4btoul(dlist[i].sector);
4283 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4284 mads = (sector & SDD_EXT_PHYS_MADS) ?
4286 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4288 if (hex_format == 0)
4289 fprintf(stdout, "%d:%d:%d%s",
4290 scsi_3btoul(dlist[i].cylinder),
4292 scsi_4btoul(dlist[i].sector),
4293 mads ? " - " : "\n");
4295 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4296 scsi_3btoul(dlist[i].cylinder),
4298 scsi_4btoul(dlist[i].sector),
4299 mads ? " - " : "\n");
4302 if (num_valid < num_returned) {
4303 starting_offset += num_valid;
4308 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4309 case SRDD10_EXT_BFI_FORMAT:
4311 struct scsi_defect_desc_bytes_from_index *dlist;
4313 dlist = (struct scsi_defect_desc_bytes_from_index *)
4314 (defect_list + hdr_size);
4316 for (i = 0; i < num_valid; i++) {
4319 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4320 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4321 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4322 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4324 if (hex_format == 0)
4325 fprintf(stdout, "%d:%d:%d%s",
4326 scsi_3btoul(dlist[i].cylinder),
4328 scsi_4btoul(dlist[i].bytes_from_index),
4329 mads ? " - " : "\n");
4331 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4332 scsi_3btoul(dlist[i].cylinder),
4334 scsi_4btoul(dlist[i].bytes_from_index),
4335 mads ? " - " : "\n");
4339 if (num_valid < num_returned) {
4340 starting_offset += num_valid;
4345 case SRDDH10_BLOCK_FORMAT:
4347 struct scsi_defect_desc_block *dlist;
4349 dlist = (struct scsi_defect_desc_block *)
4350 (defect_list + hdr_size);
4352 for (i = 0; i < num_valid; i++) {
4353 if (hex_format == 0)
4354 fprintf(stdout, "%u\n",
4355 scsi_4btoul(dlist[i].address));
4357 fprintf(stdout, "0x%x\n",
4358 scsi_4btoul(dlist[i].address));
4361 if (num_valid < num_returned) {
4362 starting_offset += num_valid;
4368 case SRDD10_LONG_BLOCK_FORMAT:
4370 struct scsi_defect_desc_long_block *dlist;
4372 dlist = (struct scsi_defect_desc_long_block *)
4373 (defect_list + hdr_size);
4375 for (i = 0; i < num_valid; i++) {
4376 if (hex_format == 0)
4377 fprintf(stdout, "%ju\n",
4378 (uintmax_t)scsi_8btou64(
4381 fprintf(stdout, "0x%jx\n",
4382 (uintmax_t)scsi_8btou64(
4386 if (num_valid < num_returned) {
4387 starting_offset += num_valid;
4393 fprintf(stderr, "Unknown defect format 0x%x\n",
4400 if (defect_list != NULL)
4411 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4415 ccb = cam_getccb(device);
4422 mode_sense(struct cam_device *device, int *cdb_len, int dbd, int llbaa, int pc,
4423 int page, int subpage, int task_attr, int retry_count, int timeout,
4424 u_int8_t *data, int datalen)
4427 int error_code, sense_key, asc, ascq;
4429 ccb = cam_getccb(device);
4431 errx(1, "mode_sense: couldn't allocate CCB");
4435 * MODE SENSE(6) can't handle more then 255 bytes. If there are more,
4436 * device must return error, so we should not get trucated data.
4438 if (*cdb_len == 6 && datalen > 255)
4441 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4443 scsi_mode_sense_subpage(&ccb->csio,
4444 /* retries */ retry_count,
4446 /* tag_action */ task_attr,
4450 /* subpage */ subpage,
4451 /* param_buf */ data,
4452 /* param_len */ datalen,
4453 /* minimum_cmd_size */ *cdb_len,
4454 /* sense_len */ SSD_FULL_SIZE,
4455 /* timeout */ timeout ? timeout : 5000);
4456 if (llbaa && ccb->csio.cdb_len == 10) {
4457 struct scsi_mode_sense_10 *cdb =
4458 (struct scsi_mode_sense_10 *)ccb->csio.cdb_io.cdb_bytes;
4459 cdb->byte2 |= SMS10_LLBAA;
4462 /* Record what CDB size the above function really set. */
4463 *cdb_len = ccb->csio.cdb_len;
4465 if (arglist & CAM_ARG_ERR_RECOVER)
4466 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4468 /* Disable freezing the device queue */
4469 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4471 if (cam_send_ccb(device, ccb) < 0)
4472 err(1, "error sending mode sense command");
4474 /* In case of ILLEGEL REQUEST try to fall back to 6-byte command. */
4475 if (*cdb_len != 6 &&
4476 ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID ||
4477 (scsi_extract_sense_ccb(ccb, &error_code, &sense_key, &asc, &ascq)
4478 && sense_key == SSD_KEY_ILLEGAL_REQUEST))) {
4483 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4484 if (arglist & CAM_ARG_VERBOSE) {
4485 cam_error_print(device, ccb, CAM_ESF_ALL,
4486 CAM_EPF_ALL, stderr);
4489 cam_close_device(device);
4490 errx(1, "mode sense command returned error");
4497 mode_select(struct cam_device *device, int cdb_len, int save_pages,
4498 int task_attr, int retry_count, int timeout, u_int8_t *data, int datalen)
4503 ccb = cam_getccb(device);
4506 errx(1, "mode_select: couldn't allocate CCB");
4508 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4510 scsi_mode_select_len(&ccb->csio,
4511 /* retries */ retry_count,
4513 /* tag_action */ task_attr,
4514 /* scsi_page_fmt */ 1,
4515 /* save_pages */ save_pages,
4516 /* param_buf */ data,
4517 /* param_len */ datalen,
4518 /* minimum_cmd_size */ cdb_len,
4519 /* sense_len */ SSD_FULL_SIZE,
4520 /* timeout */ timeout ? timeout : 5000);
4522 if (arglist & CAM_ARG_ERR_RECOVER)
4523 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4525 /* Disable freezing the device queue */
4526 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4528 if (((retval = cam_send_ccb(device, ccb)) < 0)
4529 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4530 if (arglist & CAM_ARG_VERBOSE) {
4531 cam_error_print(device, ccb, CAM_ESF_ALL,
4532 CAM_EPF_ALL, stderr);
4535 cam_close_device(device);
4538 err(1, "error sending mode select command");
4540 errx(1, "error sending mode select command");
4548 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4549 int task_attr, int retry_count, int timeout)
4552 int c, page = -1, subpage = -1, pc = 0, llbaa = 0;
4553 int binary = 0, cdb_len = 10, dbd = 0, desc = 0, edit = 0, list = 0;
4555 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4573 str_subpage = optarg;
4574 strsep(&str_subpage, ",");
4575 page = strtol(optarg, NULL, 0);
4577 subpage = strtol(str_subpage, NULL, 0);
4581 errx(1, "invalid mode page %d", page);
4583 errx(1, "invalid mode subpage %d", subpage);
4592 pc = strtol(optarg, NULL, 0);
4593 if ((pc < 0) || (pc > 3))
4594 errx(1, "invalid page control field %d", pc);
4601 if (page == -1 && desc == 0 && list == 0)
4602 errx(1, "you must specify a mode page!");
4605 errx(1, "-d and -D are incompatible!");
4607 if (llbaa && cdb_len != 10)
4608 errx(1, "LLBAA bit is not present in MODE SENSE(6)!");
4611 mode_list(device, cdb_len, dbd, pc, list > 1, task_attr,
4612 retry_count, timeout);
4614 mode_edit(device, cdb_len, desc, dbd, llbaa, pc, page, subpage,
4615 edit, binary, task_attr, retry_count, timeout);
4620 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4621 int task_attr, int retry_count, int timeout)
4624 u_int32_t flags = CAM_DIR_NONE;
4625 u_int8_t *data_ptr = NULL;
4627 u_int8_t atacmd[12];
4628 struct get_hook hook;
4629 int c, data_bytes = 0, valid_bytes;
4635 char *datastr = NULL, *tstr, *resstr = NULL;
4637 int fd_data = 0, fd_res = 0;
4640 ccb = cam_getccb(device);
4643 warnx("scsicmd: error allocating ccb");
4647 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4649 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4653 while (isspace(*tstr) && (*tstr != '\0'))
4655 hook.argc = argc - optind;
4656 hook.argv = argv + optind;
4658 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), 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
4675 while (isspace(*tstr) && (*tstr != '\0'))
4677 hook.argc = argc - optind;
4678 hook.argv = argv + optind;
4680 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4683 * Increment optind by the number of arguments the
4684 * encoding routine processed. After each call to
4685 * getopt(3), optind points to the argument that
4686 * getopt should process _next_. In this case,
4687 * that means it points to the first command string
4688 * argument, if there is one. Once we increment
4689 * this, it should point to either the next command
4690 * line argument, or it should be past the end of
4702 if (arglist & CAM_ARG_CMD_OUT) {
4703 warnx("command must either be "
4704 "read or write, not both");
4706 goto scsicmd_bailout;
4708 arglist |= CAM_ARG_CMD_IN;
4710 data_bytes = strtol(optarg, NULL, 0);
4711 if (data_bytes <= 0) {
4712 warnx("invalid number of input bytes %d",
4715 goto scsicmd_bailout;
4717 hook.argc = argc - optind;
4718 hook.argv = argv + optind;
4721 datastr = cget(&hook, NULL);
4723 * If the user supplied "-" instead of a format, he
4724 * wants the data to be written to stdout.
4726 if ((datastr != NULL)
4727 && (datastr[0] == '-'))
4730 data_ptr = (u_int8_t *)malloc(data_bytes);
4731 if (data_ptr == NULL) {
4732 warnx("can't malloc memory for data_ptr");
4734 goto scsicmd_bailout;
4738 if (arglist & CAM_ARG_CMD_IN) {
4739 warnx("command must either be "
4740 "read or write, not both");
4742 goto scsicmd_bailout;
4744 arglist |= CAM_ARG_CMD_OUT;
4745 flags = CAM_DIR_OUT;
4746 data_bytes = strtol(optarg, NULL, 0);
4747 if (data_bytes <= 0) {
4748 warnx("invalid number of output bytes %d",
4751 goto scsicmd_bailout;
4753 hook.argc = argc - optind;
4754 hook.argv = argv + optind;
4756 datastr = cget(&hook, NULL);
4757 data_ptr = (u_int8_t *)malloc(data_bytes);
4758 if (data_ptr == NULL) {
4759 warnx("can't malloc memory for data_ptr");
4761 goto scsicmd_bailout;
4763 bzero(data_ptr, data_bytes);
4765 * If the user supplied "-" instead of a format, he
4766 * wants the data to be read from stdin.
4768 if ((datastr != NULL)
4769 && (datastr[0] == '-'))
4772 buff_encode_visit(data_ptr, data_bytes, datastr,
4778 hook.argc = argc - optind;
4779 hook.argv = argv + optind;
4781 resstr = cget(&hook, NULL);
4782 if ((resstr != NULL) && (resstr[0] == '-'))
4792 * If fd_data is set, and we're writing to the device, we need to
4793 * read the data the user wants written from stdin.
4795 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4797 int amt_to_read = data_bytes;
4798 u_int8_t *buf_ptr = data_ptr;
4800 for (amt_read = 0; amt_to_read > 0;
4801 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4802 if (amt_read == -1) {
4803 warn("error reading data from stdin");
4805 goto scsicmd_bailout;
4807 amt_to_read -= amt_read;
4808 buf_ptr += amt_read;
4812 if (arglist & CAM_ARG_ERR_RECOVER)
4813 flags |= CAM_PASS_ERR_RECOVER;
4815 /* Disable freezing the device queue */
4816 flags |= CAM_DEV_QFRZDIS;
4820 * This is taken from the SCSI-3 draft spec.
4821 * (T10/1157D revision 0.3)
4822 * The top 3 bits of an opcode are the group code.
4823 * The next 5 bits are the command code.
4824 * Group 0: six byte commands
4825 * Group 1: ten byte commands
4826 * Group 2: ten byte commands
4828 * Group 4: sixteen byte commands
4829 * Group 5: twelve byte commands
4830 * Group 6: vendor specific
4831 * Group 7: vendor specific
4833 switch((cdb[0] >> 5) & 0x7) {
4844 /* computed by buff_encode_visit */
4855 * We should probably use csio_build_visit or something like that
4856 * here, but it's easier to encode arguments as you go. The
4857 * alternative would be skipping the CDB argument and then encoding
4858 * it here, since we've got the data buffer argument by now.
4860 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4862 cam_fill_csio(&ccb->csio,
4863 /*retries*/ retry_count,
4866 /*tag_action*/ task_attr,
4867 /*data_ptr*/ data_ptr,
4868 /*dxfer_len*/ data_bytes,
4869 /*sense_len*/ SSD_FULL_SIZE,
4870 /*cdb_len*/ cdb_len,
4871 /*timeout*/ timeout ? timeout : 5000);
4874 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4876 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4878 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4880 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4882 cam_fill_ataio(&ccb->ataio,
4883 /*retries*/ retry_count,
4887 /*data_ptr*/ data_ptr,
4888 /*dxfer_len*/ data_bytes,
4889 /*timeout*/ timeout ? timeout : 5000);
4892 if (((retval = cam_send_ccb(device, ccb)) < 0)
4893 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4894 const char warnstr[] = "error sending command";
4901 if (arglist & CAM_ARG_VERBOSE) {
4902 cam_error_print(device, ccb, CAM_ESF_ALL,
4903 CAM_EPF_ALL, stderr);
4907 goto scsicmd_bailout;
4910 if (atacmd_len && need_res) {
4912 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4914 fprintf(stdout, "\n");
4917 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4918 ccb->ataio.res.status,
4919 ccb->ataio.res.error,
4920 ccb->ataio.res.lba_low,
4921 ccb->ataio.res.lba_mid,
4922 ccb->ataio.res.lba_high,
4923 ccb->ataio.res.device,
4924 ccb->ataio.res.lba_low_exp,
4925 ccb->ataio.res.lba_mid_exp,
4926 ccb->ataio.res.lba_high_exp,
4927 ccb->ataio.res.sector_count,
4928 ccb->ataio.res.sector_count_exp);
4934 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4936 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4937 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4938 && (arglist & CAM_ARG_CMD_IN)
4939 && (valid_bytes > 0)) {
4941 buff_decode_visit(data_ptr, valid_bytes, datastr,
4943 fprintf(stdout, "\n");
4945 ssize_t amt_written;
4946 int amt_to_write = valid_bytes;
4947 u_int8_t *buf_ptr = data_ptr;
4949 for (amt_written = 0; (amt_to_write > 0) &&
4950 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4951 amt_to_write -= amt_written;
4952 buf_ptr += amt_written;
4954 if (amt_written == -1) {
4955 warn("error writing data to stdout");
4957 goto scsicmd_bailout;
4958 } else if ((amt_written == 0)
4959 && (amt_to_write > 0)) {
4960 warnx("only wrote %u bytes out of %u",
4961 valid_bytes - amt_to_write, valid_bytes);
4968 if ((data_bytes > 0) && (data_ptr != NULL))
4977 camdebug(int argc, char **argv, char *combinedopt)
4980 path_id_t bus = CAM_BUS_WILDCARD;
4981 target_id_t target = CAM_TARGET_WILDCARD;
4982 lun_id_t lun = CAM_LUN_WILDCARD;
4987 bzero(&ccb, sizeof(union ccb));
4989 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4992 arglist |= CAM_ARG_DEBUG_INFO;
4993 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4996 arglist |= CAM_ARG_DEBUG_PERIPH;
4997 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
5000 arglist |= CAM_ARG_DEBUG_SUBTRACE;
5001 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
5004 arglist |= CAM_ARG_DEBUG_TRACE;
5005 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
5008 arglist |= CAM_ARG_DEBUG_XPT;
5009 ccb.cdbg.flags |= CAM_DEBUG_XPT;
5012 arglist |= CAM_ARG_DEBUG_CDB;
5013 ccb.cdbg.flags |= CAM_DEBUG_CDB;
5016 arglist |= CAM_ARG_DEBUG_PROBE;
5017 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
5028 warnx("you must specify \"off\", \"all\" or a bus,");
5029 warnx("bus:target, bus:target:lun or periph");
5034 while (isspace(*tstr) && (*tstr != '\0'))
5037 if (strncmp(tstr, "off", 3) == 0) {
5038 ccb.cdbg.flags = CAM_DEBUG_NONE;
5039 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
5040 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
5041 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
5043 rv = parse_btl(tstr, &bus, &target, &lun, &arglist);
5045 warnx("you must specify \"all\", \"off\", or a bus,");
5046 warnx("bus:target, bus:target:lun or periph to debug");
5051 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
5052 warnx("error opening transport layer device %s", XPT_DEVICE);
5053 warn("%s", XPT_DEVICE);
5057 ccb.ccb_h.func_code = XPT_DEBUG;
5058 ccb.ccb_h.path_id = bus;
5059 ccb.ccb_h.target_id = target;
5060 ccb.ccb_h.target_lun = lun;
5062 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
5063 warn("CAMIOCOMMAND ioctl failed");
5066 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
5067 CAM_FUNC_NOTAVAIL) {
5068 warnx("CAM debugging not available");
5069 warnx("you need to put options CAMDEBUG in"
5070 " your kernel config file!");
5072 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
5074 warnx("XPT_DEBUG CCB failed with status %#x",
5078 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
5080 "Debugging turned off\n");
5083 "Debugging enabled for "
5085 bus, target, (uintmax_t)lun);
5095 tagcontrol(struct cam_device *device, int argc, char **argv,
5105 ccb = cam_getccb(device);
5108 warnx("tagcontrol: error allocating ccb");
5112 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5115 numtags = strtol(optarg, NULL, 0);
5117 warnx("tag count %d is < 0", numtags);
5119 goto tagcontrol_bailout;
5130 cam_path_string(device, pathstr, sizeof(pathstr));
5133 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
5134 ccb->ccb_h.func_code = XPT_REL_SIMQ;
5135 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5136 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5137 ccb->crs.openings = numtags;
5140 if (cam_send_ccb(device, ccb) < 0) {
5141 warn("error sending XPT_REL_SIMQ CCB");
5143 goto tagcontrol_bailout;
5146 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5147 warnx("XPT_REL_SIMQ CCB failed");
5148 cam_error_print(device, ccb, CAM_ESF_ALL,
5149 CAM_EPF_ALL, stderr);
5151 goto tagcontrol_bailout;
5156 fprintf(stdout, "%stagged openings now %d\n",
5157 pathstr, ccb->crs.openings);
5160 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5162 ccb->ccb_h.func_code = XPT_GDEV_STATS;
5164 if (cam_send_ccb(device, ccb) < 0) {
5165 warn("error sending XPT_GDEV_STATS CCB");
5167 goto tagcontrol_bailout;
5170 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5171 warnx("XPT_GDEV_STATS CCB failed");
5172 cam_error_print(device, ccb, CAM_ESF_ALL,
5173 CAM_EPF_ALL, stderr);
5175 goto tagcontrol_bailout;
5178 if (arglist & CAM_ARG_VERBOSE) {
5179 fprintf(stdout, "%s", pathstr);
5180 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5181 fprintf(stdout, "%s", pathstr);
5182 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5183 fprintf(stdout, "%s", pathstr);
5184 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5185 fprintf(stdout, "%s", pathstr);
5186 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5187 fprintf(stdout, "%s", pathstr);
5188 fprintf(stdout, "held %d\n", ccb->cgds.held);
5189 fprintf(stdout, "%s", pathstr);
5190 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5191 fprintf(stdout, "%s", pathstr);
5192 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5195 fprintf(stdout, "%s", pathstr);
5196 fprintf(stdout, "device openings: ");
5198 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5199 ccb->cgds.dev_active);
5209 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5213 cam_path_string(device, pathstr, sizeof(pathstr));
5215 if (cts->transport == XPORT_SPI) {
5216 struct ccb_trans_settings_spi *spi =
5217 &cts->xport_specific.spi;
5219 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5221 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5224 if (spi->sync_offset != 0) {
5227 freq = scsi_calc_syncsrate(spi->sync_period);
5228 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5229 pathstr, freq / 1000, freq % 1000);
5233 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5234 fprintf(stdout, "%soffset: %d\n", pathstr,
5238 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5239 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5240 (0x01 << spi->bus_width) * 8);
5243 if (spi->valid & CTS_SPI_VALID_DISC) {
5244 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5245 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5246 "enabled" : "disabled");
5249 if (cts->transport == XPORT_FC) {
5250 struct ccb_trans_settings_fc *fc =
5251 &cts->xport_specific.fc;
5253 if (fc->valid & CTS_FC_VALID_WWNN)
5254 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5255 (long long) fc->wwnn);
5256 if (fc->valid & CTS_FC_VALID_WWPN)
5257 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5258 (long long) fc->wwpn);
5259 if (fc->valid & CTS_FC_VALID_PORT)
5260 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5261 if (fc->valid & CTS_FC_VALID_SPEED)
5262 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5263 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5265 if (cts->transport == XPORT_SAS) {
5266 struct ccb_trans_settings_sas *sas =
5267 &cts->xport_specific.sas;
5269 if (sas->valid & CTS_SAS_VALID_SPEED)
5270 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5271 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5273 if (cts->transport == XPORT_ATA) {
5274 struct ccb_trans_settings_pata *pata =
5275 &cts->xport_specific.ata;
5277 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5278 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5279 ata_mode2string(pata->mode));
5281 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5282 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5285 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5286 fprintf(stdout, "%sPIO transaction length: %d\n",
5287 pathstr, pata->bytecount);
5290 if (cts->transport == XPORT_SATA) {
5291 struct ccb_trans_settings_sata *sata =
5292 &cts->xport_specific.sata;
5294 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5295 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5298 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5299 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5300 ata_mode2string(sata->mode));
5302 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5303 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5306 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5307 fprintf(stdout, "%sPIO transaction length: %d\n",
5308 pathstr, sata->bytecount);
5310 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5311 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5314 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5315 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5318 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5319 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5323 if (cts->protocol == PROTO_ATA) {
5324 struct ccb_trans_settings_ata *ata=
5325 &cts->proto_specific.ata;
5327 if (ata->valid & CTS_ATA_VALID_TQ) {
5328 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5329 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5330 "enabled" : "disabled");
5333 if (cts->protocol == PROTO_SCSI) {
5334 struct ccb_trans_settings_scsi *scsi=
5335 &cts->proto_specific.scsi;
5337 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5338 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5339 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5340 "enabled" : "disabled");
5344 if (cts->protocol == PROTO_NVME) {
5345 struct ccb_trans_settings_nvme *nvmex =
5346 &cts->xport_specific.nvme;
5348 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5349 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5350 NVME_MAJOR(nvmex->spec),
5351 NVME_MINOR(nvmex->spec));
5353 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5354 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5355 nvmex->lanes, nvmex->max_lanes);
5356 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5357 nvmex->speed, nvmex->max_speed);
5364 * Get a path inquiry CCB for the specified device.
5367 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5372 ccb = cam_getccb(device);
5374 warnx("get_cpi: couldn't allocate CCB");
5377 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5378 ccb->ccb_h.func_code = XPT_PATH_INQ;
5379 if (cam_send_ccb(device, ccb) < 0) {
5380 warn("get_cpi: error sending Path Inquiry CCB");
5382 goto get_cpi_bailout;
5384 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5385 if (arglist & CAM_ARG_VERBOSE)
5386 cam_error_print(device, ccb, CAM_ESF_ALL,
5387 CAM_EPF_ALL, stderr);
5389 goto get_cpi_bailout;
5391 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5399 * Get a get device CCB for the specified device.
5402 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5407 ccb = cam_getccb(device);
5409 warnx("get_cgd: couldn't allocate CCB");
5412 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5413 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5414 if (cam_send_ccb(device, ccb) < 0) {
5415 warn("get_cgd: error sending Get type information CCB");
5417 goto get_cgd_bailout;
5419 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5420 if (arglist & CAM_ARG_VERBOSE)
5421 cam_error_print(device, ccb, CAM_ESF_ALL,
5422 CAM_EPF_ALL, stderr);
5424 goto get_cgd_bailout;
5426 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5434 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5438 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5439 int timeout, int verbosemode)
5441 union ccb *ccb = NULL;
5442 struct scsi_vpd_supported_page_list sup_pages;
5446 ccb = cam_getccb(dev);
5448 warn("Unable to allocate CCB");
5453 /* cam_getccb cleans up the header, caller has to zero the payload */
5454 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5456 bzero(&sup_pages, sizeof(sup_pages));
5458 scsi_inquiry(&ccb->csio,
5459 /*retries*/ retry_count,
5461 /* tag_action */ MSG_SIMPLE_Q_TAG,
5462 /* inq_buf */ (u_int8_t *)&sup_pages,
5463 /* inq_len */ sizeof(sup_pages),
5465 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5466 /* sense_len */ SSD_FULL_SIZE,
5467 /* timeout */ timeout ? timeout : 5000);
5469 /* Disable freezing the device queue */
5470 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5472 if (retry_count != 0)
5473 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5475 if (cam_send_ccb(dev, ccb) < 0) {
5482 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5483 if (verbosemode != 0)
5484 cam_error_print(dev, ccb, CAM_ESF_ALL,
5485 CAM_EPF_ALL, stderr);
5490 for (i = 0; i < sup_pages.length; i++) {
5491 if (sup_pages.list[i] == page_id) {
5504 * devtype is filled in with the type of device.
5505 * Returns 0 for success, non-zero for failure.
5508 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5509 int verbosemode, camcontrol_devtype *devtype)
5511 struct ccb_getdev cgd;
5514 retval = get_cgd(dev, &cgd);
5518 switch (cgd.protocol) {
5524 *devtype = CC_DT_ATA;
5526 break; /*NOTREACHED*/
5528 *devtype = CC_DT_NVME;
5530 break; /*NOTREACHED*/
5532 *devtype = CC_DT_MMCSD;
5534 break; /*NOTREACHED*/
5536 *devtype = CC_DT_UNKNOWN;
5538 break; /*NOTREACHED*/
5541 if (retry_count == -1) {
5543 * For a retry count of -1, used only the cached data to avoid
5544 * I/O to the drive. Sending the identify command to the drive
5545 * can cause issues for SATL attachaed drives since identify is
5546 * not an NCQ command.
5548 if (cgd.ident_data.config != 0)
5549 *devtype = CC_DT_SATL;
5551 *devtype = CC_DT_SCSI;
5554 * Check for the ATA Information VPD page (0x89). If this is an
5555 * ATA device behind a SCSI to ATA translation layer (SATL),
5556 * this VPD page should be present.
5558 * If that VPD page isn't present, or we get an error back from
5559 * the INQUIRY command, we'll just treat it as a normal SCSI
5562 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5563 timeout, verbosemode);
5565 *devtype = CC_DT_SATL;
5567 *devtype = CC_DT_SCSI;
5576 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5577 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5578 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5579 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5580 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5581 int is48bit, camcontrol_devtype devtype)
5585 if (devtype == CC_DT_ATA) {
5586 cam_fill_ataio(&ccb->ataio,
5587 /*retries*/ retry_count,
5590 /*tag_action*/ tag_action,
5591 /*data_ptr*/ data_ptr,
5592 /*dxfer_len*/ dxfer_len,
5593 /*timeout*/ timeout);
5594 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5595 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5598 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5601 if (auxiliary != 0) {
5602 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5603 ccb->ataio.aux = auxiliary;
5606 if (ata_flags & AP_FLAG_CHK_COND)
5607 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5609 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5610 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5611 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5612 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5614 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5615 protocol |= AP_EXTEND;
5617 retval = scsi_ata_pass(&ccb->csio,
5618 /*retries*/ retry_count,
5621 /*tag_action*/ tag_action,
5622 /*protocol*/ protocol,
5623 /*ata_flags*/ ata_flags,
5624 /*features*/ features,
5625 /*sector_count*/ sector_count,
5627 /*command*/ command,
5630 /*auxiliary*/ auxiliary,
5632 /*data_ptr*/ data_ptr,
5633 /*dxfer_len*/ dxfer_len,
5634 /*cdb_storage*/ cdb_storage,
5635 /*cdb_storage_len*/ cdb_storage_len,
5636 /*minimum_cmd_size*/ 0,
5637 /*sense_len*/ sense_len,
5638 /*timeout*/ timeout);
5645 * Returns: 0 -- success, 1 -- error, 2 -- lba truncated,
5646 * 4 -- count truncated, 6 -- lba and count truncated.
5649 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5650 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5654 switch (ccb->ccb_h.func_code) {
5657 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5661 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5662 * or 16 byte, and need to see what
5664 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5665 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5667 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5668 if ((opcode != ATA_PASS_12)
5669 && (opcode != ATA_PASS_16)) {
5670 warnx("%s: unsupported opcode %02x", __func__, opcode);
5674 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5676 /* Note: the _ccb() variant returns 0 for an error */
5680 sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
5681 switch (error_code) {
5682 case SSD_DESC_CURRENT_ERROR:
5683 case SSD_DESC_DEFERRED_ERROR: {
5684 struct scsi_sense_data_desc *sense;
5685 struct scsi_sense_ata_ret_desc *desc;
5688 sense = (struct scsi_sense_data_desc *)
5689 &ccb->csio.sense_data;
5691 desc_ptr = scsi_find_desc(sense, sense_len,
5693 if (desc_ptr == NULL) {
5694 cam_error_print(dev, ccb, CAM_ESF_ALL,
5695 CAM_EPF_ALL, stderr);
5698 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5700 *error = desc->error;
5701 *count = (desc->count_15_8 << 8) |
5703 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5704 ((uint64_t)desc->lba_39_32 << 32) |
5705 ((uint64_t)desc->lba_31_24 << 24) |
5706 (desc->lba_23_16 << 16) |
5707 (desc->lba_15_8 << 8) |
5709 *device = desc->device;
5710 *status = desc->status;
5713 * If the extend bit isn't set, the result is for a
5714 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5715 * command without the extend bit set. This means
5716 * that the device is supposed to return 28-bit
5717 * status. The count field is only 8 bits, and the
5718 * LBA field is only 8 bits.
5720 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5726 case SSD_CURRENT_ERROR:
5727 case SSD_DEFERRED_ERROR: {
5731 * In my understanding of SAT-5 specification, saying:
5732 * "without interpreting the contents of the STATUS",
5733 * this should not happen if CK_COND was set, but it
5734 * does at least for some devices, so try to revert.
5736 if ((sense_key == SSD_KEY_ABORTED_COMMAND) &&
5737 (asc == 0) && (ascq == 0)) {
5738 *status = ATA_STATUS_ERROR;
5739 *error = ATA_ERROR_ABORT;
5746 if ((sense_key != SSD_KEY_RECOVERED_ERROR) ||
5747 (asc != 0x00) || (ascq != 0x1d))
5751 scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5752 SSD_DESC_INFO, &val, NULL);
5753 *error = (val >> 24) & 0xff;
5754 *status = (val >> 16) & 0xff;
5755 *device = (val >> 8) & 0xff;
5756 *count = val & 0xff;
5759 scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5760 SSD_DESC_COMMAND, &val, NULL);
5761 *lba = ((val >> 16) & 0xff) | (val & 0xff00) |
5762 ((val & 0xff) << 16);
5764 /* Report UPPER NONZERO bits as errors 2, 4 and 6. */
5765 return ((val >> 28) & 0x06);
5774 struct ata_res *res;
5776 /* Only some statuses return ATA result register set. */
5777 if (cam_ccb_status(ccb) != CAM_REQ_CMP &&
5778 cam_ccb_status(ccb) != CAM_ATA_STATUS_ERROR)
5781 res = &ccb->ataio.res;
5782 *error = res->error;
5783 *status = res->status;
5784 *device = res->device;
5785 *count = res->sector_count;
5786 *lba = (res->lba_high << 16) |
5787 (res->lba_mid << 8) |
5789 if (ccb->ataio.cmd.flags & CAM_ATAIO_48BIT) {
5790 *count |= (res->sector_count_exp << 8);
5791 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5792 ((uint64_t)res->lba_mid_exp << 32) |
5793 ((uint64_t)res->lba_high_exp << 40);
5795 *lba |= (res->device & 0xf) << 24;
5806 cpi_print(struct ccb_pathinq *cpi)
5808 char adapter_str[1024];
5811 snprintf(adapter_str, sizeof(adapter_str),
5812 "%s%d:", cpi->dev_name, cpi->unit_number);
5814 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5817 for (i = 1; i < UINT8_MAX; i = i << 1) {
5820 if ((i & cpi->hba_inquiry) == 0)
5823 fprintf(stdout, "%s supports ", adapter_str);
5827 str = "MDP message";
5830 str = "32 bit wide SCSI";
5833 str = "16 bit wide SCSI";
5836 str = "SDTR message";
5839 str = "linked CDBs";
5842 str = "tag queue messages";
5845 str = "soft reset alternative";
5848 str = "SATA Port Multiplier";
5851 str = "unknown PI bit set";
5854 fprintf(stdout, "%s\n", str);
5857 for (i = 1; i < UINT32_MAX; i = i << 1) {
5860 if ((i & cpi->hba_misc) == 0)
5863 fprintf(stdout, "%s ", adapter_str);
5867 str = "can understand ata_ext requests";
5870 str = "64bit extended LUNs supported";
5873 str = "bus scans from high ID to low ID";
5876 str = "removable devices not included in scan";
5878 case PIM_NOINITIATOR:
5879 str = "initiator role not supported";
5881 case PIM_NOBUSRESET:
5882 str = "user has disabled initial BUS RESET or"
5883 " controller is in target/mixed mode";
5886 str = "do not send 6-byte commands";
5889 str = "scan bus sequentially";
5892 str = "unmapped I/O supported";
5895 str = "does its own scanning";
5898 str = "unknown PIM bit set";
5901 fprintf(stdout, "%s\n", str);
5904 for (i = 1; i < UINT16_MAX; i = i << 1) {
5907 if ((i & cpi->target_sprt) == 0)
5910 fprintf(stdout, "%s supports ", adapter_str);
5913 str = "target mode processor mode";
5916 str = "target mode phase cog. mode";
5918 case PIT_DISCONNECT:
5919 str = "disconnects in target mode";
5922 str = "terminate I/O message in target mode";
5925 str = "group 6 commands in target mode";
5928 str = "group 7 commands in target mode";
5931 str = "unknown PIT bit set";
5935 fprintf(stdout, "%s\n", str);
5937 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5939 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5941 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5943 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5944 adapter_str, cpi->hpath_id);
5945 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5947 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5948 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5949 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5950 adapter_str, cpi->hba_vendor);
5951 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5952 adapter_str, cpi->hba_device);
5953 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5954 adapter_str, cpi->hba_subvendor);
5955 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5956 adapter_str, cpi->hba_subdevice);
5957 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5958 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5959 if (cpi->base_transfer_speed > 1000)
5960 fprintf(stdout, "%d.%03dMB/sec\n",
5961 cpi->base_transfer_speed / 1000,
5962 cpi->base_transfer_speed % 1000);
5964 fprintf(stdout, "%dKB/sec\n",
5965 (cpi->base_transfer_speed % 1000) * 1000);
5966 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5967 adapter_str, cpi->maxio);
5971 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5972 struct ccb_trans_settings *cts)
5978 ccb = cam_getccb(device);
5981 warnx("get_print_cts: error allocating ccb");
5985 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5987 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5989 if (user_settings == 0)
5990 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5992 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5994 if (cam_send_ccb(device, ccb) < 0) {
5995 warn("error sending XPT_GET_TRAN_SETTINGS CCB");
5997 goto get_print_cts_bailout;
6000 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6001 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
6002 if (arglist & CAM_ARG_VERBOSE)
6003 cam_error_print(device, ccb, CAM_ESF_ALL,
6004 CAM_EPF_ALL, stderr);
6006 goto get_print_cts_bailout;
6010 cts_print(device, &ccb->cts);
6013 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
6015 get_print_cts_bailout:
6023 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
6024 int timeout, int argc, char **argv, char *combinedopt)
6028 int user_settings = 0;
6030 int disc_enable = -1, tag_enable = -1;
6033 double syncrate = -1;
6036 int change_settings = 0, send_tur = 0;
6037 struct ccb_pathinq cpi;
6039 ccb = cam_getccb(device);
6041 warnx("ratecontrol: error allocating ccb");
6044 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6053 if (strncasecmp(optarg, "enable", 6) == 0)
6055 else if (strncasecmp(optarg, "disable", 7) == 0)
6058 warnx("-D argument \"%s\" is unknown", optarg);
6060 goto ratecontrol_bailout;
6062 change_settings = 1;
6065 mode = ata_string2mode(optarg);
6067 warnx("unknown mode '%s'", optarg);
6069 goto ratecontrol_bailout;
6071 change_settings = 1;
6074 offset = strtol(optarg, NULL, 0);
6076 warnx("offset value %d is < 0", offset);
6078 goto ratecontrol_bailout;
6080 change_settings = 1;
6086 syncrate = atof(optarg);
6088 warnx("sync rate %f is < 0", syncrate);
6090 goto ratecontrol_bailout;
6092 change_settings = 1;
6095 if (strncasecmp(optarg, "enable", 6) == 0)
6097 else if (strncasecmp(optarg, "disable", 7) == 0)
6100 warnx("-T argument \"%s\" is unknown", optarg);
6102 goto ratecontrol_bailout;
6104 change_settings = 1;
6110 bus_width = strtol(optarg, NULL, 0);
6111 if (bus_width < 0) {
6112 warnx("bus width %d is < 0", bus_width);
6114 goto ratecontrol_bailout;
6116 change_settings = 1;
6123 * Grab path inquiry information, so we can determine whether
6124 * or not the initiator is capable of the things that the user
6127 if ((retval = get_cpi(device, &cpi)) != 0)
6128 goto ratecontrol_bailout;
6129 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
6131 fprintf(stdout, "%s parameters:\n",
6132 user_settings ? "User" : "Current");
6134 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
6136 goto ratecontrol_bailout;
6138 if (arglist & CAM_ARG_VERBOSE)
6141 if (change_settings) {
6142 int didsettings = 0;
6143 struct ccb_trans_settings_spi *spi = NULL;
6144 struct ccb_trans_settings_pata *pata = NULL;
6145 struct ccb_trans_settings_sata *sata = NULL;
6146 struct ccb_trans_settings_ata *ata = NULL;
6147 struct ccb_trans_settings_scsi *scsi = NULL;
6149 if (ccb->cts.transport == XPORT_SPI)
6150 spi = &ccb->cts.xport_specific.spi;
6151 if (ccb->cts.transport == XPORT_ATA)
6152 pata = &ccb->cts.xport_specific.ata;
6153 if (ccb->cts.transport == XPORT_SATA)
6154 sata = &ccb->cts.xport_specific.sata;
6155 if (ccb->cts.protocol == PROTO_ATA)
6156 ata = &ccb->cts.proto_specific.ata;
6157 if (ccb->cts.protocol == PROTO_SCSI)
6158 scsi = &ccb->cts.proto_specific.scsi;
6159 ccb->cts.xport_specific.valid = 0;
6160 ccb->cts.proto_specific.valid = 0;
6161 if (spi && disc_enable != -1) {
6162 spi->valid |= CTS_SPI_VALID_DISC;
6163 if (disc_enable == 0)
6164 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6166 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6169 if (tag_enable != -1) {
6170 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6171 warnx("HBA does not support tagged queueing, "
6172 "so you cannot modify tag settings");
6174 goto ratecontrol_bailout;
6177 ata->valid |= CTS_SCSI_VALID_TQ;
6178 if (tag_enable == 0)
6179 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6181 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6184 scsi->valid |= CTS_SCSI_VALID_TQ;
6185 if (tag_enable == 0)
6186 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6188 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6192 if (spi && offset != -1) {
6193 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6194 warnx("HBA is not capable of changing offset");
6196 goto ratecontrol_bailout;
6198 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6199 spi->sync_offset = offset;
6202 if (spi && syncrate != -1) {
6203 int prelim_sync_period;
6205 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6206 warnx("HBA is not capable of changing "
6209 goto ratecontrol_bailout;
6211 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6213 * The sync rate the user gives us is in MHz.
6214 * We need to translate it into KHz for this
6219 * Next, we calculate a "preliminary" sync period
6220 * in tenths of a nanosecond.
6223 prelim_sync_period = 0;
6225 prelim_sync_period = 10000000 / syncrate;
6227 scsi_calc_syncparam(prelim_sync_period);
6230 if (sata && syncrate != -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 rate "
6239 "settings for SATA");
6241 goto ratecontrol_bailout;
6243 sata->revision = ata_speed2revision(syncrate * 100);
6244 if (sata->revision < 0) {
6245 warnx("Invalid rate %f", syncrate);
6247 goto ratecontrol_bailout;
6249 sata->valid |= CTS_SATA_VALID_REVISION;
6252 if ((pata || sata) && mode != -1) {
6253 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6254 warnx("HBA is not capable of changing "
6257 goto ratecontrol_bailout;
6259 if (!user_settings) {
6260 warnx("You can modify only user mode "
6261 "settings for ATA/SATA");
6263 goto ratecontrol_bailout;
6267 pata->valid |= CTS_ATA_VALID_MODE;
6270 sata->valid |= CTS_SATA_VALID_MODE;
6275 * The bus_width argument goes like this:
6279 * Therefore, if you shift the number of bits given on the
6280 * command line right by 4, you should get the correct
6283 if (spi && bus_width != -1) {
6285 * We might as well validate things here with a
6286 * decipherable error message, rather than what
6287 * will probably be an indecipherable error message
6288 * by the time it gets back to us.
6290 if ((bus_width == 16)
6291 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6292 warnx("HBA does not support 16 bit bus width");
6294 goto ratecontrol_bailout;
6295 } else if ((bus_width == 32)
6296 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6297 warnx("HBA does not support 32 bit bus width");
6299 goto ratecontrol_bailout;
6300 } else if ((bus_width != 8)
6301 && (bus_width != 16)
6302 && (bus_width != 32)) {
6303 warnx("Invalid bus width %d", bus_width);
6305 goto ratecontrol_bailout;
6307 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6308 spi->bus_width = bus_width >> 4;
6311 if (didsettings == 0) {
6312 goto ratecontrol_bailout;
6314 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6315 if (cam_send_ccb(device, ccb) < 0) {
6316 warn("error sending XPT_SET_TRAN_SETTINGS CCB");
6318 goto ratecontrol_bailout;
6320 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6321 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6322 if (arglist & CAM_ARG_VERBOSE) {
6323 cam_error_print(device, ccb, CAM_ESF_ALL,
6324 CAM_EPF_ALL, stderr);
6327 goto ratecontrol_bailout;
6331 retval = testunitready(device, task_attr, retry_count, timeout,
6332 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6334 * If the TUR didn't succeed, just bail.
6338 fprintf(stderr, "Test Unit Ready failed\n");
6339 goto ratecontrol_bailout;
6342 if ((change_settings || send_tur) && !quiet &&
6343 (ccb->cts.transport == XPORT_ATA ||
6344 ccb->cts.transport == XPORT_SATA || send_tur)) {
6345 fprintf(stdout, "New parameters:\n");
6346 retval = get_print_cts(device, user_settings, 0, NULL);
6349 ratecontrol_bailout:
6355 scsiformat(struct cam_device *device, int argc, char **argv,
6356 char *combinedopt, int task_attr, int retry_count, int timeout)
6360 int ycount = 0, quiet = 0;
6361 int error = 0, retval = 0;
6362 int use_timeout = 10800 * 1000;
6364 struct format_defect_list_header fh;
6365 u_int8_t *data_ptr = NULL;
6366 u_int32_t dxfer_len = 0;
6368 int num_warnings = 0;
6371 ccb = cam_getccb(device);
6374 warnx("scsiformat: error allocating ccb");
6378 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6380 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6400 if (quiet == 0 && ycount == 0) {
6401 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6402 "following device:\n");
6404 error = scsidoinquiry(device, argc, argv, combinedopt,
6405 task_attr, retry_count, timeout);
6408 warnx("scsiformat: error sending inquiry");
6409 goto scsiformat_bailout;
6414 if (!get_confirmation()) {
6416 goto scsiformat_bailout;
6421 use_timeout = timeout;
6424 fprintf(stdout, "Current format timeout is %d seconds\n",
6425 use_timeout / 1000);
6429 * If the user hasn't disabled questions and didn't specify a
6430 * timeout on the command line, ask them if they want the current
6434 && (timeout == 0)) {
6436 int new_timeout = 0;
6438 fprintf(stdout, "Enter new timeout in seconds or press\n"
6439 "return to keep the current timeout [%d] ",
6440 use_timeout / 1000);
6442 if (fgets(str, sizeof(str), stdin) != NULL) {
6444 new_timeout = atoi(str);
6447 if (new_timeout != 0) {
6448 use_timeout = new_timeout * 1000;
6449 fprintf(stdout, "Using new timeout value %d\n",
6450 use_timeout / 1000);
6455 * Keep this outside the if block below to silence any unused
6456 * variable warnings.
6458 bzero(&fh, sizeof(fh));
6461 * If we're in immediate mode, we've got to include the format
6464 if (immediate != 0) {
6465 fh.byte2 = FU_DLH_IMMED;
6466 data_ptr = (u_int8_t *)&fh;
6467 dxfer_len = sizeof(fh);
6468 byte2 = FU_FMT_DATA;
6469 } else if (quiet == 0) {
6470 fprintf(stdout, "Formatting...");
6474 scsi_format_unit(&ccb->csio,
6475 /* retries */ retry_count,
6477 /* tag_action */ task_attr,
6480 /* data_ptr */ data_ptr,
6481 /* dxfer_len */ dxfer_len,
6482 /* sense_len */ SSD_FULL_SIZE,
6483 /* timeout */ use_timeout);
6485 /* Disable freezing the device queue */
6486 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6488 if (arglist & CAM_ARG_ERR_RECOVER)
6489 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6491 if (((retval = cam_send_ccb(device, ccb)) < 0)
6492 || ((immediate == 0)
6493 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6494 const char errstr[] = "error sending format command";
6501 if (arglist & CAM_ARG_VERBOSE) {
6502 cam_error_print(device, ccb, CAM_ESF_ALL,
6503 CAM_EPF_ALL, stderr);
6506 goto scsiformat_bailout;
6510 * If we ran in non-immediate mode, we already checked for errors
6511 * above and printed out any necessary information. If we're in
6512 * immediate mode, we need to loop through and get status
6513 * information periodically.
6515 if (immediate == 0) {
6517 fprintf(stdout, "Format Complete\n");
6519 goto scsiformat_bailout;
6526 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6529 * There's really no need to do error recovery or
6530 * retries here, since we're just going to sit in a
6531 * loop and wait for the device to finish formatting.
6533 scsi_test_unit_ready(&ccb->csio,
6536 /* tag_action */ task_attr,
6537 /* sense_len */ SSD_FULL_SIZE,
6538 /* timeout */ 5000);
6540 /* Disable freezing the device queue */
6541 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6543 retval = cam_send_ccb(device, ccb);
6546 * If we get an error from the ioctl, bail out. SCSI
6547 * errors are expected.
6550 warn("error sending TEST UNIT READY command");
6552 goto scsiformat_bailout;
6555 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6557 if ((status != CAM_REQ_CMP)
6558 && (status == CAM_SCSI_STATUS_ERROR)
6559 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6560 struct scsi_sense_data *sense;
6561 int error_code, sense_key, asc, ascq;
6563 sense = &ccb->csio.sense_data;
6564 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6565 ccb->csio.sense_resid, &error_code, &sense_key,
6566 &asc, &ascq, /*show_errors*/ 1);
6569 * According to the SCSI-2 and SCSI-3 specs, a
6570 * drive that is in the middle of a format should
6571 * return NOT READY with an ASC of "logical unit
6572 * not ready, format in progress". The sense key
6573 * specific bytes will then be a progress indicator.
6575 if ((sense_key == SSD_KEY_NOT_READY)
6576 && (asc == 0x04) && (ascq == 0x04)) {
6579 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6580 ccb->csio.sense_resid, sks) == 0)
6583 u_int64_t percentage;
6585 val = scsi_2btoul(&sks[1]);
6586 percentage = 10000ull * val;
6589 "\rFormatting: %ju.%02u %% "
6591 (uintmax_t)(percentage /
6593 (unsigned)((percentage /
6597 } else if ((quiet == 0)
6598 && (++num_warnings <= 1)) {
6599 warnx("Unexpected SCSI Sense Key "
6600 "Specific value returned "
6602 scsi_sense_print(device, &ccb->csio,
6604 warnx("Unable to print status "
6605 "information, but format will "
6607 warnx("will exit when format is "
6612 warnx("Unexpected SCSI error during format");
6613 cam_error_print(device, ccb, CAM_ESF_ALL,
6614 CAM_EPF_ALL, stderr);
6616 goto scsiformat_bailout;
6619 } else if (status != CAM_REQ_CMP) {
6620 warnx("Unexpected CAM status %#x", status);
6621 if (arglist & CAM_ARG_VERBOSE)
6622 cam_error_print(device, ccb, CAM_ESF_ALL,
6623 CAM_EPF_ALL, stderr);
6625 goto scsiformat_bailout;
6628 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6631 fprintf(stdout, "\nFormat Complete\n");
6641 sanitize_wait_ata(struct cam_device *device, union ccb *ccb, int quiet,
6642 camcontrol_devtype devtype)
6645 uint8_t error = 0, ata_device = 0, status = 0;
6651 retval = build_ata_cmd(ccb,
6653 /*flags*/ CAM_DIR_NONE,
6654 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6655 /*protocol*/ AP_PROTO_NON_DATA,
6656 /*ata_flags*/ AP_FLAG_CHK_COND,
6657 /*features*/ 0x00, /* SANITIZE STATUS EXT */
6660 /*command*/ ATA_SANITIZE,
6664 /*cdb_storage*/ NULL,
6665 /*cdb_storage_len*/ 0,
6666 /*sense_len*/ SSD_FULL_SIZE,
6669 /*devtype*/ devtype);
6671 warnx("%s: build_ata_cmd() failed, likely "
6672 "programmer error", __func__);
6676 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6677 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6678 retval = cam_send_ccb(device, ccb);
6680 warn("error sending SANITIZE STATUS EXT command");
6684 retval = get_ata_status(device, ccb, &error, &count, &lba,
6685 &ata_device, &status);
6687 warnx("Can't get SANITIZE STATUS EXT status, "
6688 "sanitize may still run.");
6691 if (status & ATA_STATUS_ERROR) {
6692 warnx("SANITIZE STATUS EXT failed, "
6693 "sanitize may still run.");
6696 if (count & 0x4000) {
6701 "Sanitizing: %u.%02u%% (%d/%d)\r",
6702 (perc / (0x10000 * 100)),
6703 ((perc / 0x10000) % 100),
6708 } else if ((count & 0x8000) == 0) {
6709 warnx("Sanitize complete with an error. ");
6718 sanitize_wait_scsi(struct cam_device *device, union ccb *ccb, int task_attr, int quiet)
6720 int warnings = 0, retval;
6725 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6728 * There's really no need to do error recovery or
6729 * retries here, since we're just going to sit in a
6730 * loop and wait for the device to finish sanitizing.
6732 scsi_test_unit_ready(&ccb->csio,
6735 /* tag_action */ task_attr,
6736 /* sense_len */ SSD_FULL_SIZE,
6737 /* timeout */ 5000);
6739 /* Disable freezing the device queue */
6740 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6742 retval = cam_send_ccb(device, ccb);
6745 * If we get an error from the ioctl, bail out. SCSI
6746 * errors are expected.
6749 warn("error sending TEST UNIT READY command");
6753 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6754 if ((status == CAM_SCSI_STATUS_ERROR) &&
6755 ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6756 struct scsi_sense_data *sense;
6757 int error_code, sense_key, asc, ascq;
6759 sense = &ccb->csio.sense_data;
6760 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6761 ccb->csio.sense_resid, &error_code, &sense_key,
6762 &asc, &ascq, /*show_errors*/ 1);
6765 * According to the SCSI-3 spec, a drive that is in the
6766 * middle of a sanitize should return NOT READY with an
6767 * ASC of "logical unit not ready, sanitize in
6768 * progress". The sense key specific bytes will then
6769 * be a progress indicator.
6771 if ((sense_key == SSD_KEY_NOT_READY)
6772 && (asc == 0x04) && (ascq == 0x1b)) {
6775 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6776 ccb->csio.sense_resid, sks) == 0)
6778 val = scsi_2btoul(&sks[1]);
6781 "Sanitizing: %u.%02u%% (%d/%d)\r",
6782 (perc / (0x10000 * 100)),
6783 ((perc / 0x10000) % 100),
6786 } else if ((quiet == 0) && (++warnings <= 1)) {
6787 warnx("Unexpected SCSI Sense Key "
6788 "Specific value returned "
6789 "during sanitize:");
6790 scsi_sense_print(device, &ccb->csio,
6792 warnx("Unable to print status "
6793 "information, but sanitze will "
6795 warnx("will exit when sanitize is "
6800 warnx("Unexpected SCSI error during sanitize");
6801 cam_error_print(device, ccb, CAM_ESF_ALL,
6802 CAM_EPF_ALL, stderr);
6806 } else if (status != CAM_REQ_CMP && status != CAM_REQUEUE_REQ) {
6807 warnx("Unexpected CAM status %#x", status);
6808 if (arglist & CAM_ARG_VERBOSE)
6809 cam_error_print(device, ccb, CAM_ESF_ALL,
6810 CAM_EPF_ALL, stderr);
6813 } while ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6818 sanitize(struct cam_device *device, int argc, char **argv,
6819 char *combinedopt, int task_attr, int retry_count, int timeout)
6822 u_int8_t action = 0;
6824 int ycount = 0, quiet = 0;
6832 const char *pattern = NULL;
6833 u_int8_t *data_ptr = NULL;
6834 u_int32_t dxfer_len = 0;
6836 uint16_t feature, count;
6839 camcontrol_devtype dt;
6842 * Get the device type, request no I/O be done to do this.
6844 error = get_device_type(device, -1, 0, 0, &dt);
6845 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
6846 warnx("sanitize: can't get device type");
6850 ccb = cam_getccb(device);
6853 warnx("sanitize: error allocating ccb");
6857 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6859 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6862 if (strcasecmp(optarg, "overwrite") == 0)
6863 action = SSZ_SERVICE_ACTION_OVERWRITE;
6864 else if (strcasecmp(optarg, "block") == 0)
6865 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6866 else if (strcasecmp(optarg, "crypto") == 0)
6867 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6868 else if (strcasecmp(optarg, "exitfailure") == 0)
6869 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6871 warnx("invalid service operation \"%s\"",
6874 goto sanitize_bailout;
6878 passes = strtol(optarg, NULL, 0);
6879 if (passes < 1 || passes > 31) {
6880 warnx("invalid passes value %d", passes);
6882 goto sanitize_bailout;
6901 /* ATA supports only immediate commands. */
6902 if (dt == CC_DT_SCSI)
6915 warnx("an action is required");
6917 goto sanitize_bailout;
6918 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6919 struct scsi_sanitize_parameter_list *pl;
6923 if (pattern == NULL) {
6924 warnx("overwrite action requires -P argument");
6926 goto sanitize_bailout;
6928 fd = open(pattern, O_RDONLY);
6930 warn("cannot open pattern file %s", pattern);
6932 goto sanitize_bailout;
6934 if (fstat(fd, &sb) < 0) {
6935 warn("cannot stat pattern file %s", pattern);
6937 goto sanitize_bailout;
6940 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6941 warnx("pattern file size exceeds maximum value %d",
6942 SSZPL_MAX_PATTERN_LENGTH);
6944 goto sanitize_bailout;
6946 dxfer_len = sizeof(*pl) + sz;
6947 data_ptr = calloc(1, dxfer_len);
6948 if (data_ptr == NULL) {
6949 warnx("cannot allocate parameter list buffer");
6951 goto sanitize_bailout;
6954 amt = read(fd, data_ptr + sizeof(*pl), sz);
6956 warn("cannot read pattern file");
6958 goto sanitize_bailout;
6959 } else if (amt != sz) {
6960 warnx("short pattern file read");
6962 goto sanitize_bailout;
6965 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6971 pl->byte1 |= SSZPL_INVERT;
6972 scsi_ulto2b(sz, pl->length);
6978 else if (invert != 0)
6980 else if (pattern != NULL)
6985 warnx("%s argument only valid with overwrite "
6988 goto sanitize_bailout;
6992 if (quiet == 0 && ycount == 0) {
6993 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6994 "following device:\n");
6996 if (dt == CC_DT_SCSI) {
6997 error = scsidoinquiry(device, argc, argv, combinedopt,
6998 task_attr, retry_count, timeout);
6999 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7000 struct ata_params *ident_buf;
7001 error = ata_do_identify(device, retry_count, timeout,
7004 printf("%s%d: ", device->device_name,
7005 device->dev_unit_num);
7006 ata_print_ident(ident_buf);
7013 warnx("sanitize: error sending inquiry");
7014 goto sanitize_bailout;
7019 if (!get_confirmation()) {
7021 goto sanitize_bailout;
7026 use_timeout = timeout;
7028 use_timeout = (immediate ? 10 : 10800) * 1000;
7030 if (immediate == 0 && quiet == 0) {
7031 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
7032 use_timeout / 1000);
7036 * If the user hasn't disabled questions and didn't specify a
7037 * timeout on the command line, ask them if they want the current
7040 if (immediate == 0 && ycount == 0 && timeout == 0) {
7042 int new_timeout = 0;
7044 fprintf(stdout, "Enter new timeout in seconds or press\n"
7045 "return to keep the current timeout [%d] ",
7046 use_timeout / 1000);
7048 if (fgets(str, sizeof(str), stdin) != NULL) {
7050 new_timeout = atoi(str);
7053 if (new_timeout != 0) {
7054 use_timeout = new_timeout * 1000;
7055 fprintf(stdout, "Using new timeout value %d\n",
7056 use_timeout / 1000);
7060 if (dt == CC_DT_SCSI) {
7063 byte2 |= SSZ_UNRESTRICTED_EXIT;
7066 scsi_sanitize(&ccb->csio,
7067 /* retries */ retry_count,
7069 /* tag_action */ task_attr,
7072 /* data_ptr */ data_ptr,
7073 /* dxfer_len */ dxfer_len,
7074 /* sense_len */ SSD_FULL_SIZE,
7075 /* timeout */ use_timeout);
7077 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7078 if (arglist & CAM_ARG_ERR_RECOVER)
7079 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7080 if (cam_send_ccb(device, ccb) < 0) {
7081 warn("error sending sanitize command");
7083 goto sanitize_bailout;
7085 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7086 if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
7087 feature = 0x14; /* OVERWRITE EXT */
7088 lba = 0x4F5700000000 | scsi_4btoul(data_ptr + 4);
7089 count = (passes == 0) ? 1 : (passes >= 16) ? 0 : passes;
7091 count |= 0x80; /* INVERT PATTERN */
7093 count |= 0x10; /* FAILURE MODE */
7094 } else if (action == SSZ_SERVICE_ACTION_BLOCK_ERASE) {
7095 feature = 0x12; /* BLOCK ERASE EXT */
7096 lba = 0x0000426B4572;
7099 count |= 0x10; /* FAILURE MODE */
7100 } else if (action == SSZ_SERVICE_ACTION_CRYPTO_ERASE) {
7101 feature = 0x11; /* CRYPTO SCRAMBLE EXT */
7102 lba = 0x000043727970;
7105 count |= 0x10; /* FAILURE MODE */
7106 } else if (action == SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE) {
7107 feature = 0x00; /* SANITIZE STATUS EXT */
7109 count = 1; /* CLEAR SANITIZE OPERATION FAILED */
7112 goto sanitize_bailout;
7115 error = ata_do_cmd(device,
7118 /*flags*/CAM_DIR_NONE,
7119 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
7121 /*tag_action*/MSG_SIMPLE_Q_TAG,
7122 /*command*/ATA_SANITIZE,
7123 /*features*/feature,
7125 /*sector_count*/count,
7128 /*timeout*/ use_timeout,
7132 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7133 struct scsi_sense_data *sense;
7134 int error_code, sense_key, asc, ascq;
7136 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
7137 CAM_SCSI_STATUS_ERROR) {
7138 sense = &ccb->csio.sense_data;
7139 scsi_extract_sense_len(sense, ccb->csio.sense_len -
7140 ccb->csio.sense_resid, &error_code, &sense_key,
7141 &asc, &ascq, /*show_errors*/ 1);
7143 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
7144 asc == 0x20 && ascq == 0x00)
7145 warnx("sanitize is not supported by "
7148 warnx("error sanitizing this device");
7150 warnx("error sanitizing this device");
7152 if (arglist & CAM_ARG_VERBOSE) {
7153 cam_error_print(device, ccb, CAM_ESF_ALL,
7154 CAM_EPF_ALL, stderr);
7157 goto sanitize_bailout;
7161 * If we ran in non-immediate mode, we already checked for errors
7162 * above and printed out any necessary information. If we're in
7163 * immediate mode, we need to loop through and get status
7164 * information periodically.
7166 if (immediate == 0) {
7168 fprintf(stdout, "Sanitize Complete\n");
7170 goto sanitize_bailout;
7174 if (dt == CC_DT_SCSI) {
7175 error = sanitize_wait_scsi(device, ccb, task_attr, quiet);
7176 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7177 error = sanitize_wait_ata(device, ccb, quiet, dt);
7180 if (error == 0 && quiet == 0)
7181 fprintf(stdout, "Sanitize Complete \n");
7186 if (data_ptr != NULL)
7194 scsireportluns(struct cam_device *device, int argc, char **argv,
7195 char *combinedopt, int task_attr, int retry_count, int timeout)
7198 int c, countonly, lunsonly;
7199 struct scsi_report_luns_data *lundata;
7201 uint8_t report_type;
7202 uint32_t list_len, i, j;
7207 report_type = RPL_REPORT_DEFAULT;
7208 ccb = cam_getccb(device);
7211 warnx("%s: error allocating ccb", __func__);
7215 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7220 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7229 if (strcasecmp(optarg, "default") == 0)
7230 report_type = RPL_REPORT_DEFAULT;
7231 else if (strcasecmp(optarg, "wellknown") == 0)
7232 report_type = RPL_REPORT_WELLKNOWN;
7233 else if (strcasecmp(optarg, "all") == 0)
7234 report_type = RPL_REPORT_ALL;
7236 warnx("%s: invalid report type \"%s\"",
7247 if ((countonly != 0)
7248 && (lunsonly != 0)) {
7249 warnx("%s: you can only specify one of -c or -l", __func__);
7254 * According to SPC-4, the allocation length must be at least 16
7255 * bytes -- enough for the header and one LUN.
7257 alloc_len = sizeof(*lundata) + 8;
7261 lundata = malloc(alloc_len);
7263 if (lundata == NULL) {
7264 warn("%s: error mallocing %d bytes", __func__, alloc_len);
7269 scsi_report_luns(&ccb->csio,
7270 /*retries*/ retry_count,
7272 /*tag_action*/ task_attr,
7273 /*select_report*/ report_type,
7274 /*rpl_buf*/ lundata,
7275 /*alloc_len*/ alloc_len,
7276 /*sense_len*/ SSD_FULL_SIZE,
7277 /*timeout*/ timeout ? timeout : 5000);
7279 /* Disable freezing the device queue */
7280 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7282 if (arglist & CAM_ARG_ERR_RECOVER)
7283 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7285 if (cam_send_ccb(device, ccb) < 0) {
7286 warn("error sending REPORT LUNS command");
7291 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7292 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7298 list_len = scsi_4btoul(lundata->length);
7301 * If we need to list the LUNs, and our allocation
7302 * length was too short, reallocate and retry.
7304 if ((countonly == 0)
7305 && (list_len > (alloc_len - sizeof(*lundata)))) {
7306 alloc_len = list_len + sizeof(*lundata);
7312 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7313 ((list_len / 8) > 1) ? "s" : "");
7318 for (i = 0; i < (list_len / 8); i++) {
7322 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7324 fprintf(stdout, ",");
7325 switch (lundata->luns[i].lundata[j] &
7326 RPL_LUNDATA_ATYP_MASK) {
7327 case RPL_LUNDATA_ATYP_PERIPH:
7328 if ((lundata->luns[i].lundata[j] &
7329 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7330 fprintf(stdout, "%d:",
7331 lundata->luns[i].lundata[j] &
7332 RPL_LUNDATA_PERIPH_BUS_MASK);
7334 && ((lundata->luns[i].lundata[j+2] &
7335 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7338 fprintf(stdout, "%d",
7339 lundata->luns[i].lundata[j+1]);
7341 case RPL_LUNDATA_ATYP_FLAT: {
7343 tmplun[0] = lundata->luns[i].lundata[j] &
7344 RPL_LUNDATA_FLAT_LUN_MASK;
7345 tmplun[1] = lundata->luns[i].lundata[j+1];
7347 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7351 case RPL_LUNDATA_ATYP_LUN:
7352 fprintf(stdout, "%d:%d:%d",
7353 (lundata->luns[i].lundata[j+1] &
7354 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7355 lundata->luns[i].lundata[j] &
7356 RPL_LUNDATA_LUN_TARG_MASK,
7357 lundata->luns[i].lundata[j+1] &
7358 RPL_LUNDATA_LUN_LUN_MASK);
7360 case RPL_LUNDATA_ATYP_EXTLUN: {
7361 int field_len_code, eam_code;
7363 eam_code = lundata->luns[i].lundata[j] &
7364 RPL_LUNDATA_EXT_EAM_MASK;
7365 field_len_code = (lundata->luns[i].lundata[j] &
7366 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7368 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7369 && (field_len_code == 0x00)) {
7370 fprintf(stdout, "%d",
7371 lundata->luns[i].lundata[j+1]);
7372 } else if ((eam_code ==
7373 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7374 && (field_len_code == 0x03)) {
7378 * This format takes up all 8 bytes.
7379 * If we aren't starting at offset 0,
7383 fprintf(stdout, "Invalid "
7386 "specified format", j);
7390 bzero(tmp_lun, sizeof(tmp_lun));
7391 bcopy(&lundata->luns[i].lundata[j+1],
7392 &tmp_lun[1], sizeof(tmp_lun) - 1);
7393 fprintf(stdout, "%#jx",
7394 (intmax_t)scsi_8btou64(tmp_lun));
7397 fprintf(stderr, "Unknown Extended LUN"
7398 "Address method %#x, length "
7399 "code %#x", eam_code,
7406 fprintf(stderr, "Unknown LUN address method "
7407 "%#x\n", lundata->luns[i].lundata[0] &
7408 RPL_LUNDATA_ATYP_MASK);
7412 * For the flat addressing method, there are no
7413 * other levels after it.
7418 fprintf(stdout, "\n");
7431 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7432 char *combinedopt, int task_attr, int retry_count, int timeout)
7435 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7436 struct scsi_read_capacity_data rcap;
7437 struct scsi_read_capacity_data_long rcaplong;
7452 ccb = cam_getccb(device);
7455 warnx("%s: error allocating ccb", __func__);
7459 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7461 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7491 if ((blocksizeonly != 0)
7492 && (numblocks != 0)) {
7493 warnx("%s: you can only specify one of -b or -N", __func__);
7498 if ((blocksizeonly != 0)
7499 && (sizeonly != 0)) {
7500 warnx("%s: you can only specify one of -b or -s", __func__);
7507 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7513 && (blocksizeonly != 0)) {
7514 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7522 scsi_read_capacity(&ccb->csio,
7523 /*retries*/ retry_count,
7525 /*tag_action*/ task_attr,
7528 /*timeout*/ timeout ? timeout : 5000);
7530 /* Disable freezing the device queue */
7531 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7533 if (arglist & CAM_ARG_ERR_RECOVER)
7534 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7536 if (cam_send_ccb(device, ccb) < 0) {
7537 warn("error sending READ CAPACITY command");
7542 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7543 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7548 maxsector = scsi_4btoul(rcap.addr);
7549 block_len = scsi_4btoul(rcap.length);
7552 * A last block of 2^32-1 means that the true capacity is over 2TB,
7553 * and we need to issue the long READ CAPACITY to get the real
7554 * capacity. Otherwise, we're all set.
7556 if (maxsector != 0xffffffff)
7560 scsi_read_capacity_16(&ccb->csio,
7561 /*retries*/ retry_count,
7563 /*tag_action*/ task_attr,
7567 /*rcap_buf*/ (uint8_t *)&rcaplong,
7568 /*rcap_buf_len*/ sizeof(rcaplong),
7569 /*sense_len*/ SSD_FULL_SIZE,
7570 /*timeout*/ timeout ? timeout : 5000);
7572 /* Disable freezing the device queue */
7573 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7575 if (arglist & CAM_ARG_ERR_RECOVER)
7576 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7578 if (cam_send_ccb(device, ccb) < 0) {
7579 warn("error sending READ CAPACITY (16) command");
7584 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7585 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7590 maxsector = scsi_8btou64(rcaplong.addr);
7591 block_len = scsi_4btoul(rcaplong.length);
7594 if (blocksizeonly == 0) {
7596 * Humanize implies !quiet, and also implies numblocks.
7598 if (humanize != 0) {
7603 tmpbytes = (maxsector + 1) * block_len;
7604 ret = humanize_number(tmpstr, sizeof(tmpstr),
7605 tmpbytes, "", HN_AUTOSCALE,
7608 HN_DIVISOR_1000 : 0));
7610 warnx("%s: humanize_number failed!", __func__);
7614 fprintf(stdout, "Device Size: %s%s", tmpstr,
7615 (sizeonly == 0) ? ", " : "\n");
7616 } else if (numblocks != 0) {
7617 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7618 "Blocks: " : "", (uintmax_t)maxsector + 1,
7619 (sizeonly == 0) ? ", " : "\n");
7621 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7622 "Last Block: " : "", (uintmax_t)maxsector,
7623 (sizeonly == 0) ? ", " : "\n");
7627 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7628 "Block Length: " : "", block_len, (quiet == 0) ?
7637 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7638 int retry_count, int timeout)
7642 uint8_t *smp_request = NULL, *smp_response = NULL;
7643 int request_size = 0, response_size = 0;
7644 int fd_request = 0, fd_response = 0;
7645 char *datastr = NULL;
7646 struct get_hook hook;
7651 * Note that at the moment we don't support sending SMP CCBs to
7652 * devices that aren't probed by CAM.
7654 ccb = cam_getccb(device);
7656 warnx("%s: error allocating CCB", __func__);
7660 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7662 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7665 arglist |= CAM_ARG_CMD_IN;
7666 response_size = strtol(optarg, NULL, 0);
7667 if (response_size <= 0) {
7668 warnx("invalid number of response bytes %d",
7671 goto smpcmd_bailout;
7673 hook.argc = argc - optind;
7674 hook.argv = argv + optind;
7677 datastr = cget(&hook, NULL);
7679 * If the user supplied "-" instead of a format, he
7680 * wants the data to be written to stdout.
7682 if ((datastr != NULL)
7683 && (datastr[0] == '-'))
7686 smp_response = (u_int8_t *)malloc(response_size);
7687 if (smp_response == NULL) {
7688 warn("can't malloc memory for SMP response");
7690 goto smpcmd_bailout;
7694 arglist |= CAM_ARG_CMD_OUT;
7695 request_size = strtol(optarg, NULL, 0);
7696 if (request_size <= 0) {
7697 warnx("invalid number of request bytes %d",
7700 goto smpcmd_bailout;
7702 hook.argc = argc - optind;
7703 hook.argv = argv + optind;
7705 datastr = cget(&hook, NULL);
7706 smp_request = (u_int8_t *)malloc(request_size);
7707 if (smp_request == NULL) {
7708 warn("can't malloc memory for SMP request");
7710 goto smpcmd_bailout;
7712 bzero(smp_request, request_size);
7714 * If the user supplied "-" instead of a format, he
7715 * wants the data to be read from stdin.
7717 if ((datastr != NULL)
7718 && (datastr[0] == '-'))
7721 buff_encode_visit(smp_request, request_size,
7732 * If fd_data is set, and we're writing to the device, we need to
7733 * read the data the user wants written from stdin.
7735 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7737 int amt_to_read = request_size;
7738 u_int8_t *buf_ptr = smp_request;
7740 for (amt_read = 0; amt_to_read > 0;
7741 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7742 if (amt_read == -1) {
7743 warn("error reading data from stdin");
7745 goto smpcmd_bailout;
7747 amt_to_read -= amt_read;
7748 buf_ptr += amt_read;
7752 if (((arglist & CAM_ARG_CMD_IN) == 0)
7753 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7754 warnx("%s: need both the request (-r) and response (-R) "
7755 "arguments", __func__);
7757 goto smpcmd_bailout;
7760 flags |= CAM_DEV_QFRZDIS;
7762 cam_fill_smpio(&ccb->smpio,
7763 /*retries*/ retry_count,
7766 /*smp_request*/ smp_request,
7767 /*smp_request_len*/ request_size,
7768 /*smp_response*/ smp_response,
7769 /*smp_response_len*/ response_size,
7770 /*timeout*/ timeout ? timeout : 5000);
7772 ccb->smpio.flags = SMP_FLAG_NONE;
7774 if (((retval = cam_send_ccb(device, ccb)) < 0)
7775 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7776 const char warnstr[] = "error sending command";
7783 if (arglist & CAM_ARG_VERBOSE) {
7784 cam_error_print(device, ccb, CAM_ESF_ALL,
7785 CAM_EPF_ALL, stderr);
7789 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7790 && (response_size > 0)) {
7791 if (fd_response == 0) {
7792 buff_decode_visit(smp_response, response_size,
7793 datastr, arg_put, NULL);
7794 fprintf(stdout, "\n");
7796 ssize_t amt_written;
7797 int amt_to_write = response_size;
7798 u_int8_t *buf_ptr = smp_response;
7800 for (amt_written = 0; (amt_to_write > 0) &&
7801 (amt_written = write(STDOUT_FILENO, buf_ptr,
7802 amt_to_write)) > 0;){
7803 amt_to_write -= amt_written;
7804 buf_ptr += amt_written;
7806 if (amt_written == -1) {
7807 warn("error writing data to stdout");
7809 goto smpcmd_bailout;
7810 } else if ((amt_written == 0)
7811 && (amt_to_write > 0)) {
7812 warnx("only wrote %u bytes out of %u",
7813 response_size - amt_to_write,
7822 if (smp_request != NULL)
7825 if (smp_response != NULL)
7832 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7833 int retry_count, int timeout)
7837 int32_t mmc_opcode = 0, mmc_arg = 0;
7838 int32_t mmc_flags = -1;
7841 int is_bw_4 = 0, is_bw_1 = 0;
7842 int is_highspeed = 0, is_stdspeed = 0;
7843 int is_info_request = 0;
7845 uint8_t mmc_data_byte = 0;
7847 /* For IO_RW_EXTENDED command */
7848 uint8_t *mmc_data = NULL;
7849 struct mmc_data mmc_d;
7850 int mmc_data_len = 0;
7853 * Note that at the moment we don't support sending SMP CCBs to
7854 * devices that aren't probed by CAM.
7856 ccb = cam_getccb(device);
7858 warnx("%s: error allocating CCB", __func__);
7862 bzero(&(&ccb->ccb_h)[1],
7863 sizeof(union ccb) - sizeof(struct ccb_hdr));
7865 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7874 if (!strcmp(optarg, "high"))
7880 is_info_request = 1;
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");
7987 // Switch bus speed instead of sending IO command
7988 if (is_stdspeed || is_highspeed) {
7989 struct ccb_trans_settings_mmc *cts;
7990 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7991 ccb->ccb_h.flags = 0;
7992 cts = &ccb->cts.proto_specific.mmc;
7993 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
7994 cts->ios_valid = MMC_BT;
7995 if (((retval = cam_send_ccb(device, ccb)) < 0)
7996 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7997 warn("Error sending command");
7999 printf("Speed set OK (HS: %d)\n", is_highspeed);
8005 // Get information about controller and its settings
8006 if (is_info_request) {
8007 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
8008 ccb->ccb_h.flags = 0;
8009 struct ccb_trans_settings_mmc *cts;
8010 cts = &ccb->cts.proto_specific.mmc;
8011 if (((retval = cam_send_ccb(device, ccb)) < 0)
8012 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8013 warn("Error sending command");
8016 printf("Host controller information\n");
8017 printf("Host OCR: 0x%x\n", cts->host_ocr);
8018 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
8019 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
8020 printf("Supported bus width: ");
8021 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
8023 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
8025 printf("\nCurrent settings:\n");
8026 printf("Bus width: ");
8027 switch (cts->ios.bus_width) {
8038 printf("Freq: %d.%03d MHz%s\n",
8039 cts->ios.clock / 1000000,
8040 (cts->ios.clock / 1000) % 1000,
8041 cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : "");
8045 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
8047 if (mmc_data_len > 0) {
8048 flags |= CAM_DIR_IN;
8049 mmc_data = malloc(mmc_data_len);
8050 memset(mmc_data, 0, mmc_data_len);
8051 memset(&mmc_d, 0, sizeof(mmc_d));
8052 mmc_d.len = mmc_data_len;
8053 mmc_d.data = mmc_data;
8054 mmc_d.flags = MMC_DATA_READ;
8055 } else flags |= CAM_DIR_NONE;
8057 cam_fill_mmcio(&ccb->mmcio,
8058 /*retries*/ retry_count,
8061 /*mmc_opcode*/ mmc_opcode,
8062 /*mmc_arg*/ mmc_arg,
8063 /*mmc_flags*/ mmc_flags,
8064 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
8065 /*timeout*/ timeout ? timeout : 5000);
8067 if (((retval = cam_send_ccb(device, ccb)) < 0)
8068 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8069 const char warnstr[] = "error sending command";
8076 if (arglist & CAM_ARG_VERBOSE) {
8077 cam_error_print(device, ccb, CAM_ESF_ALL,
8078 CAM_EPF_ALL, stderr);
8082 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
8083 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
8084 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
8085 ccb->mmcio.cmd.resp[1],
8086 ccb->mmcio.cmd.resp[2],
8087 ccb->mmcio.cmd.resp[3]);
8089 switch (mmc_opcode) {
8090 case SD_IO_RW_DIRECT:
8091 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
8092 SD_R5_DATA(ccb->mmcio.cmd.resp),
8093 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
8095 case SD_IO_RW_EXTENDED:
8096 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
8097 hexdump(mmc_data, mmc_data_len, NULL, 0);
8099 case SD_SEND_RELATIVE_ADDR:
8100 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
8103 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
8110 if (mmc_data_len > 0 && mmc_data != NULL)
8117 smpreportgeneral(struct cam_device *device, int argc, char **argv,
8118 char *combinedopt, int retry_count, int timeout)
8121 struct smp_report_general_request *request = NULL;
8122 struct smp_report_general_response *response = NULL;
8123 struct sbuf *sb = NULL;
8125 int c, long_response = 0;
8129 * Note that at the moment we don't support sending SMP CCBs to
8130 * devices that aren't probed by CAM.
8132 ccb = cam_getccb(device);
8134 warnx("%s: error allocating CCB", __func__);
8138 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8140 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8149 request = malloc(sizeof(*request));
8150 if (request == NULL) {
8151 warn("%s: unable to allocate %zd bytes", __func__,
8157 response = malloc(sizeof(*response));
8158 if (response == NULL) {
8159 warn("%s: unable to allocate %zd bytes", __func__,
8166 smp_report_general(&ccb->smpio,
8170 /*request_len*/ sizeof(*request),
8171 (uint8_t *)response,
8172 /*response_len*/ sizeof(*response),
8173 /*long_response*/ long_response,
8176 if (((retval = cam_send_ccb(device, ccb)) < 0)
8177 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8178 const char warnstr[] = "error sending command";
8185 if (arglist & CAM_ARG_VERBOSE) {
8186 cam_error_print(device, ccb, CAM_ESF_ALL,
8187 CAM_EPF_ALL, stderr);
8194 * If the device supports the long response bit, try again and see
8195 * if we can get all of the data.
8197 if ((response->long_response & SMP_RG_LONG_RESPONSE)
8198 && (long_response == 0)) {
8199 ccb->ccb_h.status = CAM_REQ_INPROG;
8200 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8206 * XXX KDM detect and decode SMP errors here.
8208 sb = sbuf_new_auto();
8210 warnx("%s: error allocating sbuf", __func__);
8214 smp_report_general_sbuf(response, sizeof(*response), sb);
8216 if (sbuf_finish(sb) != 0) {
8217 warnx("%s: sbuf_finish", __func__);
8221 printf("%s", sbuf_data(sb));
8227 if (request != NULL)
8230 if (response != NULL)
8239 static struct camcontrol_opts phy_ops[] = {
8240 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
8241 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
8242 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
8243 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
8244 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
8245 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
8246 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
8247 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
8248 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
8253 smpphycontrol(struct cam_device *device, int argc, char **argv,
8254 char *combinedopt, int retry_count, int timeout)
8257 struct smp_phy_control_request *request = NULL;
8258 struct smp_phy_control_response *response = NULL;
8259 int long_response = 0;
8262 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
8264 uint64_t attached_dev_name = 0;
8265 int dev_name_set = 0;
8266 uint32_t min_plr = 0, max_plr = 0;
8267 uint32_t pp_timeout_val = 0;
8268 int slumber_partial = 0;
8269 int set_pp_timeout_val = 0;
8273 * Note that at the moment we don't support sending SMP CCBs to
8274 * devices that aren't probed by CAM.
8276 ccb = cam_getccb(device);
8278 warnx("%s: error allocating CCB", __func__);
8282 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8284 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8292 if (strcasecmp(optarg, "enable") == 0)
8294 else if (strcasecmp(optarg, "disable") == 0)
8297 warnx("%s: Invalid argument %s", __func__,
8304 slumber_partial |= enable <<
8305 SMP_PC_SAS_SLUMBER_SHIFT;
8308 slumber_partial |= enable <<
8309 SMP_PC_SAS_PARTIAL_SHIFT;
8312 slumber_partial |= enable <<
8313 SMP_PC_SATA_SLUMBER_SHIFT;
8316 slumber_partial |= enable <<
8317 SMP_PC_SATA_PARTIAL_SHIFT;
8320 warnx("%s: programmer error", __func__);
8323 break; /*NOTREACHED*/
8328 attached_dev_name = (uintmax_t)strtoumax(optarg,
8337 * We don't do extensive checking here, so this
8338 * will continue to work when new speeds come out.
8340 min_plr = strtoul(optarg, NULL, 0);
8342 || (min_plr > 0xf)) {
8343 warnx("%s: invalid link rate %x",
8351 * We don't do extensive checking here, so this
8352 * will continue to work when new speeds come out.
8354 max_plr = strtoul(optarg, NULL, 0);
8356 || (max_plr > 0xf)) {
8357 warnx("%s: invalid link rate %x",
8364 camcontrol_optret optreturn;
8365 cam_argmask argnums;
8368 if (phy_op_set != 0) {
8369 warnx("%s: only one phy operation argument "
8370 "(-o) allowed", __func__);
8378 * Allow the user to specify the phy operation
8379 * numerically, as well as with a name. This will
8380 * future-proof it a bit, so options that are added
8381 * in future specs can be used.
8383 if (isdigit(optarg[0])) {
8384 phy_operation = strtoul(optarg, NULL, 0);
8385 if ((phy_operation == 0)
8386 || (phy_operation > 0xff)) {
8387 warnx("%s: invalid phy operation %#x",
8388 __func__, phy_operation);
8394 optreturn = getoption(phy_ops, optarg, &phy_operation,
8397 if (optreturn == CC_OR_AMBIGUOUS) {
8398 warnx("%s: ambiguous option %s", __func__,
8403 } else if (optreturn == CC_OR_NOT_FOUND) {
8404 warnx("%s: option %s not found", __func__,
8416 pp_timeout_val = strtoul(optarg, NULL, 0);
8417 if (pp_timeout_val > 15) {
8418 warnx("%s: invalid partial pathway timeout "
8419 "value %u, need a value less than 16",
8420 __func__, pp_timeout_val);
8424 set_pp_timeout_val = 1;
8432 warnx("%s: a PHY (-p phy) argument is required",__func__);
8437 if (((dev_name_set != 0)
8438 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8439 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8440 && (dev_name_set == 0))) {
8441 warnx("%s: -d name and -o setdevname arguments both "
8442 "required to set device name", __func__);
8447 request = malloc(sizeof(*request));
8448 if (request == NULL) {
8449 warn("%s: unable to allocate %zd bytes", __func__,
8455 response = malloc(sizeof(*response));
8456 if (response == NULL) {
8457 warn("%s: unable to allocate %zd bytes", __func__,
8463 smp_phy_control(&ccb->smpio,
8468 (uint8_t *)response,
8471 /*expected_exp_change_count*/ 0,
8474 (set_pp_timeout_val != 0) ? 1 : 0,
8482 if (((retval = cam_send_ccb(device, ccb)) < 0)
8483 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8484 const char warnstr[] = "error sending command";
8491 if (arglist & CAM_ARG_VERBOSE) {
8493 * Use CAM_EPF_NORMAL so we only get one line of
8494 * SMP command decoding.
8496 cam_error_print(device, ccb, CAM_ESF_ALL,
8497 CAM_EPF_NORMAL, stderr);
8503 /* XXX KDM print out something here for success? */
8508 if (request != NULL)
8511 if (response != NULL)
8518 smpmaninfo(struct cam_device *device, int argc, char **argv,
8519 char *combinedopt, int retry_count, int timeout)
8522 struct smp_report_manuf_info_request request;
8523 struct smp_report_manuf_info_response response;
8524 struct sbuf *sb = NULL;
8525 int long_response = 0;
8530 * Note that at the moment we don't support sending SMP CCBs to
8531 * devices that aren't probed by CAM.
8533 ccb = cam_getccb(device);
8535 warnx("%s: error allocating CCB", __func__);
8539 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8541 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8550 bzero(&request, sizeof(request));
8551 bzero(&response, sizeof(response));
8553 smp_report_manuf_info(&ccb->smpio,
8558 (uint8_t *)&response,
8563 if (((retval = cam_send_ccb(device, ccb)) < 0)
8564 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8565 const char warnstr[] = "error sending command";
8572 if (arglist & CAM_ARG_VERBOSE) {
8573 cam_error_print(device, ccb, CAM_ESF_ALL,
8574 CAM_EPF_ALL, stderr);
8580 sb = sbuf_new_auto();
8582 warnx("%s: error allocating sbuf", __func__);
8586 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8588 if (sbuf_finish(sb) != 0) {
8589 warnx("%s: sbuf_finish", __func__);
8593 printf("%s", sbuf_data(sb));
8607 getdevid(struct cam_devitem *item)
8610 union ccb *ccb = NULL;
8612 struct cam_device *dev;
8614 dev = cam_open_btl(item->dev_match.path_id,
8615 item->dev_match.target_id,
8616 item->dev_match.target_lun, O_RDWR, NULL);
8619 warnx("%s", cam_errbuf);
8624 item->device_id_len = 0;
8626 ccb = cam_getccb(dev);
8628 warnx("%s: error allocating CCB", __func__);
8633 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8636 * On the first try, we just probe for the size of the data, and
8637 * then allocate that much memory and try again.
8640 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8641 ccb->ccb_h.flags = CAM_DIR_IN;
8642 ccb->cdai.flags = CDAI_FLAG_NONE;
8643 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8644 ccb->cdai.bufsiz = item->device_id_len;
8645 if (item->device_id_len != 0)
8646 ccb->cdai.buf = (uint8_t *)item->device_id;
8648 if (cam_send_ccb(dev, ccb) < 0) {
8649 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8654 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8655 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8660 if (item->device_id_len == 0) {
8662 * This is our first time through. Allocate the buffer,
8663 * and then go back to get the data.
8665 if (ccb->cdai.provsiz == 0) {
8666 warnx("%s: invalid .provsiz field returned with "
8667 "XPT_GDEV_ADVINFO CCB", __func__);
8671 item->device_id_len = ccb->cdai.provsiz;
8672 item->device_id = malloc(item->device_id_len);
8673 if (item->device_id == NULL) {
8674 warn("%s: unable to allocate %d bytes", __func__,
8675 item->device_id_len);
8679 ccb->ccb_h.status = CAM_REQ_INPROG;
8685 cam_close_device(dev);
8694 * XXX KDM merge this code with getdevtree()?
8697 buildbusdevlist(struct cam_devlist *devlist)
8700 int bufsize, fd = -1;
8701 struct dev_match_pattern *patterns;
8702 struct cam_devitem *item = NULL;
8703 int skip_device = 0;
8706 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8707 warn("couldn't open %s", XPT_DEVICE);
8711 bzero(&ccb, sizeof(union ccb));
8713 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8714 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8715 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8717 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8718 bufsize = sizeof(struct dev_match_result) * 100;
8719 ccb.cdm.match_buf_len = bufsize;
8720 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8721 if (ccb.cdm.matches == NULL) {
8722 warnx("can't malloc memory for matches");
8726 ccb.cdm.num_matches = 0;
8727 ccb.cdm.num_patterns = 2;
8728 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8729 ccb.cdm.num_patterns;
8731 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8732 if (patterns == NULL) {
8733 warnx("can't malloc memory for patterns");
8738 ccb.cdm.patterns = patterns;
8739 bzero(patterns, ccb.cdm.pattern_buf_len);
8741 patterns[0].type = DEV_MATCH_DEVICE;
8742 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8743 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8744 patterns[1].type = DEV_MATCH_PERIPH;
8745 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8746 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8749 * We do the ioctl multiple times if necessary, in case there are
8750 * more than 100 nodes in the EDT.
8755 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8756 warn("error sending CAMIOCOMMAND ioctl");
8761 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8762 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8763 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8764 warnx("got CAM error %#x, CDM error %d\n",
8765 ccb.ccb_h.status, ccb.cdm.status);
8770 for (i = 0; i < ccb.cdm.num_matches; i++) {
8771 switch (ccb.cdm.matches[i].type) {
8772 case DEV_MATCH_DEVICE: {
8773 struct device_match_result *dev_result;
8776 &ccb.cdm.matches[i].result.device_result;
8778 if (dev_result->flags &
8779 DEV_RESULT_UNCONFIGURED) {
8785 item = malloc(sizeof(*item));
8787 warn("%s: unable to allocate %zd bytes",
8788 __func__, sizeof(*item));
8792 bzero(item, sizeof(*item));
8793 bcopy(dev_result, &item->dev_match,
8794 sizeof(*dev_result));
8795 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8798 if (getdevid(item) != 0) {
8804 case DEV_MATCH_PERIPH: {
8805 struct periph_match_result *periph_result;
8808 &ccb.cdm.matches[i].result.periph_result;
8810 if (skip_device != 0)
8812 item->num_periphs++;
8813 item->periph_matches = realloc(
8814 item->periph_matches,
8816 sizeof(struct periph_match_result));
8817 if (item->periph_matches == NULL) {
8818 warn("%s: error allocating periph "
8823 bcopy(periph_result, &item->periph_matches[
8824 item->num_periphs - 1],
8825 sizeof(*periph_result));
8829 fprintf(stderr, "%s: unexpected match "
8830 "type %d\n", __func__,
8831 ccb.cdm.matches[i].type);
8834 break; /*NOTREACHED*/
8837 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8838 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8846 free(ccb.cdm.matches);
8849 freebusdevlist(devlist);
8855 freebusdevlist(struct cam_devlist *devlist)
8857 struct cam_devitem *item, *item2;
8859 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8860 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8862 free(item->device_id);
8863 free(item->periph_matches);
8868 static struct cam_devitem *
8869 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8871 struct cam_devitem *item;
8873 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8874 struct scsi_vpd_id_descriptor *idd;
8877 * XXX KDM look for LUN IDs as well?
8879 idd = scsi_get_devid(item->device_id,
8880 item->device_id_len,
8881 scsi_devid_is_sas_target);
8885 if (scsi_8btou64(idd->identifier) == sasaddr)
8893 smpphylist(struct cam_device *device, int argc, char **argv,
8894 char *combinedopt, int retry_count, int timeout)
8896 struct smp_report_general_request *rgrequest = NULL;
8897 struct smp_report_general_response *rgresponse = NULL;
8898 struct smp_discover_request *disrequest = NULL;
8899 struct smp_discover_response *disresponse = NULL;
8900 struct cam_devlist devlist;
8902 int long_response = 0;
8909 * Note that at the moment we don't support sending SMP CCBs to
8910 * devices that aren't probed by CAM.
8912 ccb = cam_getccb(device);
8914 warnx("%s: error allocating CCB", __func__);
8918 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8919 STAILQ_INIT(&devlist.dev_queue);
8921 rgrequest = malloc(sizeof(*rgrequest));
8922 if (rgrequest == NULL) {
8923 warn("%s: unable to allocate %zd bytes", __func__,
8924 sizeof(*rgrequest));
8929 rgresponse = malloc(sizeof(*rgresponse));
8930 if (rgresponse == NULL) {
8931 warn("%s: unable to allocate %zd bytes", __func__,
8932 sizeof(*rgresponse));
8937 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8950 smp_report_general(&ccb->smpio,
8954 /*request_len*/ sizeof(*rgrequest),
8955 (uint8_t *)rgresponse,
8956 /*response_len*/ sizeof(*rgresponse),
8957 /*long_response*/ long_response,
8960 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8962 if (((retval = cam_send_ccb(device, ccb)) < 0)
8963 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8964 const char warnstr[] = "error sending command";
8971 if (arglist & CAM_ARG_VERBOSE) {
8972 cam_error_print(device, ccb, CAM_ESF_ALL,
8973 CAM_EPF_ALL, stderr);
8979 num_phys = rgresponse->num_phys;
8981 if (num_phys == 0) {
8983 fprintf(stdout, "%s: No Phys reported\n", __func__);
8988 devlist.path_id = device->path_id;
8990 retval = buildbusdevlist(&devlist);
8995 fprintf(stdout, "%d PHYs:\n", num_phys);
8996 fprintf(stdout, "PHY Attached SAS Address\n");
8999 disrequest = malloc(sizeof(*disrequest));
9000 if (disrequest == NULL) {
9001 warn("%s: unable to allocate %zd bytes", __func__,
9002 sizeof(*disrequest));
9007 disresponse = malloc(sizeof(*disresponse));
9008 if (disresponse == NULL) {
9009 warn("%s: unable to allocate %zd bytes", __func__,
9010 sizeof(*disresponse));
9015 for (i = 0; i < num_phys; i++) {
9016 struct cam_devitem *item;
9017 struct device_match_result *dev_match;
9018 char vendor[16], product[48], revision[16];
9022 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
9024 ccb->ccb_h.status = CAM_REQ_INPROG;
9025 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9027 smp_discover(&ccb->smpio,
9031 sizeof(*disrequest),
9032 (uint8_t *)disresponse,
9033 sizeof(*disresponse),
9035 /*ignore_zone_group*/ 0,
9039 if (((retval = cam_send_ccb(device, ccb)) < 0)
9040 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
9041 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
9042 const char warnstr[] = "error sending command";
9049 if (arglist & CAM_ARG_VERBOSE) {
9050 cam_error_print(device, ccb, CAM_ESF_ALL,
9051 CAM_EPF_ALL, stderr);
9057 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
9059 fprintf(stdout, "%3d <vacant>\n", i);
9063 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
9066 item = findsasdevice(&devlist,
9067 scsi_8btou64(disresponse->attached_sas_address));
9071 || (item != NULL)) {
9072 fprintf(stdout, "%3d 0x%016jx", i,
9073 (uintmax_t)scsi_8btou64(
9074 disresponse->attached_sas_address));
9076 fprintf(stdout, "\n");
9079 } else if (quiet != 0)
9082 dev_match = &item->dev_match;
9084 if (dev_match->protocol == PROTO_SCSI) {
9085 cam_strvis(vendor, dev_match->inq_data.vendor,
9086 sizeof(dev_match->inq_data.vendor),
9088 cam_strvis(product, dev_match->inq_data.product,
9089 sizeof(dev_match->inq_data.product),
9091 cam_strvis(revision, dev_match->inq_data.revision,
9092 sizeof(dev_match->inq_data.revision),
9094 sprintf(tmpstr, "<%s %s %s>", vendor, product,
9096 } else if ((dev_match->protocol == PROTO_ATA)
9097 || (dev_match->protocol == PROTO_SATAPM)) {
9098 cam_strvis(product, dev_match->ident_data.model,
9099 sizeof(dev_match->ident_data.model),
9101 cam_strvis(revision, dev_match->ident_data.revision,
9102 sizeof(dev_match->ident_data.revision),
9104 sprintf(tmpstr, "<%s %s>", product, revision);
9106 sprintf(tmpstr, "<>");
9108 fprintf(stdout, " %-33s ", tmpstr);
9111 * If we have 0 periphs, that's a bug...
9113 if (item->num_periphs == 0) {
9114 fprintf(stdout, "\n");
9118 fprintf(stdout, "(");
9119 for (j = 0; j < item->num_periphs; j++) {
9121 fprintf(stdout, ",");
9123 fprintf(stdout, "%s%d",
9124 item->periph_matches[j].periph_name,
9125 item->periph_matches[j].unit_number);
9128 fprintf(stdout, ")\n");
9142 freebusdevlist(&devlist);
9148 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
9150 uint8_t error = 0, ata_device = 0, status = 0;
9155 retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
9158 if (arglist & CAM_ARG_VERBOSE) {
9159 cam_error_print(device, ccb, CAM_ESF_ALL,
9160 CAM_EPF_ALL, stderr);
9162 warnx("Can't get ATA command status");
9166 if (status & ATA_STATUS_ERROR) {
9167 cam_error_print(device, ccb, CAM_ESF_ALL,
9168 CAM_EPF_ALL, stderr);
9172 printf("%s%d: ", device->device_name, device->dev_unit_num);
9175 printf("Standby mode\n");
9178 printf("Standby_y mode\n");
9181 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
9184 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
9187 printf("Idle mode\n");
9190 printf("Idle_a mode\n");
9193 printf("Idle_b mode\n");
9196 printf("Idle_c mode\n");
9199 printf("Active or Idle mode\n");
9202 printf("Unknown mode 0x%02x\n", count);
9210 atapm(struct cam_device *device, int argc, char **argv,
9211 char *combinedopt, int retry_count, int timeout)
9217 u_int8_t ata_flags = 0;
9220 ccb = cam_getccb(device);
9223 warnx("%s: error allocating ccb", __func__);
9227 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9236 if (strcmp(argv[1], "idle") == 0) {
9238 cmd = ATA_IDLE_IMMEDIATE;
9241 } else if (strcmp(argv[1], "standby") == 0) {
9243 cmd = ATA_STANDBY_IMMEDIATE;
9245 cmd = ATA_STANDBY_CMD;
9246 } else if (strcmp(argv[1], "powermode") == 0) {
9247 cmd = ATA_CHECK_POWER_MODE;
9248 ata_flags = AP_FLAG_CHK_COND;
9257 else if (t <= (240 * 5))
9259 else if (t <= (252 * 5))
9260 /* special encoding for 21 minutes */
9262 else if (t <= (11 * 30 * 60))
9263 sc = (t - 1) / (30 * 60) + 241;
9267 retval = ata_do_cmd(device,
9269 /*retries*/retry_count,
9270 /*flags*/CAM_DIR_NONE,
9271 /*protocol*/AP_PROTO_NON_DATA,
9272 /*ata_flags*/ata_flags,
9273 /*tag_action*/MSG_SIMPLE_Q_TAG,
9280 /*timeout*/timeout ? timeout : 30 * 1000,
9285 if (retval || cmd != ATA_CHECK_POWER_MODE)
9288 return (atapm_proc_resp(device, ccb));
9292 ataaxm(struct cam_device *device, int argc, char **argv,
9293 char *combinedopt, int retry_count, int timeout)
9301 ccb = cam_getccb(device);
9304 warnx("%s: error allocating ccb", __func__);
9308 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9318 if (strcmp(argv[1], "apm") == 0) {
9334 retval = ata_do_cmd(device,
9336 /*retries*/retry_count,
9337 /*flags*/CAM_DIR_NONE,
9338 /*protocol*/AP_PROTO_NON_DATA,
9340 /*tag_action*/MSG_SIMPLE_Q_TAG,
9341 /*command*/ATA_SETFEATURES,
9347 /*timeout*/timeout ? timeout : 30 * 1000,
9355 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9356 int show_sa_errors, int sa_set, int service_action,
9357 int timeout_desc, int task_attr, int retry_count, int timeout,
9358 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9360 union ccb *ccb = NULL;
9361 uint8_t *buf = NULL;
9362 uint32_t alloc_len = 0, num_opcodes;
9363 uint32_t valid_len = 0;
9364 uint32_t avail_len = 0;
9365 struct scsi_report_supported_opcodes_all *all_hdr;
9366 struct scsi_report_supported_opcodes_one *one;
9371 * Make it clear that we haven't yet allocated or filled anything.
9376 ccb = cam_getccb(device);
9378 warnx("couldn't allocate CCB");
9383 /* cam_getccb cleans up the header, caller has to zero the payload */
9384 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9386 if (opcode_set != 0) {
9387 options |= RSO_OPTIONS_OC;
9389 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9392 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9393 sizeof(struct scsi_report_supported_opcodes_descr));
9396 if (timeout_desc != 0) {
9397 options |= RSO_RCTD;
9398 alloc_len += num_opcodes *
9399 sizeof(struct scsi_report_supported_opcodes_timeout);
9403 options |= RSO_OPTIONS_OC_SA;
9404 if (show_sa_errors != 0)
9405 options &= ~RSO_OPTIONS_OC;
9414 buf = malloc(alloc_len);
9416 warn("Unable to allocate %u bytes", alloc_len);
9420 bzero(buf, alloc_len);
9422 scsi_report_supported_opcodes(&ccb->csio,
9423 /*retries*/ retry_count,
9425 /*tag_action*/ task_attr,
9426 /*options*/ options,
9427 /*req_opcode*/ opcode,
9428 /*req_service_action*/ service_action,
9430 /*dxfer_len*/ alloc_len,
9431 /*sense_len*/ SSD_FULL_SIZE,
9432 /*timeout*/ timeout ? timeout : 10000);
9434 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9436 if (retry_count != 0)
9437 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9439 if (cam_send_ccb(device, ccb) < 0) {
9440 warn("error sending REPORT SUPPORTED OPERATION CODES command");
9445 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9446 if (verbosemode != 0)
9447 cam_error_print(device, ccb, CAM_ESF_ALL,
9448 CAM_EPF_ALL, stderr);
9453 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9455 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9456 && (valid_len >= sizeof(*all_hdr))) {
9457 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9458 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9459 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9460 && (valid_len >= sizeof(*one))) {
9461 uint32_t cdb_length;
9463 one = (struct scsi_report_supported_opcodes_one *)buf;
9464 cdb_length = scsi_2btoul(one->cdb_length);
9465 avail_len = sizeof(*one) + cdb_length;
9466 if (one->support & RSO_ONE_CTDP) {
9467 struct scsi_report_supported_opcodes_timeout *td;
9469 td = (struct scsi_report_supported_opcodes_timeout *)
9471 if (valid_len >= (avail_len + sizeof(td->length))) {
9472 avail_len += scsi_2btoul(td->length) +
9475 avail_len += sizeof(*td);
9481 * avail_len could be zero if we didn't get enough data back from
9482 * thet target to determine
9484 if ((avail_len != 0)
9485 && (avail_len > valid_len)) {
9486 alloc_len = avail_len;
9490 *fill_len = valid_len;
9502 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9503 int req_sa, uint8_t *buf, uint32_t valid_len)
9505 struct scsi_report_supported_opcodes_one *one;
9506 struct scsi_report_supported_opcodes_timeout *td;
9507 uint32_t cdb_len = 0, td_len = 0;
9508 const char *op_desc = NULL;
9512 one = (struct scsi_report_supported_opcodes_one *)buf;
9515 * If we don't have the full single opcode descriptor, no point in
9518 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9520 warnx("Only %u bytes returned, not enough to verify support",
9526 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9528 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9531 printf(", SA 0x%x", req_sa);
9534 switch (one->support & RSO_ONE_SUP_MASK) {
9535 case RSO_ONE_SUP_UNAVAIL:
9536 printf("No command support information currently available\n");
9538 case RSO_ONE_SUP_NOT_SUP:
9539 printf("Command not supported\n");
9542 break; /*NOTREACHED*/
9543 case RSO_ONE_SUP_AVAIL:
9544 printf("Command is supported, complies with a SCSI standard\n");
9546 case RSO_ONE_SUP_VENDOR:
9547 printf("Command is supported, vendor-specific "
9548 "implementation\n");
9551 printf("Unknown command support flags 0x%#x\n",
9552 one->support & RSO_ONE_SUP_MASK);
9557 * If we don't have the CDB length, it isn't exactly an error, the
9558 * command probably isn't supported.
9560 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9564 cdb_len = scsi_2btoul(one->cdb_length);
9567 * If our valid data doesn't include the full reported length,
9568 * return. The caller should have detected this and adjusted his
9569 * allocation length to get all of the available data.
9571 if (valid_len < sizeof(*one) + cdb_len) {
9577 * If all we have is the opcode, there is no point in printing out
9585 printf("CDB usage bitmap:");
9586 for (i = 0; i < cdb_len; i++) {
9587 printf(" %02x", one->cdb_usage[i]);
9592 * If we don't have a timeout descriptor, we're done.
9594 if ((one->support & RSO_ONE_CTDP) == 0)
9598 * If we don't have enough valid length to include the timeout
9599 * descriptor length, we're done.
9601 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9604 td = (struct scsi_report_supported_opcodes_timeout *)
9605 &buf[sizeof(*one) + cdb_len];
9606 td_len = scsi_2btoul(td->length);
9607 td_len += sizeof(td->length);
9610 * If we don't have the full timeout descriptor, we're done.
9612 if (td_len < sizeof(*td))
9616 * If we don't have enough valid length to contain the full timeout
9617 * descriptor, we're done.
9619 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9622 printf("Timeout information:\n");
9623 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9624 printf("Nominal timeout: %u seconds\n",
9625 scsi_4btoul(td->nominal_time));
9626 printf("Recommended timeout: %u seconds\n",
9627 scsi_4btoul(td->recommended_time));
9634 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9637 struct scsi_report_supported_opcodes_all *hdr;
9638 struct scsi_report_supported_opcodes_descr *desc;
9639 uint32_t avail_len = 0, used_len = 0;
9643 if (valid_len < sizeof(*hdr)) {
9644 warnx("%s: not enough returned data (%u bytes) opcode list",
9645 __func__, valid_len);
9649 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9650 avail_len = scsi_4btoul(hdr->length);
9651 avail_len += sizeof(hdr->length);
9653 * Take the lesser of the amount of data the drive claims is
9654 * available, and the amount of data the HBA says was returned.
9656 avail_len = MIN(avail_len, valid_len);
9658 used_len = sizeof(hdr->length);
9660 printf("%-6s %4s %8s ",
9661 "Opcode", "SA", "CDB len" );
9664 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9665 printf(" Description\n");
9667 while ((avail_len - used_len) > sizeof(*desc)) {
9668 struct scsi_report_supported_opcodes_timeout *td;
9670 const char *op_desc = NULL;
9672 cur_ptr = &buf[used_len];
9673 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9675 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9676 if (op_desc == NULL)
9677 op_desc = "UNKNOWN";
9679 printf("0x%02x %#4x %8u ", desc->opcode,
9680 scsi_2btoul(desc->service_action),
9681 scsi_2btoul(desc->cdb_length));
9683 used_len += sizeof(*desc);
9685 if ((desc->flags & RSO_CTDP) == 0) {
9686 printf(" %s\n", op_desc);
9691 * If we don't have enough space to fit a timeout
9692 * descriptor, then we're done.
9694 if (avail_len - used_len < sizeof(*td)) {
9695 used_len = avail_len;
9696 printf(" %s\n", op_desc);
9699 cur_ptr = &buf[used_len];
9700 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9701 td_len = scsi_2btoul(td->length);
9702 td_len += sizeof(td->length);
9706 * If the given timeout descriptor length is less than what
9707 * we understand, skip it.
9709 if (td_len < sizeof(*td)) {
9710 printf(" %s\n", op_desc);
9714 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9715 scsi_4btoul(td->nominal_time),
9716 scsi_4btoul(td->recommended_time), op_desc);
9723 scsiopcodes(struct cam_device *device, int argc, char **argv,
9724 char *combinedopt, int task_attr, int retry_count, int timeout,
9728 uint32_t opcode = 0, service_action = 0;
9729 int td_set = 0, opcode_set = 0, sa_set = 0;
9730 int show_sa_errors = 1;
9731 uint32_t valid_len = 0;
9732 uint8_t *buf = NULL;
9736 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9742 opcode = strtoul(optarg, &endptr, 0);
9743 if (*endptr != '\0') {
9744 warnx("Invalid opcode \"%s\", must be a number",
9749 if (opcode > 0xff) {
9750 warnx("Invalid opcode 0x%#x, must be between"
9751 "0 and 0xff inclusive", opcode);
9758 service_action = strtoul(optarg, &endptr, 0);
9759 if (*endptr != '\0') {
9760 warnx("Invalid service action \"%s\", must "
9761 "be a number", optarg);
9765 if (service_action > 0xffff) {
9766 warnx("Invalid service action 0x%#x, must "
9767 "be between 0 and 0xffff inclusive",
9782 && (opcode_set == 0)) {
9783 warnx("You must specify an opcode with -o if a service "
9788 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9789 sa_set, service_action, td_set, task_attr,
9790 retry_count, timeout, verbosemode, &valid_len,
9795 if ((opcode_set != 0)
9797 retval = scsiprintoneopcode(device, opcode, sa_set,
9798 service_action, buf, valid_len);
9800 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9811 reprobe(struct cam_device *device)
9816 ccb = cam_getccb(device);
9819 warnx("%s: error allocating ccb", __func__);
9823 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
9825 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9827 if (cam_send_ccb(device, ccb) < 0) {
9828 warn("error sending XPT_REPROBE_LUN CCB");
9833 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9834 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9846 usage(int printlong)
9849 fprintf(printlong ? stdout : stderr,
9850 "usage: camcontrol <command> [device id][generic args][command args]\n"
9851 " camcontrol devlist [-b] [-v]\n"
9852 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9853 " camcontrol tur [dev_id][generic args]\n"
9854 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9855 " camcontrol identify [dev_id][generic args] [-v]\n"
9856 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9857 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9859 " camcontrol start [dev_id][generic args]\n"
9860 " camcontrol stop [dev_id][generic args]\n"
9861 " camcontrol load [dev_id][generic args]\n"
9862 " camcontrol eject [dev_id][generic args]\n"
9863 " camcontrol reprobe [dev_id][generic args]\n"
9864 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9865 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9866 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9867 " [-q][-s][-S offset][-X]\n"
9868 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9869 " [-P pagectl][-e | -b][-d]\n"
9870 " camcontrol cmd [dev_id][generic args]\n"
9871 " <-a cmd [args] | -c cmd [args]>\n"
9872 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9873 " camcontrol smpcmd [dev_id][generic args]\n"
9874 " <-r len fmt [args]> <-R len fmt [args]>\n"
9875 " camcontrol smprg [dev_id][generic args][-l]\n"
9876 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9877 " [-o operation][-d name][-m rate][-M rate]\n"
9878 " [-T pp_timeout][-a enable|disable]\n"
9879 " [-A enable|disable][-s enable|disable]\n"
9880 " [-S enable|disable]\n"
9881 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9882 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9883 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9884 " <all|dev_id|bus[:target[:lun]]|off>\n"
9885 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9886 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9887 " [-D <enable|disable>][-M mode][-O offset]\n"
9888 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9889 " [-U][-W bus_width]\n"
9890 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9891 " camcontrol sanitize [dev_id][generic args]\n"
9892 " [-a overwrite|block|crypto|exitfailure]\n"
9893 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9895 " camcontrol idle [dev_id][generic args][-t time]\n"
9896 " camcontrol standby [dev_id][generic args][-t time]\n"
9897 " camcontrol sleep [dev_id][generic args]\n"
9898 " camcontrol powermode [dev_id][generic args]\n"
9899 " camcontrol apm [dev_id][generic args][-l level]\n"
9900 " camcontrol aam [dev_id][generic args][-l level]\n"
9901 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9903 " camcontrol security [dev_id][generic args]\n"
9904 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9905 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9906 " [-U <user|master>] [-y]\n"
9907 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9908 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9909 " camcontrol ama [dev_id][generic args] [-f] [-q] [-s max_sectors]\n"
9910 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9911 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9912 " [-s scope][-S][-T type][-U]\n"
9913 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9914 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9915 " [-p part][-s start][-T type][-V vol]\n"
9916 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9918 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9919 " [-o rep_opts] [-P print_opts]\n"
9920 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9921 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9922 " [-S power_src] [-T timer]\n"
9923 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9924 " <-s <-f format -T time | -U >>\n"
9925 " camcontrol devtype [dev_id]\n"
9927 " camcontrol help\n");
9931 "Specify one of the following options:\n"
9932 "devlist list all CAM devices\n"
9933 "periphlist list all CAM peripheral drivers attached to a device\n"
9934 "tur send a test unit ready to the named device\n"
9935 "inquiry send a SCSI inquiry command to the named device\n"
9936 "identify send a ATA identify command to the named device\n"
9937 "reportluns send a SCSI report luns command to the device\n"
9938 "readcap send a SCSI read capacity command to the device\n"
9939 "start send a Start Unit command to the device\n"
9940 "stop send a Stop Unit command to the device\n"
9941 "load send a Start Unit command to the device with the load bit set\n"
9942 "eject send a Stop Unit command to the device with the eject bit set\n"
9943 "reprobe update capacity information of the given device\n"
9944 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9945 "reset reset all buses, the given bus, bus:target:lun or device\n"
9946 "defects read the defect list of the specified device\n"
9947 "modepage display or edit (-e) the given mode page\n"
9948 "cmd send the given SCSI command, may need -i or -o as well\n"
9949 "smpcmd send the given SMP command, requires -o and -i\n"
9950 "smprg send the SMP Report General command\n"
9951 "smppc send the SMP PHY Control command, requires -p\n"
9952 "smpphylist display phys attached to a SAS expander\n"
9953 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9954 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9955 "tags report or set the number of transaction slots for a device\n"
9956 "negotiate report or set device negotiation parameters\n"
9957 "format send the SCSI FORMAT UNIT command to the named device\n"
9958 "sanitize send the SCSI SANITIZE command to the named device\n"
9959 "idle send the ATA IDLE command to the named device\n"
9960 "standby send the ATA STANDBY command to the named device\n"
9961 "sleep send the ATA SLEEP command to the named device\n"
9962 "powermode send the ATA CHECK POWER MODE command to the named device\n"
9963 "fwdownload program firmware of the named device with the given image\n"
9964 "security report or send ATA security commands to the named device\n"
9965 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9966 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9967 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9968 "zone manage Zoned Block (Shingled) devices\n"
9969 "epc send ATA Extended Power Conditions commands\n"
9970 "timestamp report or set the device's timestamp\n"
9971 "devtype report the type of device\n"
9972 "help this message\n"
9973 "Device Identifiers:\n"
9974 "bus:target specify the bus and target, lun defaults to 0\n"
9975 "bus:target:lun specify the bus, target and lun\n"
9976 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
9977 "Generic arguments:\n"
9978 "-v be verbose, print out sense information\n"
9979 "-t timeout command timeout in seconds, overrides default timeout\n"
9980 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
9981 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
9982 "-E have the kernel attempt to perform SCSI error recovery\n"
9983 "-C count specify the SCSI command retry count (needs -E to work)\n"
9984 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
9985 "modepage arguments:\n"
9986 "-l list all available mode pages\n"
9987 "-m page specify the mode page to view or edit\n"
9988 "-e edit the specified mode page\n"
9989 "-b force view to binary mode\n"
9990 "-d disable block descriptors for mode sense\n"
9991 "-P pgctl page control field 0-3\n"
9992 "defects arguments:\n"
9993 "-f format specify defect list format (block, bfi or phys)\n"
9994 "-G get the grown defect list\n"
9995 "-P get the permanent defect list\n"
9996 "inquiry arguments:\n"
9997 "-D get the standard inquiry data\n"
9998 "-S get the serial number\n"
9999 "-R get the transfer rate, etc.\n"
10000 "reportluns arguments:\n"
10001 "-c only report a count of available LUNs\n"
10002 "-l only print out luns, and not a count\n"
10003 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
10004 "readcap arguments\n"
10005 "-b only report the blocksize\n"
10006 "-h human readable device size, base 2\n"
10007 "-H human readable device size, base 10\n"
10008 "-N print the number of blocks instead of last block\n"
10009 "-q quiet, print numbers only\n"
10010 "-s only report the last block/device size\n"
10012 "-c cdb [args] specify the SCSI CDB\n"
10013 "-i len fmt specify input data and input data format\n"
10014 "-o len fmt [args] specify output data and output data fmt\n"
10015 "smpcmd arguments:\n"
10016 "-r len fmt [args] specify the SMP command to be sent\n"
10017 "-R len fmt [args] specify SMP response format\n"
10018 "smprg arguments:\n"
10019 "-l specify the long response format\n"
10020 "smppc arguments:\n"
10021 "-p phy specify the PHY to operate on\n"
10022 "-l specify the long request/response format\n"
10023 "-o operation specify the phy control operation\n"
10024 "-d name set the attached device name\n"
10025 "-m rate set the minimum physical link rate\n"
10026 "-M rate set the maximum physical link rate\n"
10027 "-T pp_timeout set the partial pathway timeout value\n"
10028 "-a enable|disable enable or disable SATA slumber\n"
10029 "-A enable|disable enable or disable SATA partial phy power\n"
10030 "-s enable|disable enable or disable SAS slumber\n"
10031 "-S enable|disable enable or disable SAS partial phy power\n"
10032 "smpphylist arguments:\n"
10033 "-l specify the long response format\n"
10034 "-q only print phys with attached devices\n"
10035 "smpmaninfo arguments:\n"
10036 "-l specify the long response format\n"
10037 "debug arguments:\n"
10038 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
10039 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
10040 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
10041 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
10042 "tags arguments:\n"
10043 "-N tags specify the number of tags to use for this device\n"
10044 "-q be quiet, don't report the number of tags\n"
10045 "-v report a number of tag-related parameters\n"
10046 "negotiate arguments:\n"
10047 "-a send a test unit ready after negotiation\n"
10048 "-c report/set current negotiation settings\n"
10049 "-D <arg> \"enable\" or \"disable\" disconnection\n"
10050 "-M mode set ATA mode\n"
10051 "-O offset set command delay offset\n"
10052 "-q be quiet, don't report anything\n"
10053 "-R syncrate synchronization rate in MHz\n"
10054 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
10055 "-U report/set user negotiation settings\n"
10056 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
10057 "-v also print a Path Inquiry CCB for the controller\n"
10058 "format arguments:\n"
10059 "-q be quiet, don't print status messages\n"
10060 "-r run in report only mode\n"
10061 "-w don't send immediate format command\n"
10062 "-y don't ask any questions\n"
10063 "sanitize arguments:\n"
10064 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
10065 "-c passes overwrite passes to perform (1 to 31)\n"
10066 "-I invert overwrite pattern after each pass\n"
10067 "-P pattern path to overwrite pattern file\n"
10068 "-q be quiet, don't print status messages\n"
10069 "-r run in report only mode\n"
10070 "-U run operation in unrestricted completion exit mode\n"
10071 "-w don't send immediate sanitize command\n"
10072 "-y don't ask any questions\n"
10073 "idle/standby arguments:\n"
10074 "-t <arg> number of seconds before respective state.\n"
10075 "fwdownload arguments:\n"
10076 "-f fw_image path to firmware image file\n"
10077 "-q don't print informational messages, only errors\n"
10078 "-s run in simulation mode\n"
10079 "-v print info for every firmware segment sent to device\n"
10080 "-y don't ask any questions\n"
10081 "security arguments:\n"
10082 "-d pwd disable security using the given password for the selected\n"
10084 "-e pwd erase the device using the given pwd for the selected user\n"
10085 "-f freeze the security configuration of the specified device\n"
10086 "-h pwd enhanced erase the device using the given pwd for the\n"
10088 "-k pwd unlock the device using the given pwd for the selected\n"
10090 "-l <high|maximum> specifies which security level to set: high or maximum\n"
10091 "-q be quiet, do not print any status messages\n"
10092 "-s pwd password the device (enable security) using the given\n"
10093 " pwd for the selected user\n"
10094 "-T timeout overrides the timeout (seconds) used for erase operation\n"
10095 "-U <user|master> specifies which user to set: user or master\n"
10096 "-y don't ask any questions\n"
10098 "-f freeze the HPA configuration of the device\n"
10099 "-l lock the HPA configuration of the device\n"
10100 "-P make the HPA max sectors persist\n"
10101 "-p pwd Set the HPA configuration password required for unlock\n"
10103 "-q be quiet, do not print any status messages\n"
10104 "-s sectors configures the maximum user accessible sectors of the\n"
10106 "-U pwd unlock the HPA configuration of the device\n"
10107 "-y don't ask any questions\n"
10109 "-f freeze the AMA configuration of the device\n"
10110 "-q be quiet, do not print any status messages\n"
10111 "-s sectors configures the maximum user accessible sectors of the\n"
10113 "persist arguments:\n"
10114 "-i action specify read_keys, read_reservation, report_cap, or\n"
10115 " read_full_status\n"
10116 "-o action specify register, register_ignore, reserve, release,\n"
10117 " clear, preempt, preempt_abort, register_move, replace_lost\n"
10118 "-a set the All Target Ports (ALL_TG_PT) bit\n"
10119 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
10120 "-k key specify the Reservation Key\n"
10121 "-K sa_key specify the Service Action Reservation Key\n"
10122 "-p set the Activate Persist Through Power Loss bit\n"
10123 "-R rtp specify the Relative Target Port\n"
10124 "-s scope specify the scope: lun, extent, element or a number\n"
10125 "-S specify Transport ID for register, requires -I\n"
10126 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
10127 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
10128 "-U unregister the current initiator for register_move\n"
10129 "attrib arguments:\n"
10130 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
10132 "-w attr specify an attribute to write, one -w argument per attr\n"
10133 "-a attr_num only display this attribute number\n"
10134 "-c get cached attributes\n"
10135 "-e elem_addr request attributes for the given element in a changer\n"
10136 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
10137 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
10138 " field_none, field_desc, field_num, field_size, field_rw\n"
10139 "-p partition request attributes for the given partition\n"
10140 "-s start_attr request attributes starting at the given number\n"
10141 "-T elem_type specify the element type (used with -e)\n"
10142 "-V logical_vol specify the logical volume ID\n"
10143 "opcodes arguments:\n"
10144 "-o opcode specify the individual opcode to list\n"
10145 "-s service_action specify the service action for the opcode\n"
10146 "-N do not return SCSI error for unsupported SA\n"
10147 "-T request nominal and recommended timeout values\n"
10148 "zone arguments:\n"
10149 "-c cmd required: rz, open, close, finish, or rwp\n"
10150 "-a apply the action to all zones\n"
10151 "-l LBA specify the zone starting LBA\n"
10152 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
10153 " closed, full, ro, offline, reset, nonseq, nonwp\n"
10154 "-P print_opt report zones printing: normal, summary, script\n"
10156 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
10157 " source, status, list\n"
10158 "-d disable power mode (timer, state)\n"
10159 "-D delayed entry (goto)\n"
10160 "-e enable power mode (timer, state)\n"
10161 "-H hold power mode (goto)\n"
10162 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
10164 "-P only display power mode (status)\n"
10165 "-r rst_src restore settings from: default, saved (restore)\n"
10166 "-s save mode (timer, state, restore)\n"
10167 "-S power_src set power source: battery, nonbattery (source)\n"
10168 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
10169 "timestamp arguments:\n"
10170 "-r report the timestamp of the device\n"
10171 "-f format report the timestamp of the device with the given\n"
10172 " strftime(3) format string\n"
10173 "-m report the timestamp of the device as milliseconds since\n"
10174 " January 1st, 1970\n"
10175 "-U report the time with UTC instead of the local time zone\n"
10176 "-s set the timestamp of the device\n"
10177 "-f format the format of the time string passed into strptime(3)\n"
10178 "-T time the time value passed into strptime(3)\n"
10179 "-U set the timestamp of the device to UTC time\n"
10184 main(int argc, char **argv)
10187 char *device = NULL;
10189 struct cam_device *cam_dev = NULL;
10190 int timeout = 0, retry_count = 1;
10191 camcontrol_optret optreturn;
10193 const char *mainopt = "C:En:Q:t:u:v";
10194 const char *subopt = NULL;
10195 char combinedopt[256];
10196 int error = 0, optstart = 2;
10197 int task_attr = MSG_SIMPLE_Q_TAG;
10200 target_id_t target;
10203 cmdlist = CAM_CMD_NONE;
10204 arglist = CAM_ARG_NONE;
10212 * Get the base option.
10214 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
10216 if (optreturn == CC_OR_AMBIGUOUS) {
10217 warnx("ambiguous option %s", argv[1]);
10220 } else if (optreturn == CC_OR_NOT_FOUND) {
10221 warnx("option %s not found", argv[1]);
10227 * Ahh, getopt(3) is a pain.
10229 * This is a gross hack. There really aren't many other good
10230 * options (excuse the pun) for parsing options in a situation like
10231 * this. getopt is kinda braindead, so you end up having to run
10232 * through the options twice, and give each invocation of getopt
10233 * the option string for the other invocation.
10235 * You would think that you could just have two groups of options.
10236 * The first group would get parsed by the first invocation of
10237 * getopt, and the second group would get parsed by the second
10238 * invocation of getopt. It doesn't quite work out that way. When
10239 * the first invocation of getopt finishes, it leaves optind pointing
10240 * to the argument _after_ the first argument in the second group.
10241 * So when the second invocation of getopt comes around, it doesn't
10242 * recognize the first argument it gets and then bails out.
10244 * A nice alternative would be to have a flag for getopt that says
10245 * "just keep parsing arguments even when you encounter an unknown
10246 * argument", but there isn't one. So there's no real clean way to
10247 * easily parse two sets of arguments without having one invocation
10248 * of getopt know about the other.
10250 * Without this hack, the first invocation of getopt would work as
10251 * long as the generic arguments are first, but the second invocation
10252 * (in the subfunction) would fail in one of two ways. In the case
10253 * where you don't set optreset, it would fail because optind may be
10254 * pointing to the argument after the one it should be pointing at.
10255 * In the case where you do set optreset, and reset optind, it would
10256 * fail because getopt would run into the first set of options, which
10257 * it doesn't understand.
10259 * All of this would "sort of" work if you could somehow figure out
10260 * whether optind had been incremented one option too far. The
10261 * mechanics of that, however, are more daunting than just giving
10262 * both invocations all of the expect options for either invocation.
10264 * Needless to say, I wouldn't mind if someone invented a better
10265 * (non-GPL!) command line parsing interface than getopt. I
10266 * wouldn't mind if someone added more knobs to getopt to make it
10267 * work better. Who knows, I may talk myself into doing it someday,
10268 * if the standards weenies let me. As it is, it just leads to
10269 * hackery like this and causes people to avoid it in some cases.
10271 * KDM, September 8th, 1998
10273 if (subopt != NULL)
10274 sprintf(combinedopt, "%s%s", mainopt, subopt);
10276 sprintf(combinedopt, "%s", mainopt);
10279 * For these options we do not parse optional device arguments and
10280 * we do not open a passthrough device.
10282 if ((cmdlist == CAM_CMD_RESCAN)
10283 || (cmdlist == CAM_CMD_RESET)
10284 || (cmdlist == CAM_CMD_DEVTREE)
10285 || (cmdlist == CAM_CMD_USAGE)
10286 || (cmdlist == CAM_CMD_DEBUG))
10290 && (argc > 2 && argv[2][0] != '-')) {
10294 if (isdigit(argv[2][0])) {
10295 /* device specified as bus:target[:lun] */
10296 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10298 errx(1, "numeric device specification must "
10299 "be either bus:target, or "
10301 /* default to 0 if lun was not specified */
10302 if ((arglist & CAM_ARG_LUN) == 0) {
10304 arglist |= CAM_ARG_LUN;
10308 if (cam_get_device(argv[2], name, sizeof name, &unit)
10310 errx(1, "%s", cam_errbuf);
10311 device = strdup(name);
10312 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10317 * Start getopt processing at argv[2/3], since we've already
10318 * accepted argv[1..2] as the command name, and as a possible
10324 * Now we run through the argument list looking for generic
10325 * options, and ignoring options that possibly belong to
10328 while ((c = getopt(argc, argv, combinedopt))!= -1){
10331 retry_count = strtol(optarg, NULL, 0);
10332 if (retry_count < 0)
10333 errx(1, "retry count %d is < 0",
10335 arglist |= CAM_ARG_RETRIES;
10338 arglist |= CAM_ARG_ERR_RECOVER;
10341 arglist |= CAM_ARG_DEVICE;
10343 while (isspace(*tstr) && (*tstr != '\0'))
10345 device = (char *)strdup(tstr);
10349 int table_entry = 0;
10352 while (isspace(*tstr) && (*tstr != '\0'))
10354 if (isdigit(*tstr)) {
10355 task_attr = strtol(tstr, &endptr, 0);
10356 if (*endptr != '\0') {
10357 errx(1, "Invalid queue option "
10362 scsi_nv_status status;
10364 table_size = sizeof(task_attrs) /
10365 sizeof(task_attrs[0]);
10366 status = scsi_get_nv(task_attrs,
10367 table_size, tstr, &table_entry,
10368 SCSI_NV_FLAG_IG_CASE);
10369 if (status == SCSI_NV_FOUND)
10370 task_attr = task_attrs[
10371 table_entry].value;
10373 errx(1, "%s option %s",
10374 (status == SCSI_NV_AMBIGUOUS)?
10375 "ambiguous" : "invalid",
10382 timeout = strtol(optarg, NULL, 0);
10384 errx(1, "invalid timeout %d", timeout);
10385 /* Convert the timeout from seconds to ms */
10387 arglist |= CAM_ARG_TIMEOUT;
10390 arglist |= CAM_ARG_UNIT;
10391 unit = strtol(optarg, NULL, 0);
10394 arglist |= CAM_ARG_VERBOSE;
10402 * For most commands we'll want to open the passthrough device
10403 * associated with the specified device. In the case of the rescan
10404 * commands, we don't use a passthrough device at all, just the
10405 * transport layer device.
10407 if (devopen == 1) {
10408 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10409 && (((arglist & CAM_ARG_DEVICE) == 0)
10410 || ((arglist & CAM_ARG_UNIT) == 0))) {
10411 errx(1, "subcommand \"%s\" requires a valid device "
10412 "identifier", argv[1]);
10415 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10416 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10417 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10419 errx(1,"%s", cam_errbuf);
10423 * Reset optind to 2, and reset getopt, so these routines can parse
10424 * the arguments again.
10430 case CAM_CMD_DEVLIST:
10431 error = getdevlist(cam_dev);
10434 error = atahpa(cam_dev, retry_count, timeout,
10435 argc, argv, combinedopt);
10438 error = ataama(cam_dev, retry_count, timeout,
10439 argc, argv, combinedopt);
10441 case CAM_CMD_DEVTREE:
10442 error = getdevtree(argc, argv, combinedopt);
10444 case CAM_CMD_DEVTYPE:
10445 error = getdevtype(cam_dev);
10448 error = testunitready(cam_dev, task_attr, retry_count,
10451 case CAM_CMD_INQUIRY:
10452 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10453 task_attr, retry_count, timeout);
10455 case CAM_CMD_IDENTIFY:
10456 error = identify(cam_dev, retry_count, timeout);
10458 case CAM_CMD_STARTSTOP:
10459 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10460 arglist & CAM_ARG_EJECT, task_attr,
10461 retry_count, timeout);
10463 case CAM_CMD_RESCAN:
10464 error = dorescan_or_reset(argc, argv, 1);
10466 case CAM_CMD_RESET:
10467 error = dorescan_or_reset(argc, argv, 0);
10469 case CAM_CMD_READ_DEFECTS:
10470 error = readdefects(cam_dev, argc, argv, combinedopt,
10471 task_attr, retry_count, timeout);
10473 case CAM_CMD_MODE_PAGE:
10474 modepage(cam_dev, argc, argv, combinedopt,
10475 task_attr, retry_count, timeout);
10477 case CAM_CMD_SCSI_CMD:
10478 error = scsicmd(cam_dev, argc, argv, combinedopt,
10479 task_attr, retry_count, timeout);
10481 case CAM_CMD_MMCSD_CMD:
10482 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10483 retry_count, timeout);
10485 case CAM_CMD_SMP_CMD:
10486 error = smpcmd(cam_dev, argc, argv, combinedopt,
10487 retry_count, timeout);
10489 case CAM_CMD_SMP_RG:
10490 error = smpreportgeneral(cam_dev, argc, argv,
10491 combinedopt, retry_count,
10494 case CAM_CMD_SMP_PC:
10495 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10496 retry_count, timeout);
10498 case CAM_CMD_SMP_PHYLIST:
10499 error = smpphylist(cam_dev, argc, argv, combinedopt,
10500 retry_count, timeout);
10502 case CAM_CMD_SMP_MANINFO:
10503 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10504 retry_count, timeout);
10506 case CAM_CMD_DEBUG:
10507 error = camdebug(argc, argv, combinedopt);
10510 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10513 error = ratecontrol(cam_dev, task_attr, retry_count,
10514 timeout, argc, argv, combinedopt);
10516 case CAM_CMD_FORMAT:
10517 error = scsiformat(cam_dev, argc, argv,
10518 combinedopt, task_attr, retry_count,
10521 case CAM_CMD_REPORTLUNS:
10522 error = scsireportluns(cam_dev, argc, argv,
10523 combinedopt, task_attr,
10524 retry_count, timeout);
10526 case CAM_CMD_READCAP:
10527 error = scsireadcapacity(cam_dev, argc, argv,
10528 combinedopt, task_attr,
10529 retry_count, timeout);
10532 case CAM_CMD_STANDBY:
10533 case CAM_CMD_SLEEP:
10534 case CAM_CMD_POWER_MODE:
10535 error = atapm(cam_dev, argc, argv,
10536 combinedopt, retry_count, timeout);
10540 error = ataaxm(cam_dev, argc, argv,
10541 combinedopt, retry_count, timeout);
10543 case CAM_CMD_SECURITY:
10544 error = atasecurity(cam_dev, retry_count, timeout,
10545 argc, argv, combinedopt);
10547 case CAM_CMD_DOWNLOAD_FW:
10548 error = fwdownload(cam_dev, argc, argv, combinedopt,
10549 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10552 case CAM_CMD_SANITIZE:
10553 error = sanitize(cam_dev, argc, argv, combinedopt, task_attr,
10554 retry_count, timeout);
10556 case CAM_CMD_PERSIST:
10557 error = scsipersist(cam_dev, argc, argv, combinedopt,
10558 task_attr, retry_count, timeout,
10559 arglist & CAM_ARG_VERBOSE,
10560 arglist & CAM_ARG_ERR_RECOVER);
10562 case CAM_CMD_ATTRIB:
10563 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10564 task_attr, retry_count, timeout,
10565 arglist & CAM_ARG_VERBOSE,
10566 arglist & CAM_ARG_ERR_RECOVER);
10568 case CAM_CMD_OPCODES:
10569 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10570 task_attr, retry_count, timeout,
10571 arglist & CAM_ARG_VERBOSE);
10573 case CAM_CMD_REPROBE:
10574 error = reprobe(cam_dev);
10577 error = zone(cam_dev, argc, argv, combinedopt,
10578 task_attr, retry_count, timeout,
10579 arglist & CAM_ARG_VERBOSE);
10582 error = epc(cam_dev, argc, argv, combinedopt,
10583 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10585 case CAM_CMD_TIMESTAMP:
10586 error = timestamp(cam_dev, argc, argv, combinedopt,
10587 task_attr, retry_count, timeout,
10588 arglist & CAM_ARG_VERBOSE);
10590 case CAM_CMD_USAGE:
10599 if (cam_dev != NULL)
10600 cam_close_device(cam_dev);