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 = 0, 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);
4578 if (page < 0 || page > 0x3f)
4579 errx(1, "invalid mode page %d", page);
4580 if (subpage < 0 || subpage > 0xff)
4581 errx(1, "invalid mode subpage %d", subpage);
4590 pc = strtol(optarg, NULL, 0);
4591 if ((pc < 0) || (pc > 3))
4592 errx(1, "invalid page control field %d", pc);
4599 if (desc && page == -1)
4600 page = SMS_ALL_PAGES_PAGE;
4602 if (page == -1 && list == 0)
4603 errx(1, "you must specify a mode page!");
4606 errx(1, "-d and -D are incompatible!");
4608 if (llbaa && cdb_len != 10)
4609 errx(1, "LLBAA bit is not present in MODE SENSE(6)!");
4612 mode_list(device, cdb_len, dbd, pc, list > 1, task_attr,
4613 retry_count, timeout);
4615 mode_edit(device, cdb_len, desc, dbd, llbaa, pc, page, subpage,
4616 edit, binary, task_attr, retry_count, timeout);
4621 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4622 int task_attr, int retry_count, int timeout)
4625 u_int32_t flags = CAM_DIR_NONE;
4626 u_int8_t *data_ptr = NULL;
4628 u_int8_t atacmd[12];
4629 struct get_hook hook;
4630 int c, data_bytes = 0, valid_bytes;
4636 char *datastr = NULL, *tstr, *resstr = NULL;
4638 int fd_data = 0, fd_res = 0;
4641 ccb = cam_getccb(device);
4644 warnx("scsicmd: error allocating ccb");
4648 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4650 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4654 while (isspace(*tstr) && (*tstr != '\0'))
4656 hook.argc = argc - optind;
4657 hook.argv = argv + optind;
4659 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4662 * Increment optind by the number of arguments the
4663 * encoding routine processed. After each call to
4664 * getopt(3), optind points to the argument that
4665 * getopt should process _next_. In this case,
4666 * that means it points to the first command string
4667 * argument, if there is one. Once we increment
4668 * this, it should point to either the next command
4669 * line argument, or it should be past the end of
4676 while (isspace(*tstr) && (*tstr != '\0'))
4678 hook.argc = argc - optind;
4679 hook.argv = argv + optind;
4681 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4684 * Increment optind by the number of arguments the
4685 * encoding routine processed. After each call to
4686 * getopt(3), optind points to the argument that
4687 * getopt should process _next_. In this case,
4688 * that means it points to the first command string
4689 * argument, if there is one. Once we increment
4690 * this, it should point to either the next command
4691 * line argument, or it should be past the end of
4703 if (arglist & CAM_ARG_CMD_OUT) {
4704 warnx("command must either be "
4705 "read or write, not both");
4707 goto scsicmd_bailout;
4709 arglist |= CAM_ARG_CMD_IN;
4711 data_bytes = strtol(optarg, NULL, 0);
4712 if (data_bytes <= 0) {
4713 warnx("invalid number of input bytes %d",
4716 goto scsicmd_bailout;
4718 hook.argc = argc - optind;
4719 hook.argv = argv + optind;
4722 datastr = cget(&hook, NULL);
4724 * If the user supplied "-" instead of a format, he
4725 * wants the data to be written to stdout.
4727 if ((datastr != NULL)
4728 && (datastr[0] == '-'))
4731 data_ptr = (u_int8_t *)malloc(data_bytes);
4732 if (data_ptr == NULL) {
4733 warnx("can't malloc memory for data_ptr");
4735 goto scsicmd_bailout;
4739 if (arglist & CAM_ARG_CMD_IN) {
4740 warnx("command must either be "
4741 "read or write, not both");
4743 goto scsicmd_bailout;
4745 arglist |= CAM_ARG_CMD_OUT;
4746 flags = CAM_DIR_OUT;
4747 data_bytes = strtol(optarg, NULL, 0);
4748 if (data_bytes <= 0) {
4749 warnx("invalid number of output bytes %d",
4752 goto scsicmd_bailout;
4754 hook.argc = argc - optind;
4755 hook.argv = argv + optind;
4757 datastr = cget(&hook, NULL);
4758 data_ptr = (u_int8_t *)malloc(data_bytes);
4759 if (data_ptr == NULL) {
4760 warnx("can't malloc memory for data_ptr");
4762 goto scsicmd_bailout;
4764 bzero(data_ptr, data_bytes);
4766 * If the user supplied "-" instead of a format, he
4767 * wants the data to be read from stdin.
4769 if ((datastr != NULL)
4770 && (datastr[0] == '-'))
4773 buff_encode_visit(data_ptr, data_bytes, datastr,
4779 hook.argc = argc - optind;
4780 hook.argv = argv + optind;
4782 resstr = cget(&hook, NULL);
4783 if ((resstr != NULL) && (resstr[0] == '-'))
4793 * If fd_data is set, and we're writing to the device, we need to
4794 * read the data the user wants written from stdin.
4796 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4798 int amt_to_read = data_bytes;
4799 u_int8_t *buf_ptr = data_ptr;
4801 for (amt_read = 0; amt_to_read > 0;
4802 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4803 if (amt_read == -1) {
4804 warn("error reading data from stdin");
4806 goto scsicmd_bailout;
4808 amt_to_read -= amt_read;
4809 buf_ptr += amt_read;
4813 if (arglist & CAM_ARG_ERR_RECOVER)
4814 flags |= CAM_PASS_ERR_RECOVER;
4816 /* Disable freezing the device queue */
4817 flags |= CAM_DEV_QFRZDIS;
4821 * This is taken from the SCSI-3 draft spec.
4822 * (T10/1157D revision 0.3)
4823 * The top 3 bits of an opcode are the group code.
4824 * The next 5 bits are the command code.
4825 * Group 0: six byte commands
4826 * Group 1: ten byte commands
4827 * Group 2: ten byte commands
4829 * Group 4: sixteen byte commands
4830 * Group 5: twelve byte commands
4831 * Group 6: vendor specific
4832 * Group 7: vendor specific
4834 switch((cdb[0] >> 5) & 0x7) {
4845 /* computed by buff_encode_visit */
4856 * We should probably use csio_build_visit or something like that
4857 * here, but it's easier to encode arguments as you go. The
4858 * alternative would be skipping the CDB argument and then encoding
4859 * it here, since we've got the data buffer argument by now.
4861 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4863 cam_fill_csio(&ccb->csio,
4864 /*retries*/ retry_count,
4867 /*tag_action*/ task_attr,
4868 /*data_ptr*/ data_ptr,
4869 /*dxfer_len*/ data_bytes,
4870 /*sense_len*/ SSD_FULL_SIZE,
4871 /*cdb_len*/ cdb_len,
4872 /*timeout*/ timeout ? timeout : 5000);
4875 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4877 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4879 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4881 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4883 cam_fill_ataio(&ccb->ataio,
4884 /*retries*/ retry_count,
4888 /*data_ptr*/ data_ptr,
4889 /*dxfer_len*/ data_bytes,
4890 /*timeout*/ timeout ? timeout : 5000);
4893 if (((retval = cam_send_ccb(device, ccb)) < 0)
4894 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4895 const char warnstr[] = "error sending command";
4902 if (arglist & CAM_ARG_VERBOSE) {
4903 cam_error_print(device, ccb, CAM_ESF_ALL,
4904 CAM_EPF_ALL, stderr);
4908 goto scsicmd_bailout;
4911 if (atacmd_len && need_res) {
4913 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4915 fprintf(stdout, "\n");
4918 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4919 ccb->ataio.res.status,
4920 ccb->ataio.res.error,
4921 ccb->ataio.res.lba_low,
4922 ccb->ataio.res.lba_mid,
4923 ccb->ataio.res.lba_high,
4924 ccb->ataio.res.device,
4925 ccb->ataio.res.lba_low_exp,
4926 ccb->ataio.res.lba_mid_exp,
4927 ccb->ataio.res.lba_high_exp,
4928 ccb->ataio.res.sector_count,
4929 ccb->ataio.res.sector_count_exp);
4935 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4937 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4938 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4939 && (arglist & CAM_ARG_CMD_IN)
4940 && (valid_bytes > 0)) {
4942 buff_decode_visit(data_ptr, valid_bytes, datastr,
4944 fprintf(stdout, "\n");
4946 ssize_t amt_written;
4947 int amt_to_write = valid_bytes;
4948 u_int8_t *buf_ptr = data_ptr;
4950 for (amt_written = 0; (amt_to_write > 0) &&
4951 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4952 amt_to_write -= amt_written;
4953 buf_ptr += amt_written;
4955 if (amt_written == -1) {
4956 warn("error writing data to stdout");
4958 goto scsicmd_bailout;
4959 } else if ((amt_written == 0)
4960 && (amt_to_write > 0)) {
4961 warnx("only wrote %u bytes out of %u",
4962 valid_bytes - amt_to_write, valid_bytes);
4969 if ((data_bytes > 0) && (data_ptr != NULL))
4978 camdebug(int argc, char **argv, char *combinedopt)
4981 path_id_t bus = CAM_BUS_WILDCARD;
4982 target_id_t target = CAM_TARGET_WILDCARD;
4983 lun_id_t lun = CAM_LUN_WILDCARD;
4988 bzero(&ccb, sizeof(union ccb));
4990 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4993 arglist |= CAM_ARG_DEBUG_INFO;
4994 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4997 arglist |= CAM_ARG_DEBUG_PERIPH;
4998 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
5001 arglist |= CAM_ARG_DEBUG_SUBTRACE;
5002 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
5005 arglist |= CAM_ARG_DEBUG_TRACE;
5006 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
5009 arglist |= CAM_ARG_DEBUG_XPT;
5010 ccb.cdbg.flags |= CAM_DEBUG_XPT;
5013 arglist |= CAM_ARG_DEBUG_CDB;
5014 ccb.cdbg.flags |= CAM_DEBUG_CDB;
5017 arglist |= CAM_ARG_DEBUG_PROBE;
5018 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
5029 warnx("you must specify \"off\", \"all\" or a bus,");
5030 warnx("bus:target, bus:target:lun or periph");
5035 while (isspace(*tstr) && (*tstr != '\0'))
5038 if (strncmp(tstr, "off", 3) == 0) {
5039 ccb.cdbg.flags = CAM_DEBUG_NONE;
5040 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
5041 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
5042 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
5044 rv = parse_btl(tstr, &bus, &target, &lun, &arglist);
5046 warnx("you must specify \"all\", \"off\", or a bus,");
5047 warnx("bus:target, bus:target:lun or periph to debug");
5052 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
5053 warnx("error opening transport layer device %s", XPT_DEVICE);
5054 warn("%s", XPT_DEVICE);
5058 ccb.ccb_h.func_code = XPT_DEBUG;
5059 ccb.ccb_h.path_id = bus;
5060 ccb.ccb_h.target_id = target;
5061 ccb.ccb_h.target_lun = lun;
5063 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
5064 warn("CAMIOCOMMAND ioctl failed");
5067 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
5068 CAM_FUNC_NOTAVAIL) {
5069 warnx("CAM debugging not available");
5070 warnx("you need to put options CAMDEBUG in"
5071 " your kernel config file!");
5073 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
5075 warnx("XPT_DEBUG CCB failed with status %#x",
5079 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
5081 "Debugging turned off\n");
5084 "Debugging enabled for "
5086 bus, target, (uintmax_t)lun);
5096 tagcontrol(struct cam_device *device, int argc, char **argv,
5106 ccb = cam_getccb(device);
5109 warnx("tagcontrol: error allocating ccb");
5113 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5116 numtags = strtol(optarg, NULL, 0);
5118 warnx("tag count %d is < 0", numtags);
5120 goto tagcontrol_bailout;
5131 cam_path_string(device, pathstr, sizeof(pathstr));
5134 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
5135 ccb->ccb_h.func_code = XPT_REL_SIMQ;
5136 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5137 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5138 ccb->crs.openings = numtags;
5141 if (cam_send_ccb(device, ccb) < 0) {
5142 warn("error sending XPT_REL_SIMQ CCB");
5144 goto tagcontrol_bailout;
5147 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5148 warnx("XPT_REL_SIMQ CCB failed");
5149 cam_error_print(device, ccb, CAM_ESF_ALL,
5150 CAM_EPF_ALL, stderr);
5152 goto tagcontrol_bailout;
5157 fprintf(stdout, "%stagged openings now %d\n",
5158 pathstr, ccb->crs.openings);
5161 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5163 ccb->ccb_h.func_code = XPT_GDEV_STATS;
5165 if (cam_send_ccb(device, ccb) < 0) {
5166 warn("error sending XPT_GDEV_STATS CCB");
5168 goto tagcontrol_bailout;
5171 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5172 warnx("XPT_GDEV_STATS CCB failed");
5173 cam_error_print(device, ccb, CAM_ESF_ALL,
5174 CAM_EPF_ALL, stderr);
5176 goto tagcontrol_bailout;
5179 if (arglist & CAM_ARG_VERBOSE) {
5180 fprintf(stdout, "%s", pathstr);
5181 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5182 fprintf(stdout, "%s", pathstr);
5183 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5184 fprintf(stdout, "%s", pathstr);
5185 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5186 fprintf(stdout, "%s", pathstr);
5187 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5188 fprintf(stdout, "%s", pathstr);
5189 fprintf(stdout, "held %d\n", ccb->cgds.held);
5190 fprintf(stdout, "%s", pathstr);
5191 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5192 fprintf(stdout, "%s", pathstr);
5193 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5196 fprintf(stdout, "%s", pathstr);
5197 fprintf(stdout, "device openings: ");
5199 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5200 ccb->cgds.dev_active);
5210 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5214 cam_path_string(device, pathstr, sizeof(pathstr));
5216 if (cts->transport == XPORT_SPI) {
5217 struct ccb_trans_settings_spi *spi =
5218 &cts->xport_specific.spi;
5220 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5222 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5225 if (spi->sync_offset != 0) {
5228 freq = scsi_calc_syncsrate(spi->sync_period);
5229 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5230 pathstr, freq / 1000, freq % 1000);
5234 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5235 fprintf(stdout, "%soffset: %d\n", pathstr,
5239 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5240 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5241 (0x01 << spi->bus_width) * 8);
5244 if (spi->valid & CTS_SPI_VALID_DISC) {
5245 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5246 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5247 "enabled" : "disabled");
5250 if (cts->transport == XPORT_FC) {
5251 struct ccb_trans_settings_fc *fc =
5252 &cts->xport_specific.fc;
5254 if (fc->valid & CTS_FC_VALID_WWNN)
5255 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5256 (long long) fc->wwnn);
5257 if (fc->valid & CTS_FC_VALID_WWPN)
5258 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5259 (long long) fc->wwpn);
5260 if (fc->valid & CTS_FC_VALID_PORT)
5261 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5262 if (fc->valid & CTS_FC_VALID_SPEED)
5263 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5264 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5266 if (cts->transport == XPORT_SAS) {
5267 struct ccb_trans_settings_sas *sas =
5268 &cts->xport_specific.sas;
5270 if (sas->valid & CTS_SAS_VALID_SPEED)
5271 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5272 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5274 if (cts->transport == XPORT_ATA) {
5275 struct ccb_trans_settings_pata *pata =
5276 &cts->xport_specific.ata;
5278 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5279 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5280 ata_mode2string(pata->mode));
5282 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5283 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5286 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5287 fprintf(stdout, "%sPIO transaction length: %d\n",
5288 pathstr, pata->bytecount);
5291 if (cts->transport == XPORT_SATA) {
5292 struct ccb_trans_settings_sata *sata =
5293 &cts->xport_specific.sata;
5295 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5296 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5299 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5300 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5301 ata_mode2string(sata->mode));
5303 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5304 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5307 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5308 fprintf(stdout, "%sPIO transaction length: %d\n",
5309 pathstr, sata->bytecount);
5311 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5312 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5315 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5316 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5319 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5320 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5324 if (cts->protocol == PROTO_ATA) {
5325 struct ccb_trans_settings_ata *ata=
5326 &cts->proto_specific.ata;
5328 if (ata->valid & CTS_ATA_VALID_TQ) {
5329 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5330 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5331 "enabled" : "disabled");
5334 if (cts->protocol == PROTO_SCSI) {
5335 struct ccb_trans_settings_scsi *scsi=
5336 &cts->proto_specific.scsi;
5338 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5339 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5340 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5341 "enabled" : "disabled");
5345 if (cts->protocol == PROTO_NVME) {
5346 struct ccb_trans_settings_nvme *nvmex =
5347 &cts->xport_specific.nvme;
5349 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5350 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5351 NVME_MAJOR(nvmex->spec),
5352 NVME_MINOR(nvmex->spec));
5354 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5355 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5356 nvmex->lanes, nvmex->max_lanes);
5357 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5358 nvmex->speed, nvmex->max_speed);
5365 * Get a path inquiry CCB for the specified device.
5368 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5373 ccb = cam_getccb(device);
5375 warnx("get_cpi: couldn't allocate CCB");
5378 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5379 ccb->ccb_h.func_code = XPT_PATH_INQ;
5380 if (cam_send_ccb(device, ccb) < 0) {
5381 warn("get_cpi: error sending Path Inquiry CCB");
5383 goto get_cpi_bailout;
5385 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5386 if (arglist & CAM_ARG_VERBOSE)
5387 cam_error_print(device, ccb, CAM_ESF_ALL,
5388 CAM_EPF_ALL, stderr);
5390 goto get_cpi_bailout;
5392 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5400 * Get a get device CCB for the specified device.
5403 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5408 ccb = cam_getccb(device);
5410 warnx("get_cgd: couldn't allocate CCB");
5413 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5414 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5415 if (cam_send_ccb(device, ccb) < 0) {
5416 warn("get_cgd: error sending Get type information CCB");
5418 goto get_cgd_bailout;
5420 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5421 if (arglist & CAM_ARG_VERBOSE)
5422 cam_error_print(device, ccb, CAM_ESF_ALL,
5423 CAM_EPF_ALL, stderr);
5425 goto get_cgd_bailout;
5427 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5435 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5439 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5440 int timeout, int verbosemode)
5442 union ccb *ccb = NULL;
5443 struct scsi_vpd_supported_page_list sup_pages;
5447 ccb = cam_getccb(dev);
5449 warn("Unable to allocate CCB");
5454 /* cam_getccb cleans up the header, caller has to zero the payload */
5455 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5457 bzero(&sup_pages, sizeof(sup_pages));
5459 scsi_inquiry(&ccb->csio,
5460 /*retries*/ retry_count,
5462 /* tag_action */ MSG_SIMPLE_Q_TAG,
5463 /* inq_buf */ (u_int8_t *)&sup_pages,
5464 /* inq_len */ sizeof(sup_pages),
5466 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5467 /* sense_len */ SSD_FULL_SIZE,
5468 /* timeout */ timeout ? timeout : 5000);
5470 /* Disable freezing the device queue */
5471 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5473 if (retry_count != 0)
5474 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5476 if (cam_send_ccb(dev, ccb) < 0) {
5483 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5484 if (verbosemode != 0)
5485 cam_error_print(dev, ccb, CAM_ESF_ALL,
5486 CAM_EPF_ALL, stderr);
5491 for (i = 0; i < sup_pages.length; i++) {
5492 if (sup_pages.list[i] == page_id) {
5505 * devtype is filled in with the type of device.
5506 * Returns 0 for success, non-zero for failure.
5509 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5510 int verbosemode, camcontrol_devtype *devtype)
5512 struct ccb_getdev cgd;
5515 retval = get_cgd(dev, &cgd);
5519 switch (cgd.protocol) {
5525 *devtype = CC_DT_ATA;
5527 break; /*NOTREACHED*/
5529 *devtype = CC_DT_NVME;
5531 break; /*NOTREACHED*/
5533 *devtype = CC_DT_MMCSD;
5535 break; /*NOTREACHED*/
5537 *devtype = CC_DT_UNKNOWN;
5539 break; /*NOTREACHED*/
5542 if (retry_count == -1) {
5544 * For a retry count of -1, used only the cached data to avoid
5545 * I/O to the drive. Sending the identify command to the drive
5546 * can cause issues for SATL attachaed drives since identify is
5547 * not an NCQ command.
5549 if (cgd.ident_data.config != 0)
5550 *devtype = CC_DT_SATL;
5552 *devtype = CC_DT_SCSI;
5555 * Check for the ATA Information VPD page (0x89). If this is an
5556 * ATA device behind a SCSI to ATA translation layer (SATL),
5557 * this VPD page should be present.
5559 * If that VPD page isn't present, or we get an error back from
5560 * the INQUIRY command, we'll just treat it as a normal SCSI
5563 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5564 timeout, verbosemode);
5566 *devtype = CC_DT_SATL;
5568 *devtype = CC_DT_SCSI;
5577 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5578 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5579 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5580 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5581 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5582 int is48bit, camcontrol_devtype devtype)
5586 if (devtype == CC_DT_ATA) {
5587 cam_fill_ataio(&ccb->ataio,
5588 /*retries*/ retry_count,
5591 /*tag_action*/ tag_action,
5592 /*data_ptr*/ data_ptr,
5593 /*dxfer_len*/ dxfer_len,
5594 /*timeout*/ timeout);
5595 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5596 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5599 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5602 if (auxiliary != 0) {
5603 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5604 ccb->ataio.aux = auxiliary;
5607 if (ata_flags & AP_FLAG_CHK_COND)
5608 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5610 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5611 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5612 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5613 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5615 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5616 protocol |= AP_EXTEND;
5618 retval = scsi_ata_pass(&ccb->csio,
5619 /*retries*/ retry_count,
5622 /*tag_action*/ tag_action,
5623 /*protocol*/ protocol,
5624 /*ata_flags*/ ata_flags,
5625 /*features*/ features,
5626 /*sector_count*/ sector_count,
5628 /*command*/ command,
5631 /*auxiliary*/ auxiliary,
5633 /*data_ptr*/ data_ptr,
5634 /*dxfer_len*/ dxfer_len,
5635 /*cdb_storage*/ cdb_storage,
5636 /*cdb_storage_len*/ cdb_storage_len,
5637 /*minimum_cmd_size*/ 0,
5638 /*sense_len*/ sense_len,
5639 /*timeout*/ timeout);
5646 * Returns: 0 -- success, 1 -- error, 2 -- lba truncated,
5647 * 4 -- count truncated, 6 -- lba and count truncated.
5650 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5651 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5655 switch (ccb->ccb_h.func_code) {
5658 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5662 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5663 * or 16 byte, and need to see what
5665 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5666 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5668 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5669 if ((opcode != ATA_PASS_12)
5670 && (opcode != ATA_PASS_16)) {
5671 warnx("%s: unsupported opcode %02x", __func__, opcode);
5675 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5677 /* Note: the _ccb() variant returns 0 for an error */
5681 sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
5682 switch (error_code) {
5683 case SSD_DESC_CURRENT_ERROR:
5684 case SSD_DESC_DEFERRED_ERROR: {
5685 struct scsi_sense_data_desc *sense;
5686 struct scsi_sense_ata_ret_desc *desc;
5689 sense = (struct scsi_sense_data_desc *)
5690 &ccb->csio.sense_data;
5692 desc_ptr = scsi_find_desc(sense, sense_len,
5694 if (desc_ptr == NULL) {
5695 cam_error_print(dev, ccb, CAM_ESF_ALL,
5696 CAM_EPF_ALL, stderr);
5699 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5701 *error = desc->error;
5702 *count = (desc->count_15_8 << 8) |
5704 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5705 ((uint64_t)desc->lba_39_32 << 32) |
5706 ((uint64_t)desc->lba_31_24 << 24) |
5707 (desc->lba_23_16 << 16) |
5708 (desc->lba_15_8 << 8) |
5710 *device = desc->device;
5711 *status = desc->status;
5714 * If the extend bit isn't set, the result is for a
5715 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5716 * command without the extend bit set. This means
5717 * that the device is supposed to return 28-bit
5718 * status. The count field is only 8 bits, and the
5719 * LBA field is only 8 bits.
5721 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5727 case SSD_CURRENT_ERROR:
5728 case SSD_DEFERRED_ERROR: {
5732 * In my understanding of SAT-5 specification, saying:
5733 * "without interpreting the contents of the STATUS",
5734 * this should not happen if CK_COND was set, but it
5735 * does at least for some devices, so try to revert.
5737 if ((sense_key == SSD_KEY_ABORTED_COMMAND) &&
5738 (asc == 0) && (ascq == 0)) {
5739 *status = ATA_STATUS_ERROR;
5740 *error = ATA_ERROR_ABORT;
5747 if ((sense_key != SSD_KEY_RECOVERED_ERROR) ||
5748 (asc != 0x00) || (ascq != 0x1d))
5752 scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5753 SSD_DESC_INFO, &val, NULL);
5754 *error = (val >> 24) & 0xff;
5755 *status = (val >> 16) & 0xff;
5756 *device = (val >> 8) & 0xff;
5757 *count = val & 0xff;
5760 scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5761 SSD_DESC_COMMAND, &val, NULL);
5762 *lba = ((val >> 16) & 0xff) | (val & 0xff00) |
5763 ((val & 0xff) << 16);
5765 /* Report UPPER NONZERO bits as errors 2, 4 and 6. */
5766 return ((val >> 28) & 0x06);
5775 struct ata_res *res;
5777 /* Only some statuses return ATA result register set. */
5778 if (cam_ccb_status(ccb) != CAM_REQ_CMP &&
5779 cam_ccb_status(ccb) != CAM_ATA_STATUS_ERROR)
5782 res = &ccb->ataio.res;
5783 *error = res->error;
5784 *status = res->status;
5785 *device = res->device;
5786 *count = res->sector_count;
5787 *lba = (res->lba_high << 16) |
5788 (res->lba_mid << 8) |
5790 if (ccb->ataio.cmd.flags & CAM_ATAIO_48BIT) {
5791 *count |= (res->sector_count_exp << 8);
5792 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5793 ((uint64_t)res->lba_mid_exp << 32) |
5794 ((uint64_t)res->lba_high_exp << 40);
5796 *lba |= (res->device & 0xf) << 24;
5807 cpi_print(struct ccb_pathinq *cpi)
5809 char adapter_str[1024];
5812 snprintf(adapter_str, sizeof(adapter_str),
5813 "%s%d:", cpi->dev_name, cpi->unit_number);
5815 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5818 for (i = 1; i < UINT8_MAX; i = i << 1) {
5821 if ((i & cpi->hba_inquiry) == 0)
5824 fprintf(stdout, "%s supports ", adapter_str);
5828 str = "MDP message";
5831 str = "32 bit wide SCSI";
5834 str = "16 bit wide SCSI";
5837 str = "SDTR message";
5840 str = "linked CDBs";
5843 str = "tag queue messages";
5846 str = "soft reset alternative";
5849 str = "SATA Port Multiplier";
5852 str = "unknown PI bit set";
5855 fprintf(stdout, "%s\n", str);
5858 for (i = 1; i < UINT32_MAX; i = i << 1) {
5861 if ((i & cpi->hba_misc) == 0)
5864 fprintf(stdout, "%s ", adapter_str);
5868 str = "can understand ata_ext requests";
5871 str = "64bit extended LUNs supported";
5874 str = "bus scans from high ID to low ID";
5877 str = "removable devices not included in scan";
5879 case PIM_NOINITIATOR:
5880 str = "initiator role not supported";
5882 case PIM_NOBUSRESET:
5883 str = "user has disabled initial BUS RESET or"
5884 " controller is in target/mixed mode";
5887 str = "do not send 6-byte commands";
5890 str = "scan bus sequentially";
5893 str = "unmapped I/O supported";
5896 str = "does its own scanning";
5899 str = "unknown PIM bit set";
5902 fprintf(stdout, "%s\n", str);
5905 for (i = 1; i < UINT16_MAX; i = i << 1) {
5908 if ((i & cpi->target_sprt) == 0)
5911 fprintf(stdout, "%s supports ", adapter_str);
5914 str = "target mode processor mode";
5917 str = "target mode phase cog. mode";
5919 case PIT_DISCONNECT:
5920 str = "disconnects in target mode";
5923 str = "terminate I/O message in target mode";
5926 str = "group 6 commands in target mode";
5929 str = "group 7 commands in target mode";
5932 str = "unknown PIT bit set";
5936 fprintf(stdout, "%s\n", str);
5938 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5940 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5942 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5944 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5945 adapter_str, cpi->hpath_id);
5946 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5948 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5949 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5950 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5951 adapter_str, cpi->hba_vendor);
5952 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5953 adapter_str, cpi->hba_device);
5954 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5955 adapter_str, cpi->hba_subvendor);
5956 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5957 adapter_str, cpi->hba_subdevice);
5958 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5959 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5960 if (cpi->base_transfer_speed > 1000)
5961 fprintf(stdout, "%d.%03dMB/sec\n",
5962 cpi->base_transfer_speed / 1000,
5963 cpi->base_transfer_speed % 1000);
5965 fprintf(stdout, "%dKB/sec\n",
5966 (cpi->base_transfer_speed % 1000) * 1000);
5967 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5968 adapter_str, cpi->maxio);
5972 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5973 struct ccb_trans_settings *cts)
5979 ccb = cam_getccb(device);
5982 warnx("get_print_cts: error allocating ccb");
5986 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5988 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5990 if (user_settings == 0)
5991 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5993 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5995 if (cam_send_ccb(device, ccb) < 0) {
5996 warn("error sending XPT_GET_TRAN_SETTINGS CCB");
5998 goto get_print_cts_bailout;
6001 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6002 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
6003 if (arglist & CAM_ARG_VERBOSE)
6004 cam_error_print(device, ccb, CAM_ESF_ALL,
6005 CAM_EPF_ALL, stderr);
6007 goto get_print_cts_bailout;
6011 cts_print(device, &ccb->cts);
6014 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
6016 get_print_cts_bailout:
6024 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
6025 int timeout, int argc, char **argv, char *combinedopt)
6029 int user_settings = 0;
6031 int disc_enable = -1, tag_enable = -1;
6034 double syncrate = -1;
6037 int change_settings = 0, send_tur = 0;
6038 struct ccb_pathinq cpi;
6040 ccb = cam_getccb(device);
6042 warnx("ratecontrol: error allocating ccb");
6045 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6054 if (strncasecmp(optarg, "enable", 6) == 0)
6056 else if (strncasecmp(optarg, "disable", 7) == 0)
6059 warnx("-D argument \"%s\" is unknown", optarg);
6061 goto ratecontrol_bailout;
6063 change_settings = 1;
6066 mode = ata_string2mode(optarg);
6068 warnx("unknown mode '%s'", optarg);
6070 goto ratecontrol_bailout;
6072 change_settings = 1;
6075 offset = strtol(optarg, NULL, 0);
6077 warnx("offset value %d is < 0", offset);
6079 goto ratecontrol_bailout;
6081 change_settings = 1;
6087 syncrate = atof(optarg);
6089 warnx("sync rate %f is < 0", syncrate);
6091 goto ratecontrol_bailout;
6093 change_settings = 1;
6096 if (strncasecmp(optarg, "enable", 6) == 0)
6098 else if (strncasecmp(optarg, "disable", 7) == 0)
6101 warnx("-T argument \"%s\" is unknown", optarg);
6103 goto ratecontrol_bailout;
6105 change_settings = 1;
6111 bus_width = strtol(optarg, NULL, 0);
6112 if (bus_width < 0) {
6113 warnx("bus width %d is < 0", bus_width);
6115 goto ratecontrol_bailout;
6117 change_settings = 1;
6124 * Grab path inquiry information, so we can determine whether
6125 * or not the initiator is capable of the things that the user
6128 if ((retval = get_cpi(device, &cpi)) != 0)
6129 goto ratecontrol_bailout;
6130 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
6132 fprintf(stdout, "%s parameters:\n",
6133 user_settings ? "User" : "Current");
6135 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
6137 goto ratecontrol_bailout;
6139 if (arglist & CAM_ARG_VERBOSE)
6142 if (change_settings) {
6143 int didsettings = 0;
6144 struct ccb_trans_settings_spi *spi = NULL;
6145 struct ccb_trans_settings_pata *pata = NULL;
6146 struct ccb_trans_settings_sata *sata = NULL;
6147 struct ccb_trans_settings_ata *ata = NULL;
6148 struct ccb_trans_settings_scsi *scsi = NULL;
6150 if (ccb->cts.transport == XPORT_SPI)
6151 spi = &ccb->cts.xport_specific.spi;
6152 if (ccb->cts.transport == XPORT_ATA)
6153 pata = &ccb->cts.xport_specific.ata;
6154 if (ccb->cts.transport == XPORT_SATA)
6155 sata = &ccb->cts.xport_specific.sata;
6156 if (ccb->cts.protocol == PROTO_ATA)
6157 ata = &ccb->cts.proto_specific.ata;
6158 if (ccb->cts.protocol == PROTO_SCSI)
6159 scsi = &ccb->cts.proto_specific.scsi;
6160 ccb->cts.xport_specific.valid = 0;
6161 ccb->cts.proto_specific.valid = 0;
6162 if (spi && disc_enable != -1) {
6163 spi->valid |= CTS_SPI_VALID_DISC;
6164 if (disc_enable == 0)
6165 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6167 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6170 if (tag_enable != -1) {
6171 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6172 warnx("HBA does not support tagged queueing, "
6173 "so you cannot modify tag settings");
6175 goto ratecontrol_bailout;
6178 ata->valid |= CTS_SCSI_VALID_TQ;
6179 if (tag_enable == 0)
6180 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6182 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6185 scsi->valid |= CTS_SCSI_VALID_TQ;
6186 if (tag_enable == 0)
6187 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6189 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6193 if (spi && offset != -1) {
6194 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6195 warnx("HBA is not capable of changing offset");
6197 goto ratecontrol_bailout;
6199 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6200 spi->sync_offset = offset;
6203 if (spi && syncrate != -1) {
6204 int prelim_sync_period;
6206 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6207 warnx("HBA is not capable of changing "
6210 goto ratecontrol_bailout;
6212 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6214 * The sync rate the user gives us is in MHz.
6215 * We need to translate it into KHz for this
6220 * Next, we calculate a "preliminary" sync period
6221 * in tenths of a nanosecond.
6224 prelim_sync_period = 0;
6226 prelim_sync_period = 10000000 / syncrate;
6228 scsi_calc_syncparam(prelim_sync_period);
6231 if (sata && syncrate != -1) {
6232 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6233 warnx("HBA is not capable of changing "
6236 goto ratecontrol_bailout;
6238 if (!user_settings) {
6239 warnx("You can modify only user rate "
6240 "settings for SATA");
6242 goto ratecontrol_bailout;
6244 sata->revision = ata_speed2revision(syncrate * 100);
6245 if (sata->revision < 0) {
6246 warnx("Invalid rate %f", syncrate);
6248 goto ratecontrol_bailout;
6250 sata->valid |= CTS_SATA_VALID_REVISION;
6253 if ((pata || sata) && mode != -1) {
6254 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6255 warnx("HBA is not capable of changing "
6258 goto ratecontrol_bailout;
6260 if (!user_settings) {
6261 warnx("You can modify only user mode "
6262 "settings for ATA/SATA");
6264 goto ratecontrol_bailout;
6268 pata->valid |= CTS_ATA_VALID_MODE;
6271 sata->valid |= CTS_SATA_VALID_MODE;
6276 * The bus_width argument goes like this:
6280 * Therefore, if you shift the number of bits given on the
6281 * command line right by 4, you should get the correct
6284 if (spi && bus_width != -1) {
6286 * We might as well validate things here with a
6287 * decipherable error message, rather than what
6288 * will probably be an indecipherable error message
6289 * by the time it gets back to us.
6291 if ((bus_width == 16)
6292 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6293 warnx("HBA does not support 16 bit bus width");
6295 goto ratecontrol_bailout;
6296 } else if ((bus_width == 32)
6297 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6298 warnx("HBA does not support 32 bit bus width");
6300 goto ratecontrol_bailout;
6301 } else if ((bus_width != 8)
6302 && (bus_width != 16)
6303 && (bus_width != 32)) {
6304 warnx("Invalid bus width %d", bus_width);
6306 goto ratecontrol_bailout;
6308 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6309 spi->bus_width = bus_width >> 4;
6312 if (didsettings == 0) {
6313 goto ratecontrol_bailout;
6315 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6316 if (cam_send_ccb(device, ccb) < 0) {
6317 warn("error sending XPT_SET_TRAN_SETTINGS CCB");
6319 goto ratecontrol_bailout;
6321 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6322 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6323 if (arglist & CAM_ARG_VERBOSE) {
6324 cam_error_print(device, ccb, CAM_ESF_ALL,
6325 CAM_EPF_ALL, stderr);
6328 goto ratecontrol_bailout;
6332 retval = testunitready(device, task_attr, retry_count, timeout,
6333 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6335 * If the TUR didn't succeed, just bail.
6339 fprintf(stderr, "Test Unit Ready failed\n");
6340 goto ratecontrol_bailout;
6343 if ((change_settings || send_tur) && !quiet &&
6344 (ccb->cts.transport == XPORT_ATA ||
6345 ccb->cts.transport == XPORT_SATA || send_tur)) {
6346 fprintf(stdout, "New parameters:\n");
6347 retval = get_print_cts(device, user_settings, 0, NULL);
6350 ratecontrol_bailout:
6356 scsiformat(struct cam_device *device, int argc, char **argv,
6357 char *combinedopt, int task_attr, int retry_count, int timeout)
6361 int ycount = 0, quiet = 0;
6362 int error = 0, retval = 0;
6363 int use_timeout = 10800 * 1000;
6365 struct format_defect_list_header fh;
6366 u_int8_t *data_ptr = NULL;
6367 u_int32_t dxfer_len = 0;
6369 int num_warnings = 0;
6372 ccb = cam_getccb(device);
6375 warnx("scsiformat: error allocating ccb");
6379 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6381 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6401 if (quiet == 0 && ycount == 0) {
6402 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6403 "following device:\n");
6405 error = scsidoinquiry(device, argc, argv, combinedopt,
6406 task_attr, retry_count, timeout);
6409 warnx("scsiformat: error sending inquiry");
6410 goto scsiformat_bailout;
6415 if (!get_confirmation()) {
6417 goto scsiformat_bailout;
6422 use_timeout = timeout;
6425 fprintf(stdout, "Current format timeout is %d seconds\n",
6426 use_timeout / 1000);
6430 * If the user hasn't disabled questions and didn't specify a
6431 * timeout on the command line, ask them if they want the current
6435 && (timeout == 0)) {
6437 int new_timeout = 0;
6439 fprintf(stdout, "Enter new timeout in seconds or press\n"
6440 "return to keep the current timeout [%d] ",
6441 use_timeout / 1000);
6443 if (fgets(str, sizeof(str), stdin) != NULL) {
6445 new_timeout = atoi(str);
6448 if (new_timeout != 0) {
6449 use_timeout = new_timeout * 1000;
6450 fprintf(stdout, "Using new timeout value %d\n",
6451 use_timeout / 1000);
6456 * Keep this outside the if block below to silence any unused
6457 * variable warnings.
6459 bzero(&fh, sizeof(fh));
6462 * If we're in immediate mode, we've got to include the format
6465 if (immediate != 0) {
6466 fh.byte2 = FU_DLH_IMMED;
6467 data_ptr = (u_int8_t *)&fh;
6468 dxfer_len = sizeof(fh);
6469 byte2 = FU_FMT_DATA;
6470 } else if (quiet == 0) {
6471 fprintf(stdout, "Formatting...");
6475 scsi_format_unit(&ccb->csio,
6476 /* retries */ retry_count,
6478 /* tag_action */ task_attr,
6481 /* data_ptr */ data_ptr,
6482 /* dxfer_len */ dxfer_len,
6483 /* sense_len */ SSD_FULL_SIZE,
6484 /* timeout */ use_timeout);
6486 /* Disable freezing the device queue */
6487 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6489 if (arglist & CAM_ARG_ERR_RECOVER)
6490 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6492 if (((retval = cam_send_ccb(device, ccb)) < 0)
6493 || ((immediate == 0)
6494 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6495 const char errstr[] = "error sending format command";
6502 if (arglist & CAM_ARG_VERBOSE) {
6503 cam_error_print(device, ccb, CAM_ESF_ALL,
6504 CAM_EPF_ALL, stderr);
6507 goto scsiformat_bailout;
6511 * If we ran in non-immediate mode, we already checked for errors
6512 * above and printed out any necessary information. If we're in
6513 * immediate mode, we need to loop through and get status
6514 * information periodically.
6516 if (immediate == 0) {
6518 fprintf(stdout, "Format Complete\n");
6520 goto scsiformat_bailout;
6527 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6530 * There's really no need to do error recovery or
6531 * retries here, since we're just going to sit in a
6532 * loop and wait for the device to finish formatting.
6534 scsi_test_unit_ready(&ccb->csio,
6537 /* tag_action */ task_attr,
6538 /* sense_len */ SSD_FULL_SIZE,
6539 /* timeout */ 5000);
6541 /* Disable freezing the device queue */
6542 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6544 retval = cam_send_ccb(device, ccb);
6547 * If we get an error from the ioctl, bail out. SCSI
6548 * errors are expected.
6551 warn("error sending TEST UNIT READY command");
6553 goto scsiformat_bailout;
6556 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6558 if ((status != CAM_REQ_CMP)
6559 && (status == CAM_SCSI_STATUS_ERROR)
6560 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6561 struct scsi_sense_data *sense;
6562 int error_code, sense_key, asc, ascq;
6564 sense = &ccb->csio.sense_data;
6565 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6566 ccb->csio.sense_resid, &error_code, &sense_key,
6567 &asc, &ascq, /*show_errors*/ 1);
6570 * According to the SCSI-2 and SCSI-3 specs, a
6571 * drive that is in the middle of a format should
6572 * return NOT READY with an ASC of "logical unit
6573 * not ready, format in progress". The sense key
6574 * specific bytes will then be a progress indicator.
6576 if ((sense_key == SSD_KEY_NOT_READY)
6577 && (asc == 0x04) && (ascq == 0x04)) {
6580 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6581 ccb->csio.sense_resid, sks) == 0)
6584 u_int64_t percentage;
6586 val = scsi_2btoul(&sks[1]);
6587 percentage = 10000ull * val;
6590 "\rFormatting: %ju.%02u %% "
6592 (uintmax_t)(percentage /
6594 (unsigned)((percentage /
6598 } else if ((quiet == 0)
6599 && (++num_warnings <= 1)) {
6600 warnx("Unexpected SCSI Sense Key "
6601 "Specific value returned "
6603 scsi_sense_print(device, &ccb->csio,
6605 warnx("Unable to print status "
6606 "information, but format will "
6608 warnx("will exit when format is "
6613 warnx("Unexpected SCSI error during format");
6614 cam_error_print(device, ccb, CAM_ESF_ALL,
6615 CAM_EPF_ALL, stderr);
6617 goto scsiformat_bailout;
6620 } else if (status != CAM_REQ_CMP) {
6621 warnx("Unexpected CAM status %#x", status);
6622 if (arglist & CAM_ARG_VERBOSE)
6623 cam_error_print(device, ccb, CAM_ESF_ALL,
6624 CAM_EPF_ALL, stderr);
6626 goto scsiformat_bailout;
6629 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6632 fprintf(stdout, "\nFormat Complete\n");
6642 sanitize_wait_ata(struct cam_device *device, union ccb *ccb, int quiet,
6643 camcontrol_devtype devtype)
6646 uint8_t error = 0, ata_device = 0, status = 0;
6652 retval = build_ata_cmd(ccb,
6654 /*flags*/ CAM_DIR_NONE,
6655 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6656 /*protocol*/ AP_PROTO_NON_DATA,
6657 /*ata_flags*/ AP_FLAG_CHK_COND,
6658 /*features*/ 0x00, /* SANITIZE STATUS EXT */
6661 /*command*/ ATA_SANITIZE,
6665 /*cdb_storage*/ NULL,
6666 /*cdb_storage_len*/ 0,
6667 /*sense_len*/ SSD_FULL_SIZE,
6670 /*devtype*/ devtype);
6672 warnx("%s: build_ata_cmd() failed, likely "
6673 "programmer error", __func__);
6677 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6678 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6679 retval = cam_send_ccb(device, ccb);
6681 warn("error sending SANITIZE STATUS EXT command");
6685 retval = get_ata_status(device, ccb, &error, &count, &lba,
6686 &ata_device, &status);
6688 warnx("Can't get SANITIZE STATUS EXT status, "
6689 "sanitize may still run.");
6692 if (status & ATA_STATUS_ERROR) {
6693 warnx("SANITIZE STATUS EXT failed, "
6694 "sanitize may still run.");
6697 if (count & 0x4000) {
6702 "Sanitizing: %u.%02u%% (%d/%d)\r",
6703 (perc / (0x10000 * 100)),
6704 ((perc / 0x10000) % 100),
6709 } else if ((count & 0x8000) == 0) {
6710 warnx("Sanitize complete with an error. ");
6719 sanitize_wait_scsi(struct cam_device *device, union ccb *ccb, int task_attr, int quiet)
6721 int warnings = 0, retval;
6726 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6729 * There's really no need to do error recovery or
6730 * retries here, since we're just going to sit in a
6731 * loop and wait for the device to finish sanitizing.
6733 scsi_test_unit_ready(&ccb->csio,
6736 /* tag_action */ task_attr,
6737 /* sense_len */ SSD_FULL_SIZE,
6738 /* timeout */ 5000);
6740 /* Disable freezing the device queue */
6741 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6743 retval = cam_send_ccb(device, ccb);
6746 * If we get an error from the ioctl, bail out. SCSI
6747 * errors are expected.
6750 warn("error sending TEST UNIT READY command");
6754 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6755 if ((status == CAM_SCSI_STATUS_ERROR) &&
6756 ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6757 struct scsi_sense_data *sense;
6758 int error_code, sense_key, asc, ascq;
6760 sense = &ccb->csio.sense_data;
6761 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6762 ccb->csio.sense_resid, &error_code, &sense_key,
6763 &asc, &ascq, /*show_errors*/ 1);
6766 * According to the SCSI-3 spec, a drive that is in the
6767 * middle of a sanitize should return NOT READY with an
6768 * ASC of "logical unit not ready, sanitize in
6769 * progress". The sense key specific bytes will then
6770 * be a progress indicator.
6772 if ((sense_key == SSD_KEY_NOT_READY)
6773 && (asc == 0x04) && (ascq == 0x1b)) {
6776 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6777 ccb->csio.sense_resid, sks) == 0)
6779 val = scsi_2btoul(&sks[1]);
6782 "Sanitizing: %u.%02u%% (%d/%d)\r",
6783 (perc / (0x10000 * 100)),
6784 ((perc / 0x10000) % 100),
6787 } else if ((quiet == 0) && (++warnings <= 1)) {
6788 warnx("Unexpected SCSI Sense Key "
6789 "Specific value returned "
6790 "during sanitize:");
6791 scsi_sense_print(device, &ccb->csio,
6793 warnx("Unable to print status "
6794 "information, but sanitze will "
6796 warnx("will exit when sanitize is "
6801 warnx("Unexpected SCSI error during sanitize");
6802 cam_error_print(device, ccb, CAM_ESF_ALL,
6803 CAM_EPF_ALL, stderr);
6807 } else if (status != CAM_REQ_CMP && status != CAM_REQUEUE_REQ) {
6808 warnx("Unexpected CAM status %#x", status);
6809 if (arglist & CAM_ARG_VERBOSE)
6810 cam_error_print(device, ccb, CAM_ESF_ALL,
6811 CAM_EPF_ALL, stderr);
6814 } while ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6819 sanitize(struct cam_device *device, int argc, char **argv,
6820 char *combinedopt, int task_attr, int retry_count, int timeout)
6823 u_int8_t action = 0;
6825 int ycount = 0, quiet = 0;
6833 const char *pattern = NULL;
6834 u_int8_t *data_ptr = NULL;
6835 u_int32_t dxfer_len = 0;
6837 uint16_t feature, count;
6840 camcontrol_devtype dt;
6843 * Get the device type, request no I/O be done to do this.
6845 error = get_device_type(device, -1, 0, 0, &dt);
6846 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
6847 warnx("sanitize: can't get device type");
6851 ccb = cam_getccb(device);
6854 warnx("sanitize: error allocating ccb");
6858 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6860 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6863 if (strcasecmp(optarg, "overwrite") == 0)
6864 action = SSZ_SERVICE_ACTION_OVERWRITE;
6865 else if (strcasecmp(optarg, "block") == 0)
6866 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6867 else if (strcasecmp(optarg, "crypto") == 0)
6868 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6869 else if (strcasecmp(optarg, "exitfailure") == 0)
6870 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6872 warnx("invalid service operation \"%s\"",
6875 goto sanitize_bailout;
6879 passes = strtol(optarg, NULL, 0);
6880 if (passes < 1 || passes > 31) {
6881 warnx("invalid passes value %d", passes);
6883 goto sanitize_bailout;
6902 /* ATA supports only immediate commands. */
6903 if (dt == CC_DT_SCSI)
6916 warnx("an action is required");
6918 goto sanitize_bailout;
6919 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6920 struct scsi_sanitize_parameter_list *pl;
6924 if (pattern == NULL) {
6925 warnx("overwrite action requires -P argument");
6927 goto sanitize_bailout;
6929 fd = open(pattern, O_RDONLY);
6931 warn("cannot open pattern file %s", pattern);
6933 goto sanitize_bailout;
6935 if (fstat(fd, &sb) < 0) {
6936 warn("cannot stat pattern file %s", pattern);
6938 goto sanitize_bailout;
6941 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6942 warnx("pattern file size exceeds maximum value %d",
6943 SSZPL_MAX_PATTERN_LENGTH);
6945 goto sanitize_bailout;
6947 dxfer_len = sizeof(*pl) + sz;
6948 data_ptr = calloc(1, dxfer_len);
6949 if (data_ptr == NULL) {
6950 warnx("cannot allocate parameter list buffer");
6952 goto sanitize_bailout;
6955 amt = read(fd, data_ptr + sizeof(*pl), sz);
6957 warn("cannot read pattern file");
6959 goto sanitize_bailout;
6960 } else if (amt != sz) {
6961 warnx("short pattern file read");
6963 goto sanitize_bailout;
6966 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6972 pl->byte1 |= SSZPL_INVERT;
6973 scsi_ulto2b(sz, pl->length);
6979 else if (invert != 0)
6981 else if (pattern != NULL)
6986 warnx("%s argument only valid with overwrite "
6989 goto sanitize_bailout;
6993 if (quiet == 0 && ycount == 0) {
6994 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6995 "following device:\n");
6997 if (dt == CC_DT_SCSI) {
6998 error = scsidoinquiry(device, argc, argv, combinedopt,
6999 task_attr, retry_count, timeout);
7000 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7001 struct ata_params *ident_buf;
7002 error = ata_do_identify(device, retry_count, timeout,
7005 printf("%s%d: ", device->device_name,
7006 device->dev_unit_num);
7007 ata_print_ident(ident_buf);
7014 warnx("sanitize: error sending inquiry");
7015 goto sanitize_bailout;
7020 if (!get_confirmation()) {
7022 goto sanitize_bailout;
7027 use_timeout = timeout;
7029 use_timeout = (immediate ? 10 : 10800) * 1000;
7031 if (immediate == 0 && quiet == 0) {
7032 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
7033 use_timeout / 1000);
7037 * If the user hasn't disabled questions and didn't specify a
7038 * timeout on the command line, ask them if they want the current
7041 if (immediate == 0 && ycount == 0 && timeout == 0) {
7043 int new_timeout = 0;
7045 fprintf(stdout, "Enter new timeout in seconds or press\n"
7046 "return to keep the current timeout [%d] ",
7047 use_timeout / 1000);
7049 if (fgets(str, sizeof(str), stdin) != NULL) {
7051 new_timeout = atoi(str);
7054 if (new_timeout != 0) {
7055 use_timeout = new_timeout * 1000;
7056 fprintf(stdout, "Using new timeout value %d\n",
7057 use_timeout / 1000);
7061 if (dt == CC_DT_SCSI) {
7064 byte2 |= SSZ_UNRESTRICTED_EXIT;
7067 scsi_sanitize(&ccb->csio,
7068 /* retries */ retry_count,
7070 /* tag_action */ task_attr,
7073 /* data_ptr */ data_ptr,
7074 /* dxfer_len */ dxfer_len,
7075 /* sense_len */ SSD_FULL_SIZE,
7076 /* timeout */ use_timeout);
7078 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7079 if (arglist & CAM_ARG_ERR_RECOVER)
7080 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7081 if (cam_send_ccb(device, ccb) < 0) {
7082 warn("error sending sanitize command");
7084 goto sanitize_bailout;
7086 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7087 if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
7088 feature = 0x14; /* OVERWRITE EXT */
7089 lba = 0x4F5700000000 | scsi_4btoul(data_ptr + 4);
7090 count = (passes == 0) ? 1 : (passes >= 16) ? 0 : passes;
7092 count |= 0x80; /* INVERT PATTERN */
7094 count |= 0x10; /* FAILURE MODE */
7095 } else if (action == SSZ_SERVICE_ACTION_BLOCK_ERASE) {
7096 feature = 0x12; /* BLOCK ERASE EXT */
7097 lba = 0x0000426B4572;
7100 count |= 0x10; /* FAILURE MODE */
7101 } else if (action == SSZ_SERVICE_ACTION_CRYPTO_ERASE) {
7102 feature = 0x11; /* CRYPTO SCRAMBLE EXT */
7103 lba = 0x000043727970;
7106 count |= 0x10; /* FAILURE MODE */
7107 } else if (action == SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE) {
7108 feature = 0x00; /* SANITIZE STATUS EXT */
7110 count = 1; /* CLEAR SANITIZE OPERATION FAILED */
7113 goto sanitize_bailout;
7116 error = ata_do_cmd(device,
7119 /*flags*/CAM_DIR_NONE,
7120 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
7122 /*tag_action*/MSG_SIMPLE_Q_TAG,
7123 /*command*/ATA_SANITIZE,
7124 /*features*/feature,
7126 /*sector_count*/count,
7129 /*timeout*/ use_timeout,
7133 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7134 struct scsi_sense_data *sense;
7135 int error_code, sense_key, asc, ascq;
7137 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
7138 CAM_SCSI_STATUS_ERROR) {
7139 sense = &ccb->csio.sense_data;
7140 scsi_extract_sense_len(sense, ccb->csio.sense_len -
7141 ccb->csio.sense_resid, &error_code, &sense_key,
7142 &asc, &ascq, /*show_errors*/ 1);
7144 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
7145 asc == 0x20 && ascq == 0x00)
7146 warnx("sanitize is not supported by "
7149 warnx("error sanitizing this device");
7151 warnx("error sanitizing this device");
7153 if (arglist & CAM_ARG_VERBOSE) {
7154 cam_error_print(device, ccb, CAM_ESF_ALL,
7155 CAM_EPF_ALL, stderr);
7158 goto sanitize_bailout;
7162 * If we ran in non-immediate mode, we already checked for errors
7163 * above and printed out any necessary information. If we're in
7164 * immediate mode, we need to loop through and get status
7165 * information periodically.
7167 if (immediate == 0) {
7169 fprintf(stdout, "Sanitize Complete\n");
7171 goto sanitize_bailout;
7175 if (dt == CC_DT_SCSI) {
7176 error = sanitize_wait_scsi(device, ccb, task_attr, quiet);
7177 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7178 error = sanitize_wait_ata(device, ccb, quiet, dt);
7181 if (error == 0 && quiet == 0)
7182 fprintf(stdout, "Sanitize Complete \n");
7187 if (data_ptr != NULL)
7195 scsireportluns(struct cam_device *device, int argc, char **argv,
7196 char *combinedopt, int task_attr, int retry_count, int timeout)
7199 int c, countonly, lunsonly;
7200 struct scsi_report_luns_data *lundata;
7202 uint8_t report_type;
7203 uint32_t list_len, i, j;
7208 report_type = RPL_REPORT_DEFAULT;
7209 ccb = cam_getccb(device);
7212 warnx("%s: error allocating ccb", __func__);
7216 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7221 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7230 if (strcasecmp(optarg, "default") == 0)
7231 report_type = RPL_REPORT_DEFAULT;
7232 else if (strcasecmp(optarg, "wellknown") == 0)
7233 report_type = RPL_REPORT_WELLKNOWN;
7234 else if (strcasecmp(optarg, "all") == 0)
7235 report_type = RPL_REPORT_ALL;
7237 warnx("%s: invalid report type \"%s\"",
7248 if ((countonly != 0)
7249 && (lunsonly != 0)) {
7250 warnx("%s: you can only specify one of -c or -l", __func__);
7255 * According to SPC-4, the allocation length must be at least 16
7256 * bytes -- enough for the header and one LUN.
7258 alloc_len = sizeof(*lundata) + 8;
7262 lundata = malloc(alloc_len);
7264 if (lundata == NULL) {
7265 warn("%s: error mallocing %d bytes", __func__, alloc_len);
7270 scsi_report_luns(&ccb->csio,
7271 /*retries*/ retry_count,
7273 /*tag_action*/ task_attr,
7274 /*select_report*/ report_type,
7275 /*rpl_buf*/ lundata,
7276 /*alloc_len*/ alloc_len,
7277 /*sense_len*/ SSD_FULL_SIZE,
7278 /*timeout*/ timeout ? timeout : 5000);
7280 /* Disable freezing the device queue */
7281 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7283 if (arglist & CAM_ARG_ERR_RECOVER)
7284 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7286 if (cam_send_ccb(device, ccb) < 0) {
7287 warn("error sending REPORT LUNS command");
7292 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7293 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7299 list_len = scsi_4btoul(lundata->length);
7302 * If we need to list the LUNs, and our allocation
7303 * length was too short, reallocate and retry.
7305 if ((countonly == 0)
7306 && (list_len > (alloc_len - sizeof(*lundata)))) {
7307 alloc_len = list_len + sizeof(*lundata);
7313 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7314 ((list_len / 8) > 1) ? "s" : "");
7319 for (i = 0; i < (list_len / 8); i++) {
7323 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7325 fprintf(stdout, ",");
7326 switch (lundata->luns[i].lundata[j] &
7327 RPL_LUNDATA_ATYP_MASK) {
7328 case RPL_LUNDATA_ATYP_PERIPH:
7329 if ((lundata->luns[i].lundata[j] &
7330 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7331 fprintf(stdout, "%d:",
7332 lundata->luns[i].lundata[j] &
7333 RPL_LUNDATA_PERIPH_BUS_MASK);
7335 && ((lundata->luns[i].lundata[j+2] &
7336 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7339 fprintf(stdout, "%d",
7340 lundata->luns[i].lundata[j+1]);
7342 case RPL_LUNDATA_ATYP_FLAT: {
7344 tmplun[0] = lundata->luns[i].lundata[j] &
7345 RPL_LUNDATA_FLAT_LUN_MASK;
7346 tmplun[1] = lundata->luns[i].lundata[j+1];
7348 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7352 case RPL_LUNDATA_ATYP_LUN:
7353 fprintf(stdout, "%d:%d:%d",
7354 (lundata->luns[i].lundata[j+1] &
7355 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7356 lundata->luns[i].lundata[j] &
7357 RPL_LUNDATA_LUN_TARG_MASK,
7358 lundata->luns[i].lundata[j+1] &
7359 RPL_LUNDATA_LUN_LUN_MASK);
7361 case RPL_LUNDATA_ATYP_EXTLUN: {
7362 int field_len_code, eam_code;
7364 eam_code = lundata->luns[i].lundata[j] &
7365 RPL_LUNDATA_EXT_EAM_MASK;
7366 field_len_code = (lundata->luns[i].lundata[j] &
7367 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7369 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7370 && (field_len_code == 0x00)) {
7371 fprintf(stdout, "%d",
7372 lundata->luns[i].lundata[j+1]);
7373 } else if ((eam_code ==
7374 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7375 && (field_len_code == 0x03)) {
7379 * This format takes up all 8 bytes.
7380 * If we aren't starting at offset 0,
7384 fprintf(stdout, "Invalid "
7387 "specified format", j);
7391 bzero(tmp_lun, sizeof(tmp_lun));
7392 bcopy(&lundata->luns[i].lundata[j+1],
7393 &tmp_lun[1], sizeof(tmp_lun) - 1);
7394 fprintf(stdout, "%#jx",
7395 (intmax_t)scsi_8btou64(tmp_lun));
7398 fprintf(stderr, "Unknown Extended LUN"
7399 "Address method %#x, length "
7400 "code %#x", eam_code,
7407 fprintf(stderr, "Unknown LUN address method "
7408 "%#x\n", lundata->luns[i].lundata[0] &
7409 RPL_LUNDATA_ATYP_MASK);
7413 * For the flat addressing method, there are no
7414 * other levels after it.
7419 fprintf(stdout, "\n");
7432 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7433 char *combinedopt, int task_attr, int retry_count, int timeout)
7436 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7437 struct scsi_read_capacity_data rcap;
7438 struct scsi_read_capacity_data_long rcaplong;
7453 ccb = cam_getccb(device);
7456 warnx("%s: error allocating ccb", __func__);
7460 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7462 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7492 if ((blocksizeonly != 0)
7493 && (numblocks != 0)) {
7494 warnx("%s: you can only specify one of -b or -N", __func__);
7499 if ((blocksizeonly != 0)
7500 && (sizeonly != 0)) {
7501 warnx("%s: you can only specify one of -b or -s", __func__);
7508 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7514 && (blocksizeonly != 0)) {
7515 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7523 scsi_read_capacity(&ccb->csio,
7524 /*retries*/ retry_count,
7526 /*tag_action*/ task_attr,
7529 /*timeout*/ timeout ? timeout : 5000);
7531 /* Disable freezing the device queue */
7532 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7534 if (arglist & CAM_ARG_ERR_RECOVER)
7535 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7537 if (cam_send_ccb(device, ccb) < 0) {
7538 warn("error sending READ CAPACITY command");
7543 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7544 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7549 maxsector = scsi_4btoul(rcap.addr);
7550 block_len = scsi_4btoul(rcap.length);
7553 * A last block of 2^32-1 means that the true capacity is over 2TB,
7554 * and we need to issue the long READ CAPACITY to get the real
7555 * capacity. Otherwise, we're all set.
7557 if (maxsector != 0xffffffff)
7561 scsi_read_capacity_16(&ccb->csio,
7562 /*retries*/ retry_count,
7564 /*tag_action*/ task_attr,
7568 /*rcap_buf*/ (uint8_t *)&rcaplong,
7569 /*rcap_buf_len*/ sizeof(rcaplong),
7570 /*sense_len*/ SSD_FULL_SIZE,
7571 /*timeout*/ timeout ? timeout : 5000);
7573 /* Disable freezing the device queue */
7574 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7576 if (arglist & CAM_ARG_ERR_RECOVER)
7577 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7579 if (cam_send_ccb(device, ccb) < 0) {
7580 warn("error sending READ CAPACITY (16) command");
7585 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7586 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7591 maxsector = scsi_8btou64(rcaplong.addr);
7592 block_len = scsi_4btoul(rcaplong.length);
7595 if (blocksizeonly == 0) {
7597 * Humanize implies !quiet, and also implies numblocks.
7599 if (humanize != 0) {
7604 tmpbytes = (maxsector + 1) * block_len;
7605 ret = humanize_number(tmpstr, sizeof(tmpstr),
7606 tmpbytes, "", HN_AUTOSCALE,
7609 HN_DIVISOR_1000 : 0));
7611 warnx("%s: humanize_number failed!", __func__);
7615 fprintf(stdout, "Device Size: %s%s", tmpstr,
7616 (sizeonly == 0) ? ", " : "\n");
7617 } else if (numblocks != 0) {
7618 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7619 "Blocks: " : "", (uintmax_t)maxsector + 1,
7620 (sizeonly == 0) ? ", " : "\n");
7622 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7623 "Last Block: " : "", (uintmax_t)maxsector,
7624 (sizeonly == 0) ? ", " : "\n");
7628 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7629 "Block Length: " : "", block_len, (quiet == 0) ?
7638 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7639 int retry_count, int timeout)
7643 uint8_t *smp_request = NULL, *smp_response = NULL;
7644 int request_size = 0, response_size = 0;
7645 int fd_request = 0, fd_response = 0;
7646 char *datastr = NULL;
7647 struct get_hook hook;
7652 * Note that at the moment we don't support sending SMP CCBs to
7653 * devices that aren't probed by CAM.
7655 ccb = cam_getccb(device);
7657 warnx("%s: error allocating CCB", __func__);
7661 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7663 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7666 arglist |= CAM_ARG_CMD_IN;
7667 response_size = strtol(optarg, NULL, 0);
7668 if (response_size <= 0) {
7669 warnx("invalid number of response bytes %d",
7672 goto smpcmd_bailout;
7674 hook.argc = argc - optind;
7675 hook.argv = argv + optind;
7678 datastr = cget(&hook, NULL);
7680 * If the user supplied "-" instead of a format, he
7681 * wants the data to be written to stdout.
7683 if ((datastr != NULL)
7684 && (datastr[0] == '-'))
7687 smp_response = (u_int8_t *)malloc(response_size);
7688 if (smp_response == NULL) {
7689 warn("can't malloc memory for SMP response");
7691 goto smpcmd_bailout;
7695 arglist |= CAM_ARG_CMD_OUT;
7696 request_size = strtol(optarg, NULL, 0);
7697 if (request_size <= 0) {
7698 warnx("invalid number of request bytes %d",
7701 goto smpcmd_bailout;
7703 hook.argc = argc - optind;
7704 hook.argv = argv + optind;
7706 datastr = cget(&hook, NULL);
7707 smp_request = (u_int8_t *)malloc(request_size);
7708 if (smp_request == NULL) {
7709 warn("can't malloc memory for SMP request");
7711 goto smpcmd_bailout;
7713 bzero(smp_request, request_size);
7715 * If the user supplied "-" instead of a format, he
7716 * wants the data to be read from stdin.
7718 if ((datastr != NULL)
7719 && (datastr[0] == '-'))
7722 buff_encode_visit(smp_request, request_size,
7733 * If fd_data is set, and we're writing to the device, we need to
7734 * read the data the user wants written from stdin.
7736 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7738 int amt_to_read = request_size;
7739 u_int8_t *buf_ptr = smp_request;
7741 for (amt_read = 0; amt_to_read > 0;
7742 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7743 if (amt_read == -1) {
7744 warn("error reading data from stdin");
7746 goto smpcmd_bailout;
7748 amt_to_read -= amt_read;
7749 buf_ptr += amt_read;
7753 if (((arglist & CAM_ARG_CMD_IN) == 0)
7754 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7755 warnx("%s: need both the request (-r) and response (-R) "
7756 "arguments", __func__);
7758 goto smpcmd_bailout;
7761 flags |= CAM_DEV_QFRZDIS;
7763 cam_fill_smpio(&ccb->smpio,
7764 /*retries*/ retry_count,
7767 /*smp_request*/ smp_request,
7768 /*smp_request_len*/ request_size,
7769 /*smp_response*/ smp_response,
7770 /*smp_response_len*/ response_size,
7771 /*timeout*/ timeout ? timeout : 5000);
7773 ccb->smpio.flags = SMP_FLAG_NONE;
7775 if (((retval = cam_send_ccb(device, ccb)) < 0)
7776 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7777 const char warnstr[] = "error sending command";
7784 if (arglist & CAM_ARG_VERBOSE) {
7785 cam_error_print(device, ccb, CAM_ESF_ALL,
7786 CAM_EPF_ALL, stderr);
7790 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7791 && (response_size > 0)) {
7792 if (fd_response == 0) {
7793 buff_decode_visit(smp_response, response_size,
7794 datastr, arg_put, NULL);
7795 fprintf(stdout, "\n");
7797 ssize_t amt_written;
7798 int amt_to_write = response_size;
7799 u_int8_t *buf_ptr = smp_response;
7801 for (amt_written = 0; (amt_to_write > 0) &&
7802 (amt_written = write(STDOUT_FILENO, buf_ptr,
7803 amt_to_write)) > 0;){
7804 amt_to_write -= amt_written;
7805 buf_ptr += amt_written;
7807 if (amt_written == -1) {
7808 warn("error writing data to stdout");
7810 goto smpcmd_bailout;
7811 } else if ((amt_written == 0)
7812 && (amt_to_write > 0)) {
7813 warnx("only wrote %u bytes out of %u",
7814 response_size - amt_to_write,
7823 if (smp_request != NULL)
7826 if (smp_response != NULL)
7833 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7834 int retry_count, int timeout)
7838 int32_t mmc_opcode = 0, mmc_arg = 0;
7839 int32_t mmc_flags = -1;
7842 int is_bw_4 = 0, is_bw_1 = 0;
7843 int is_highspeed = 0, is_stdspeed = 0;
7844 int is_info_request = 0;
7846 uint8_t mmc_data_byte = 0;
7848 /* For IO_RW_EXTENDED command */
7849 uint8_t *mmc_data = NULL;
7850 struct mmc_data mmc_d;
7851 int mmc_data_len = 0;
7854 * Note that at the moment we don't support sending SMP CCBs to
7855 * devices that aren't probed by CAM.
7857 ccb = cam_getccb(device);
7859 warnx("%s: error allocating CCB", __func__);
7863 bzero(&(&ccb->ccb_h)[1],
7864 sizeof(union ccb) - sizeof(struct ccb_hdr));
7866 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7875 if (!strcmp(optarg, "high"))
7881 is_info_request = 1;
7884 mmc_opcode = strtol(optarg, NULL, 0);
7885 if (mmc_opcode < 0) {
7886 warnx("invalid MMC opcode %d",
7889 goto mmccmd_bailout;
7893 mmc_arg = strtol(optarg, NULL, 0);
7895 warnx("invalid MMC arg %d",
7898 goto mmccmd_bailout;
7902 mmc_flags = strtol(optarg, NULL, 0);
7903 if (mmc_flags < 0) {
7904 warnx("invalid MMC flags %d",
7907 goto mmccmd_bailout;
7911 mmc_data_len = strtol(optarg, NULL, 0);
7912 if (mmc_data_len <= 0) {
7913 warnx("invalid MMC data len %d",
7916 goto mmccmd_bailout;
7923 mmc_data_byte = strtol(optarg, NULL, 0);
7929 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7931 /* If flags are left default, supply the right flags */
7933 switch (mmc_opcode) {
7934 case MMC_GO_IDLE_STATE:
7935 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7937 case IO_SEND_OP_COND:
7938 mmc_flags = MMC_RSP_R4;
7940 case SD_SEND_RELATIVE_ADDR:
7941 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7943 case MMC_SELECT_CARD:
7944 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7945 mmc_arg = mmc_arg << 16;
7947 case SD_IO_RW_DIRECT:
7948 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7949 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7951 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7953 case SD_IO_RW_EXTENDED:
7954 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7955 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7956 int len_arg = mmc_data_len;
7957 if (mmc_data_len == 512)
7961 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7963 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7966 mmc_flags = MMC_RSP_R1;
7970 // Switch bus width instead of sending IO command
7971 if (is_bw_4 || is_bw_1) {
7972 struct ccb_trans_settings_mmc *cts;
7973 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7974 ccb->ccb_h.flags = 0;
7975 cts = &ccb->cts.proto_specific.mmc;
7976 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7977 cts->ios_valid = MMC_BW;
7978 if (((retval = cam_send_ccb(device, ccb)) < 0)
7979 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7980 warn("Error sending command");
7982 printf("Parameters set OK\n");
7988 // Switch bus speed instead of sending IO command
7989 if (is_stdspeed || is_highspeed) {
7990 struct ccb_trans_settings_mmc *cts;
7991 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7992 ccb->ccb_h.flags = 0;
7993 cts = &ccb->cts.proto_specific.mmc;
7994 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
7995 cts->ios_valid = MMC_BT;
7996 if (((retval = cam_send_ccb(device, ccb)) < 0)
7997 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7998 warn("Error sending command");
8000 printf("Speed set OK (HS: %d)\n", is_highspeed);
8006 // Get information about controller and its settings
8007 if (is_info_request) {
8008 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
8009 ccb->ccb_h.flags = 0;
8010 struct ccb_trans_settings_mmc *cts;
8011 cts = &ccb->cts.proto_specific.mmc;
8012 if (((retval = cam_send_ccb(device, ccb)) < 0)
8013 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8014 warn("Error sending command");
8017 printf("Host controller information\n");
8018 printf("Host OCR: 0x%x\n", cts->host_ocr);
8019 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
8020 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
8021 printf("Supported bus width: ");
8022 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
8024 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
8026 printf("\nCurrent settings:\n");
8027 printf("Bus width: ");
8028 switch (cts->ios.bus_width) {
8039 printf("Freq: %d.%03d MHz%s\n",
8040 cts->ios.clock / 1000000,
8041 (cts->ios.clock / 1000) % 1000,
8042 cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : "");
8046 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
8048 if (mmc_data_len > 0) {
8049 flags |= CAM_DIR_IN;
8050 mmc_data = malloc(mmc_data_len);
8051 memset(mmc_data, 0, mmc_data_len);
8052 memset(&mmc_d, 0, sizeof(mmc_d));
8053 mmc_d.len = mmc_data_len;
8054 mmc_d.data = mmc_data;
8055 mmc_d.flags = MMC_DATA_READ;
8056 } else flags |= CAM_DIR_NONE;
8058 cam_fill_mmcio(&ccb->mmcio,
8059 /*retries*/ retry_count,
8062 /*mmc_opcode*/ mmc_opcode,
8063 /*mmc_arg*/ mmc_arg,
8064 /*mmc_flags*/ mmc_flags,
8065 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
8066 /*timeout*/ timeout ? timeout : 5000);
8068 if (((retval = cam_send_ccb(device, ccb)) < 0)
8069 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8070 const char warnstr[] = "error sending command";
8077 if (arglist & CAM_ARG_VERBOSE) {
8078 cam_error_print(device, ccb, CAM_ESF_ALL,
8079 CAM_EPF_ALL, stderr);
8083 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
8084 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
8085 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
8086 ccb->mmcio.cmd.resp[1],
8087 ccb->mmcio.cmd.resp[2],
8088 ccb->mmcio.cmd.resp[3]);
8090 switch (mmc_opcode) {
8091 case SD_IO_RW_DIRECT:
8092 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
8093 SD_R5_DATA(ccb->mmcio.cmd.resp),
8094 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
8096 case SD_IO_RW_EXTENDED:
8097 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
8098 hexdump(mmc_data, mmc_data_len, NULL, 0);
8100 case SD_SEND_RELATIVE_ADDR:
8101 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
8104 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
8111 if (mmc_data_len > 0 && mmc_data != NULL)
8118 smpreportgeneral(struct cam_device *device, int argc, char **argv,
8119 char *combinedopt, int retry_count, int timeout)
8122 struct smp_report_general_request *request = NULL;
8123 struct smp_report_general_response *response = NULL;
8124 struct sbuf *sb = NULL;
8126 int c, long_response = 0;
8130 * Note that at the moment we don't support sending SMP CCBs to
8131 * devices that aren't probed by CAM.
8133 ccb = cam_getccb(device);
8135 warnx("%s: error allocating CCB", __func__);
8139 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8141 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8150 request = malloc(sizeof(*request));
8151 if (request == NULL) {
8152 warn("%s: unable to allocate %zd bytes", __func__,
8158 response = malloc(sizeof(*response));
8159 if (response == NULL) {
8160 warn("%s: unable to allocate %zd bytes", __func__,
8167 smp_report_general(&ccb->smpio,
8171 /*request_len*/ sizeof(*request),
8172 (uint8_t *)response,
8173 /*response_len*/ sizeof(*response),
8174 /*long_response*/ long_response,
8177 if (((retval = cam_send_ccb(device, ccb)) < 0)
8178 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8179 const char warnstr[] = "error sending command";
8186 if (arglist & CAM_ARG_VERBOSE) {
8187 cam_error_print(device, ccb, CAM_ESF_ALL,
8188 CAM_EPF_ALL, stderr);
8195 * If the device supports the long response bit, try again and see
8196 * if we can get all of the data.
8198 if ((response->long_response & SMP_RG_LONG_RESPONSE)
8199 && (long_response == 0)) {
8200 ccb->ccb_h.status = CAM_REQ_INPROG;
8201 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8207 * XXX KDM detect and decode SMP errors here.
8209 sb = sbuf_new_auto();
8211 warnx("%s: error allocating sbuf", __func__);
8215 smp_report_general_sbuf(response, sizeof(*response), sb);
8217 if (sbuf_finish(sb) != 0) {
8218 warnx("%s: sbuf_finish", __func__);
8222 printf("%s", sbuf_data(sb));
8228 if (request != NULL)
8231 if (response != NULL)
8240 static struct camcontrol_opts phy_ops[] = {
8241 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
8242 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
8243 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
8244 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
8245 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
8246 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
8247 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
8248 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
8249 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
8254 smpphycontrol(struct cam_device *device, int argc, char **argv,
8255 char *combinedopt, int retry_count, int timeout)
8258 struct smp_phy_control_request *request = NULL;
8259 struct smp_phy_control_response *response = NULL;
8260 int long_response = 0;
8263 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
8265 uint64_t attached_dev_name = 0;
8266 int dev_name_set = 0;
8267 uint32_t min_plr = 0, max_plr = 0;
8268 uint32_t pp_timeout_val = 0;
8269 int slumber_partial = 0;
8270 int set_pp_timeout_val = 0;
8274 * Note that at the moment we don't support sending SMP CCBs to
8275 * devices that aren't probed by CAM.
8277 ccb = cam_getccb(device);
8279 warnx("%s: error allocating CCB", __func__);
8283 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8285 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8293 if (strcasecmp(optarg, "enable") == 0)
8295 else if (strcasecmp(optarg, "disable") == 0)
8298 warnx("%s: Invalid argument %s", __func__,
8305 slumber_partial |= enable <<
8306 SMP_PC_SAS_SLUMBER_SHIFT;
8309 slumber_partial |= enable <<
8310 SMP_PC_SAS_PARTIAL_SHIFT;
8313 slumber_partial |= enable <<
8314 SMP_PC_SATA_SLUMBER_SHIFT;
8317 slumber_partial |= enable <<
8318 SMP_PC_SATA_PARTIAL_SHIFT;
8321 warnx("%s: programmer error", __func__);
8324 break; /*NOTREACHED*/
8329 attached_dev_name = (uintmax_t)strtoumax(optarg,
8338 * We don't do extensive checking here, so this
8339 * will continue to work when new speeds come out.
8341 min_plr = strtoul(optarg, NULL, 0);
8343 || (min_plr > 0xf)) {
8344 warnx("%s: invalid link rate %x",
8352 * We don't do extensive checking here, so this
8353 * will continue to work when new speeds come out.
8355 max_plr = strtoul(optarg, NULL, 0);
8357 || (max_plr > 0xf)) {
8358 warnx("%s: invalid link rate %x",
8365 camcontrol_optret optreturn;
8366 cam_argmask argnums;
8369 if (phy_op_set != 0) {
8370 warnx("%s: only one phy operation argument "
8371 "(-o) allowed", __func__);
8379 * Allow the user to specify the phy operation
8380 * numerically, as well as with a name. This will
8381 * future-proof it a bit, so options that are added
8382 * in future specs can be used.
8384 if (isdigit(optarg[0])) {
8385 phy_operation = strtoul(optarg, NULL, 0);
8386 if ((phy_operation == 0)
8387 || (phy_operation > 0xff)) {
8388 warnx("%s: invalid phy operation %#x",
8389 __func__, phy_operation);
8395 optreturn = getoption(phy_ops, optarg, &phy_operation,
8398 if (optreturn == CC_OR_AMBIGUOUS) {
8399 warnx("%s: ambiguous option %s", __func__,
8404 } else if (optreturn == CC_OR_NOT_FOUND) {
8405 warnx("%s: option %s not found", __func__,
8417 pp_timeout_val = strtoul(optarg, NULL, 0);
8418 if (pp_timeout_val > 15) {
8419 warnx("%s: invalid partial pathway timeout "
8420 "value %u, need a value less than 16",
8421 __func__, pp_timeout_val);
8425 set_pp_timeout_val = 1;
8433 warnx("%s: a PHY (-p phy) argument is required",__func__);
8438 if (((dev_name_set != 0)
8439 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8440 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8441 && (dev_name_set == 0))) {
8442 warnx("%s: -d name and -o setdevname arguments both "
8443 "required to set device name", __func__);
8448 request = malloc(sizeof(*request));
8449 if (request == NULL) {
8450 warn("%s: unable to allocate %zd bytes", __func__,
8456 response = malloc(sizeof(*response));
8457 if (response == NULL) {
8458 warn("%s: unable to allocate %zd bytes", __func__,
8464 smp_phy_control(&ccb->smpio,
8469 (uint8_t *)response,
8472 /*expected_exp_change_count*/ 0,
8475 (set_pp_timeout_val != 0) ? 1 : 0,
8483 if (((retval = cam_send_ccb(device, ccb)) < 0)
8484 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8485 const char warnstr[] = "error sending command";
8492 if (arglist & CAM_ARG_VERBOSE) {
8494 * Use CAM_EPF_NORMAL so we only get one line of
8495 * SMP command decoding.
8497 cam_error_print(device, ccb, CAM_ESF_ALL,
8498 CAM_EPF_NORMAL, stderr);
8504 /* XXX KDM print out something here for success? */
8509 if (request != NULL)
8512 if (response != NULL)
8519 smpmaninfo(struct cam_device *device, int argc, char **argv,
8520 char *combinedopt, int retry_count, int timeout)
8523 struct smp_report_manuf_info_request request;
8524 struct smp_report_manuf_info_response response;
8525 struct sbuf *sb = NULL;
8526 int long_response = 0;
8531 * Note that at the moment we don't support sending SMP CCBs to
8532 * devices that aren't probed by CAM.
8534 ccb = cam_getccb(device);
8536 warnx("%s: error allocating CCB", __func__);
8540 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8542 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8551 bzero(&request, sizeof(request));
8552 bzero(&response, sizeof(response));
8554 smp_report_manuf_info(&ccb->smpio,
8559 (uint8_t *)&response,
8564 if (((retval = cam_send_ccb(device, ccb)) < 0)
8565 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8566 const char warnstr[] = "error sending command";
8573 if (arglist & CAM_ARG_VERBOSE) {
8574 cam_error_print(device, ccb, CAM_ESF_ALL,
8575 CAM_EPF_ALL, stderr);
8581 sb = sbuf_new_auto();
8583 warnx("%s: error allocating sbuf", __func__);
8587 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8589 if (sbuf_finish(sb) != 0) {
8590 warnx("%s: sbuf_finish", __func__);
8594 printf("%s", sbuf_data(sb));
8608 getdevid(struct cam_devitem *item)
8611 union ccb *ccb = NULL;
8613 struct cam_device *dev;
8615 dev = cam_open_btl(item->dev_match.path_id,
8616 item->dev_match.target_id,
8617 item->dev_match.target_lun, O_RDWR, NULL);
8620 warnx("%s", cam_errbuf);
8625 item->device_id_len = 0;
8627 ccb = cam_getccb(dev);
8629 warnx("%s: error allocating CCB", __func__);
8634 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8637 * On the first try, we just probe for the size of the data, and
8638 * then allocate that much memory and try again.
8641 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8642 ccb->ccb_h.flags = CAM_DIR_IN;
8643 ccb->cdai.flags = CDAI_FLAG_NONE;
8644 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8645 ccb->cdai.bufsiz = item->device_id_len;
8646 if (item->device_id_len != 0)
8647 ccb->cdai.buf = (uint8_t *)item->device_id;
8649 if (cam_send_ccb(dev, ccb) < 0) {
8650 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8655 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8656 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8661 if (item->device_id_len == 0) {
8663 * This is our first time through. Allocate the buffer,
8664 * and then go back to get the data.
8666 if (ccb->cdai.provsiz == 0) {
8667 warnx("%s: invalid .provsiz field returned with "
8668 "XPT_GDEV_ADVINFO CCB", __func__);
8672 item->device_id_len = ccb->cdai.provsiz;
8673 item->device_id = malloc(item->device_id_len);
8674 if (item->device_id == NULL) {
8675 warn("%s: unable to allocate %d bytes", __func__,
8676 item->device_id_len);
8680 ccb->ccb_h.status = CAM_REQ_INPROG;
8686 cam_close_device(dev);
8695 * XXX KDM merge this code with getdevtree()?
8698 buildbusdevlist(struct cam_devlist *devlist)
8701 int bufsize, fd = -1;
8702 struct dev_match_pattern *patterns;
8703 struct cam_devitem *item = NULL;
8704 int skip_device = 0;
8707 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8708 warn("couldn't open %s", XPT_DEVICE);
8712 bzero(&ccb, sizeof(union ccb));
8714 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8715 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8716 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8718 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8719 bufsize = sizeof(struct dev_match_result) * 100;
8720 ccb.cdm.match_buf_len = bufsize;
8721 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8722 if (ccb.cdm.matches == NULL) {
8723 warnx("can't malloc memory for matches");
8727 ccb.cdm.num_matches = 0;
8728 ccb.cdm.num_patterns = 2;
8729 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8730 ccb.cdm.num_patterns;
8732 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8733 if (patterns == NULL) {
8734 warnx("can't malloc memory for patterns");
8739 ccb.cdm.patterns = patterns;
8740 bzero(patterns, ccb.cdm.pattern_buf_len);
8742 patterns[0].type = DEV_MATCH_DEVICE;
8743 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8744 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8745 patterns[1].type = DEV_MATCH_PERIPH;
8746 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8747 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8750 * We do the ioctl multiple times if necessary, in case there are
8751 * more than 100 nodes in the EDT.
8756 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8757 warn("error sending CAMIOCOMMAND ioctl");
8762 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8763 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8764 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8765 warnx("got CAM error %#x, CDM error %d\n",
8766 ccb.ccb_h.status, ccb.cdm.status);
8771 for (i = 0; i < ccb.cdm.num_matches; i++) {
8772 switch (ccb.cdm.matches[i].type) {
8773 case DEV_MATCH_DEVICE: {
8774 struct device_match_result *dev_result;
8777 &ccb.cdm.matches[i].result.device_result;
8779 if (dev_result->flags &
8780 DEV_RESULT_UNCONFIGURED) {
8786 item = malloc(sizeof(*item));
8788 warn("%s: unable to allocate %zd bytes",
8789 __func__, sizeof(*item));
8793 bzero(item, sizeof(*item));
8794 bcopy(dev_result, &item->dev_match,
8795 sizeof(*dev_result));
8796 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8799 if (getdevid(item) != 0) {
8805 case DEV_MATCH_PERIPH: {
8806 struct periph_match_result *periph_result;
8809 &ccb.cdm.matches[i].result.periph_result;
8811 if (skip_device != 0)
8813 item->num_periphs++;
8814 item->periph_matches = realloc(
8815 item->periph_matches,
8817 sizeof(struct periph_match_result));
8818 if (item->periph_matches == NULL) {
8819 warn("%s: error allocating periph "
8824 bcopy(periph_result, &item->periph_matches[
8825 item->num_periphs - 1],
8826 sizeof(*periph_result));
8830 fprintf(stderr, "%s: unexpected match "
8831 "type %d\n", __func__,
8832 ccb.cdm.matches[i].type);
8835 break; /*NOTREACHED*/
8838 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8839 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8847 free(ccb.cdm.matches);
8850 freebusdevlist(devlist);
8856 freebusdevlist(struct cam_devlist *devlist)
8858 struct cam_devitem *item, *item2;
8860 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8861 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8863 free(item->device_id);
8864 free(item->periph_matches);
8869 static struct cam_devitem *
8870 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8872 struct cam_devitem *item;
8874 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8875 struct scsi_vpd_id_descriptor *idd;
8878 * XXX KDM look for LUN IDs as well?
8880 idd = scsi_get_devid(item->device_id,
8881 item->device_id_len,
8882 scsi_devid_is_sas_target);
8886 if (scsi_8btou64(idd->identifier) == sasaddr)
8894 smpphylist(struct cam_device *device, int argc, char **argv,
8895 char *combinedopt, int retry_count, int timeout)
8897 struct smp_report_general_request *rgrequest = NULL;
8898 struct smp_report_general_response *rgresponse = NULL;
8899 struct smp_discover_request *disrequest = NULL;
8900 struct smp_discover_response *disresponse = NULL;
8901 struct cam_devlist devlist;
8903 int long_response = 0;
8910 * Note that at the moment we don't support sending SMP CCBs to
8911 * devices that aren't probed by CAM.
8913 ccb = cam_getccb(device);
8915 warnx("%s: error allocating CCB", __func__);
8919 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8920 STAILQ_INIT(&devlist.dev_queue);
8922 rgrequest = malloc(sizeof(*rgrequest));
8923 if (rgrequest == NULL) {
8924 warn("%s: unable to allocate %zd bytes", __func__,
8925 sizeof(*rgrequest));
8930 rgresponse = malloc(sizeof(*rgresponse));
8931 if (rgresponse == NULL) {
8932 warn("%s: unable to allocate %zd bytes", __func__,
8933 sizeof(*rgresponse));
8938 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8951 smp_report_general(&ccb->smpio,
8955 /*request_len*/ sizeof(*rgrequest),
8956 (uint8_t *)rgresponse,
8957 /*response_len*/ sizeof(*rgresponse),
8958 /*long_response*/ long_response,
8961 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8963 if (((retval = cam_send_ccb(device, ccb)) < 0)
8964 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8965 const char warnstr[] = "error sending command";
8972 if (arglist & CAM_ARG_VERBOSE) {
8973 cam_error_print(device, ccb, CAM_ESF_ALL,
8974 CAM_EPF_ALL, stderr);
8980 num_phys = rgresponse->num_phys;
8982 if (num_phys == 0) {
8984 fprintf(stdout, "%s: No Phys reported\n", __func__);
8989 devlist.path_id = device->path_id;
8991 retval = buildbusdevlist(&devlist);
8996 fprintf(stdout, "%d PHYs:\n", num_phys);
8997 fprintf(stdout, "PHY Attached SAS Address\n");
9000 disrequest = malloc(sizeof(*disrequest));
9001 if (disrequest == NULL) {
9002 warn("%s: unable to allocate %zd bytes", __func__,
9003 sizeof(*disrequest));
9008 disresponse = malloc(sizeof(*disresponse));
9009 if (disresponse == NULL) {
9010 warn("%s: unable to allocate %zd bytes", __func__,
9011 sizeof(*disresponse));
9016 for (i = 0; i < num_phys; i++) {
9017 struct cam_devitem *item;
9018 struct device_match_result *dev_match;
9019 char vendor[16], product[48], revision[16];
9023 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
9025 ccb->ccb_h.status = CAM_REQ_INPROG;
9026 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9028 smp_discover(&ccb->smpio,
9032 sizeof(*disrequest),
9033 (uint8_t *)disresponse,
9034 sizeof(*disresponse),
9036 /*ignore_zone_group*/ 0,
9040 if (((retval = cam_send_ccb(device, ccb)) < 0)
9041 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
9042 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
9043 const char warnstr[] = "error sending command";
9050 if (arglist & CAM_ARG_VERBOSE) {
9051 cam_error_print(device, ccb, CAM_ESF_ALL,
9052 CAM_EPF_ALL, stderr);
9058 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
9060 fprintf(stdout, "%3d <vacant>\n", i);
9064 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
9067 item = findsasdevice(&devlist,
9068 scsi_8btou64(disresponse->attached_sas_address));
9072 || (item != NULL)) {
9073 fprintf(stdout, "%3d 0x%016jx", i,
9074 (uintmax_t)scsi_8btou64(
9075 disresponse->attached_sas_address));
9077 fprintf(stdout, "\n");
9080 } else if (quiet != 0)
9083 dev_match = &item->dev_match;
9085 if (dev_match->protocol == PROTO_SCSI) {
9086 cam_strvis(vendor, dev_match->inq_data.vendor,
9087 sizeof(dev_match->inq_data.vendor),
9089 cam_strvis(product, dev_match->inq_data.product,
9090 sizeof(dev_match->inq_data.product),
9092 cam_strvis(revision, dev_match->inq_data.revision,
9093 sizeof(dev_match->inq_data.revision),
9095 sprintf(tmpstr, "<%s %s %s>", vendor, product,
9097 } else if ((dev_match->protocol == PROTO_ATA)
9098 || (dev_match->protocol == PROTO_SATAPM)) {
9099 cam_strvis(product, dev_match->ident_data.model,
9100 sizeof(dev_match->ident_data.model),
9102 cam_strvis(revision, dev_match->ident_data.revision,
9103 sizeof(dev_match->ident_data.revision),
9105 sprintf(tmpstr, "<%s %s>", product, revision);
9107 sprintf(tmpstr, "<>");
9109 fprintf(stdout, " %-33s ", tmpstr);
9112 * If we have 0 periphs, that's a bug...
9114 if (item->num_periphs == 0) {
9115 fprintf(stdout, "\n");
9119 fprintf(stdout, "(");
9120 for (j = 0; j < item->num_periphs; j++) {
9122 fprintf(stdout, ",");
9124 fprintf(stdout, "%s%d",
9125 item->periph_matches[j].periph_name,
9126 item->periph_matches[j].unit_number);
9129 fprintf(stdout, ")\n");
9143 freebusdevlist(&devlist);
9149 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
9151 uint8_t error = 0, ata_device = 0, status = 0;
9156 retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
9159 if (arglist & CAM_ARG_VERBOSE) {
9160 cam_error_print(device, ccb, CAM_ESF_ALL,
9161 CAM_EPF_ALL, stderr);
9163 warnx("Can't get ATA command status");
9167 if (status & ATA_STATUS_ERROR) {
9168 cam_error_print(device, ccb, CAM_ESF_ALL,
9169 CAM_EPF_ALL, stderr);
9173 printf("%s%d: ", device->device_name, device->dev_unit_num);
9176 printf("Standby mode\n");
9179 printf("Standby_y mode\n");
9182 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
9185 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
9188 printf("Idle mode\n");
9191 printf("Idle_a mode\n");
9194 printf("Idle_b mode\n");
9197 printf("Idle_c mode\n");
9200 printf("Active or Idle mode\n");
9203 printf("Unknown mode 0x%02x\n", count);
9211 atapm(struct cam_device *device, int argc, char **argv,
9212 char *combinedopt, int retry_count, int timeout)
9218 u_int8_t ata_flags = 0;
9221 ccb = cam_getccb(device);
9224 warnx("%s: error allocating ccb", __func__);
9228 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9237 if (strcmp(argv[1], "idle") == 0) {
9239 cmd = ATA_IDLE_IMMEDIATE;
9242 } else if (strcmp(argv[1], "standby") == 0) {
9244 cmd = ATA_STANDBY_IMMEDIATE;
9246 cmd = ATA_STANDBY_CMD;
9247 } else if (strcmp(argv[1], "powermode") == 0) {
9248 cmd = ATA_CHECK_POWER_MODE;
9249 ata_flags = AP_FLAG_CHK_COND;
9258 else if (t <= (240 * 5))
9260 else if (t <= (252 * 5))
9261 /* special encoding for 21 minutes */
9263 else if (t <= (11 * 30 * 60))
9264 sc = (t - 1) / (30 * 60) + 241;
9268 retval = ata_do_cmd(device,
9270 /*retries*/retry_count,
9271 /*flags*/CAM_DIR_NONE,
9272 /*protocol*/AP_PROTO_NON_DATA,
9273 /*ata_flags*/ata_flags,
9274 /*tag_action*/MSG_SIMPLE_Q_TAG,
9281 /*timeout*/timeout ? timeout : 30 * 1000,
9286 if (retval || cmd != ATA_CHECK_POWER_MODE)
9289 return (atapm_proc_resp(device, ccb));
9293 ataaxm(struct cam_device *device, int argc, char **argv,
9294 char *combinedopt, int retry_count, int timeout)
9302 ccb = cam_getccb(device);
9305 warnx("%s: error allocating ccb", __func__);
9309 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9319 if (strcmp(argv[1], "apm") == 0) {
9335 retval = ata_do_cmd(device,
9337 /*retries*/retry_count,
9338 /*flags*/CAM_DIR_NONE,
9339 /*protocol*/AP_PROTO_NON_DATA,
9341 /*tag_action*/MSG_SIMPLE_Q_TAG,
9342 /*command*/ATA_SETFEATURES,
9348 /*timeout*/timeout ? timeout : 30 * 1000,
9356 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9357 int show_sa_errors, int sa_set, int service_action,
9358 int timeout_desc, int task_attr, int retry_count, int timeout,
9359 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9361 union ccb *ccb = NULL;
9362 uint8_t *buf = NULL;
9363 uint32_t alloc_len = 0, num_opcodes;
9364 uint32_t valid_len = 0;
9365 uint32_t avail_len = 0;
9366 struct scsi_report_supported_opcodes_all *all_hdr;
9367 struct scsi_report_supported_opcodes_one *one;
9372 * Make it clear that we haven't yet allocated or filled anything.
9377 ccb = cam_getccb(device);
9379 warnx("couldn't allocate CCB");
9384 /* cam_getccb cleans up the header, caller has to zero the payload */
9385 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9387 if (opcode_set != 0) {
9388 options |= RSO_OPTIONS_OC;
9390 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9393 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9394 sizeof(struct scsi_report_supported_opcodes_descr));
9397 if (timeout_desc != 0) {
9398 options |= RSO_RCTD;
9399 alloc_len += num_opcodes *
9400 sizeof(struct scsi_report_supported_opcodes_timeout);
9404 options |= RSO_OPTIONS_OC_SA;
9405 if (show_sa_errors != 0)
9406 options &= ~RSO_OPTIONS_OC;
9415 buf = malloc(alloc_len);
9417 warn("Unable to allocate %u bytes", alloc_len);
9421 bzero(buf, alloc_len);
9423 scsi_report_supported_opcodes(&ccb->csio,
9424 /*retries*/ retry_count,
9426 /*tag_action*/ task_attr,
9427 /*options*/ options,
9428 /*req_opcode*/ opcode,
9429 /*req_service_action*/ service_action,
9431 /*dxfer_len*/ alloc_len,
9432 /*sense_len*/ SSD_FULL_SIZE,
9433 /*timeout*/ timeout ? timeout : 10000);
9435 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9437 if (retry_count != 0)
9438 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9440 if (cam_send_ccb(device, ccb) < 0) {
9441 warn("error sending REPORT SUPPORTED OPERATION CODES command");
9446 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9447 if (verbosemode != 0)
9448 cam_error_print(device, ccb, CAM_ESF_ALL,
9449 CAM_EPF_ALL, stderr);
9454 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9456 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9457 && (valid_len >= sizeof(*all_hdr))) {
9458 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9459 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9460 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9461 && (valid_len >= sizeof(*one))) {
9462 uint32_t cdb_length;
9464 one = (struct scsi_report_supported_opcodes_one *)buf;
9465 cdb_length = scsi_2btoul(one->cdb_length);
9466 avail_len = sizeof(*one) + cdb_length;
9467 if (one->support & RSO_ONE_CTDP) {
9468 struct scsi_report_supported_opcodes_timeout *td;
9470 td = (struct scsi_report_supported_opcodes_timeout *)
9472 if (valid_len >= (avail_len + sizeof(td->length))) {
9473 avail_len += scsi_2btoul(td->length) +
9476 avail_len += sizeof(*td);
9482 * avail_len could be zero if we didn't get enough data back from
9483 * thet target to determine
9485 if ((avail_len != 0)
9486 && (avail_len > valid_len)) {
9487 alloc_len = avail_len;
9491 *fill_len = valid_len;
9503 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9504 int req_sa, uint8_t *buf, uint32_t valid_len)
9506 struct scsi_report_supported_opcodes_one *one;
9507 struct scsi_report_supported_opcodes_timeout *td;
9508 uint32_t cdb_len = 0, td_len = 0;
9509 const char *op_desc = NULL;
9513 one = (struct scsi_report_supported_opcodes_one *)buf;
9516 * If we don't have the full single opcode descriptor, no point in
9519 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9521 warnx("Only %u bytes returned, not enough to verify support",
9527 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9529 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9532 printf(", SA 0x%x", req_sa);
9535 switch (one->support & RSO_ONE_SUP_MASK) {
9536 case RSO_ONE_SUP_UNAVAIL:
9537 printf("No command support information currently available\n");
9539 case RSO_ONE_SUP_NOT_SUP:
9540 printf("Command not supported\n");
9543 break; /*NOTREACHED*/
9544 case RSO_ONE_SUP_AVAIL:
9545 printf("Command is supported, complies with a SCSI standard\n");
9547 case RSO_ONE_SUP_VENDOR:
9548 printf("Command is supported, vendor-specific "
9549 "implementation\n");
9552 printf("Unknown command support flags 0x%#x\n",
9553 one->support & RSO_ONE_SUP_MASK);
9558 * If we don't have the CDB length, it isn't exactly an error, the
9559 * command probably isn't supported.
9561 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9565 cdb_len = scsi_2btoul(one->cdb_length);
9568 * If our valid data doesn't include the full reported length,
9569 * return. The caller should have detected this and adjusted his
9570 * allocation length to get all of the available data.
9572 if (valid_len < sizeof(*one) + cdb_len) {
9578 * If all we have is the opcode, there is no point in printing out
9586 printf("CDB usage bitmap:");
9587 for (i = 0; i < cdb_len; i++) {
9588 printf(" %02x", one->cdb_usage[i]);
9593 * If we don't have a timeout descriptor, we're done.
9595 if ((one->support & RSO_ONE_CTDP) == 0)
9599 * If we don't have enough valid length to include the timeout
9600 * descriptor length, we're done.
9602 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9605 td = (struct scsi_report_supported_opcodes_timeout *)
9606 &buf[sizeof(*one) + cdb_len];
9607 td_len = scsi_2btoul(td->length);
9608 td_len += sizeof(td->length);
9611 * If we don't have the full timeout descriptor, we're done.
9613 if (td_len < sizeof(*td))
9617 * If we don't have enough valid length to contain the full timeout
9618 * descriptor, we're done.
9620 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9623 printf("Timeout information:\n");
9624 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9625 printf("Nominal timeout: %u seconds\n",
9626 scsi_4btoul(td->nominal_time));
9627 printf("Recommended timeout: %u seconds\n",
9628 scsi_4btoul(td->recommended_time));
9635 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9638 struct scsi_report_supported_opcodes_all *hdr;
9639 struct scsi_report_supported_opcodes_descr *desc;
9640 uint32_t avail_len = 0, used_len = 0;
9644 if (valid_len < sizeof(*hdr)) {
9645 warnx("%s: not enough returned data (%u bytes) opcode list",
9646 __func__, valid_len);
9650 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9651 avail_len = scsi_4btoul(hdr->length);
9652 avail_len += sizeof(hdr->length);
9654 * Take the lesser of the amount of data the drive claims is
9655 * available, and the amount of data the HBA says was returned.
9657 avail_len = MIN(avail_len, valid_len);
9659 used_len = sizeof(hdr->length);
9661 printf("%-6s %4s %8s ",
9662 "Opcode", "SA", "CDB len" );
9665 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9666 printf(" Description\n");
9668 while ((avail_len - used_len) > sizeof(*desc)) {
9669 struct scsi_report_supported_opcodes_timeout *td;
9671 const char *op_desc = NULL;
9673 cur_ptr = &buf[used_len];
9674 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9676 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9677 if (op_desc == NULL)
9678 op_desc = "UNKNOWN";
9680 printf("0x%02x %#4x %8u ", desc->opcode,
9681 scsi_2btoul(desc->service_action),
9682 scsi_2btoul(desc->cdb_length));
9684 used_len += sizeof(*desc);
9686 if ((desc->flags & RSO_CTDP) == 0) {
9687 printf(" %s\n", op_desc);
9692 * If we don't have enough space to fit a timeout
9693 * descriptor, then we're done.
9695 if (avail_len - used_len < sizeof(*td)) {
9696 used_len = avail_len;
9697 printf(" %s\n", op_desc);
9700 cur_ptr = &buf[used_len];
9701 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9702 td_len = scsi_2btoul(td->length);
9703 td_len += sizeof(td->length);
9707 * If the given timeout descriptor length is less than what
9708 * we understand, skip it.
9710 if (td_len < sizeof(*td)) {
9711 printf(" %s\n", op_desc);
9715 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9716 scsi_4btoul(td->nominal_time),
9717 scsi_4btoul(td->recommended_time), op_desc);
9724 scsiopcodes(struct cam_device *device, int argc, char **argv,
9725 char *combinedopt, int task_attr, int retry_count, int timeout,
9729 uint32_t opcode = 0, service_action = 0;
9730 int td_set = 0, opcode_set = 0, sa_set = 0;
9731 int show_sa_errors = 1;
9732 uint32_t valid_len = 0;
9733 uint8_t *buf = NULL;
9737 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9743 opcode = strtoul(optarg, &endptr, 0);
9744 if (*endptr != '\0') {
9745 warnx("Invalid opcode \"%s\", must be a number",
9750 if (opcode > 0xff) {
9751 warnx("Invalid opcode 0x%#x, must be between"
9752 "0 and 0xff inclusive", opcode);
9759 service_action = strtoul(optarg, &endptr, 0);
9760 if (*endptr != '\0') {
9761 warnx("Invalid service action \"%s\", must "
9762 "be a number", optarg);
9766 if (service_action > 0xffff) {
9767 warnx("Invalid service action 0x%#x, must "
9768 "be between 0 and 0xffff inclusive",
9783 && (opcode_set == 0)) {
9784 warnx("You must specify an opcode with -o if a service "
9789 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9790 sa_set, service_action, td_set, task_attr,
9791 retry_count, timeout, verbosemode, &valid_len,
9796 if ((opcode_set != 0)
9798 retval = scsiprintoneopcode(device, opcode, sa_set,
9799 service_action, buf, valid_len);
9801 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9812 reprobe(struct cam_device *device)
9817 ccb = cam_getccb(device);
9820 warnx("%s: error allocating ccb", __func__);
9824 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
9826 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9828 if (cam_send_ccb(device, ccb) < 0) {
9829 warn("error sending XPT_REPROBE_LUN CCB");
9834 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9835 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9847 usage(int printlong)
9850 fprintf(printlong ? stdout : stderr,
9851 "usage: camcontrol <command> [device id][generic args][command args]\n"
9852 " camcontrol devlist [-b] [-v]\n"
9853 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9854 " camcontrol tur [dev_id][generic args]\n"
9855 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9856 " camcontrol identify [dev_id][generic args] [-v]\n"
9857 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9858 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9860 " camcontrol start [dev_id][generic args]\n"
9861 " camcontrol stop [dev_id][generic args]\n"
9862 " camcontrol load [dev_id][generic args]\n"
9863 " camcontrol eject [dev_id][generic args]\n"
9864 " camcontrol reprobe [dev_id][generic args]\n"
9865 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9866 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9867 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9868 " [-q][-s][-S offset][-X]\n"
9869 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9870 " [-P pagectl][-e | -b][-d]\n"
9871 " camcontrol cmd [dev_id][generic args]\n"
9872 " <-a cmd [args] | -c cmd [args]>\n"
9873 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9874 " camcontrol smpcmd [dev_id][generic args]\n"
9875 " <-r len fmt [args]> <-R len fmt [args]>\n"
9876 " camcontrol smprg [dev_id][generic args][-l]\n"
9877 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9878 " [-o operation][-d name][-m rate][-M rate]\n"
9879 " [-T pp_timeout][-a enable|disable]\n"
9880 " [-A enable|disable][-s enable|disable]\n"
9881 " [-S enable|disable]\n"
9882 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9883 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9884 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9885 " <all|dev_id|bus[:target[:lun]]|off>\n"
9886 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9887 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9888 " [-D <enable|disable>][-M mode][-O offset]\n"
9889 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9890 " [-U][-W bus_width]\n"
9891 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9892 " camcontrol sanitize [dev_id][generic args]\n"
9893 " [-a overwrite|block|crypto|exitfailure]\n"
9894 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9896 " camcontrol idle [dev_id][generic args][-t time]\n"
9897 " camcontrol standby [dev_id][generic args][-t time]\n"
9898 " camcontrol sleep [dev_id][generic args]\n"
9899 " camcontrol powermode [dev_id][generic args]\n"
9900 " camcontrol apm [dev_id][generic args][-l level]\n"
9901 " camcontrol aam [dev_id][generic args][-l level]\n"
9902 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9904 " camcontrol security [dev_id][generic args]\n"
9905 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9906 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9907 " [-U <user|master>] [-y]\n"
9908 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9909 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9910 " camcontrol ama [dev_id][generic args] [-f] [-q] [-s max_sectors]\n"
9911 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9912 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9913 " [-s scope][-S][-T type][-U]\n"
9914 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9915 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9916 " [-p part][-s start][-T type][-V vol]\n"
9917 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9919 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9920 " [-o rep_opts] [-P print_opts]\n"
9921 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9922 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9923 " [-S power_src] [-T timer]\n"
9924 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9925 " <-s <-f format -T time | -U >>\n"
9926 " camcontrol devtype [dev_id]\n"
9928 " camcontrol help\n");
9932 "Specify one of the following options:\n"
9933 "devlist list all CAM devices\n"
9934 "periphlist list all CAM peripheral drivers attached to a device\n"
9935 "tur send a test unit ready to the named device\n"
9936 "inquiry send a SCSI inquiry command to the named device\n"
9937 "identify send a ATA identify command to the named device\n"
9938 "reportluns send a SCSI report luns command to the device\n"
9939 "readcap send a SCSI read capacity command to the device\n"
9940 "start send a Start Unit command to the device\n"
9941 "stop send a Stop Unit command to the device\n"
9942 "load send a Start Unit command to the device with the load bit set\n"
9943 "eject send a Stop Unit command to the device with the eject bit set\n"
9944 "reprobe update capacity information of the given device\n"
9945 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9946 "reset reset all buses, the given bus, bus:target:lun or device\n"
9947 "defects read the defect list of the specified device\n"
9948 "modepage display or edit (-e) the given mode page\n"
9949 "cmd send the given SCSI command, may need -i or -o as well\n"
9950 "smpcmd send the given SMP command, requires -o and -i\n"
9951 "smprg send the SMP Report General command\n"
9952 "smppc send the SMP PHY Control command, requires -p\n"
9953 "smpphylist display phys attached to a SAS expander\n"
9954 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9955 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9956 "tags report or set the number of transaction slots for a device\n"
9957 "negotiate report or set device negotiation parameters\n"
9958 "format send the SCSI FORMAT UNIT command to the named device\n"
9959 "sanitize send the SCSI SANITIZE command to the named device\n"
9960 "idle send the ATA IDLE command to the named device\n"
9961 "standby send the ATA STANDBY command to the named device\n"
9962 "sleep send the ATA SLEEP command to the named device\n"
9963 "powermode send the ATA CHECK POWER MODE command to the named device\n"
9964 "fwdownload program firmware of the named device with the given image\n"
9965 "security report or send ATA security commands to the named device\n"
9966 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9967 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9968 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9969 "zone manage Zoned Block (Shingled) devices\n"
9970 "epc send ATA Extended Power Conditions commands\n"
9971 "timestamp report or set the device's timestamp\n"
9972 "devtype report the type of device\n"
9973 "help this message\n"
9974 "Device Identifiers:\n"
9975 "bus:target specify the bus and target, lun defaults to 0\n"
9976 "bus:target:lun specify the bus, target and lun\n"
9977 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
9978 "Generic arguments:\n"
9979 "-v be verbose, print out sense information\n"
9980 "-t timeout command timeout in seconds, overrides default timeout\n"
9981 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
9982 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
9983 "-E have the kernel attempt to perform SCSI error recovery\n"
9984 "-C count specify the SCSI command retry count (needs -E to work)\n"
9985 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
9986 "modepage arguments:\n"
9987 "-l list all available mode pages\n"
9988 "-m page specify the mode page to view or edit\n"
9989 "-e edit the specified mode page\n"
9990 "-b force view to binary mode\n"
9991 "-d disable block descriptors for mode sense\n"
9992 "-P pgctl page control field 0-3\n"
9993 "defects arguments:\n"
9994 "-f format specify defect list format (block, bfi or phys)\n"
9995 "-G get the grown defect list\n"
9996 "-P get the permanent defect list\n"
9997 "inquiry arguments:\n"
9998 "-D get the standard inquiry data\n"
9999 "-S get the serial number\n"
10000 "-R get the transfer rate, etc.\n"
10001 "reportluns arguments:\n"
10002 "-c only report a count of available LUNs\n"
10003 "-l only print out luns, and not a count\n"
10004 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
10005 "readcap arguments\n"
10006 "-b only report the blocksize\n"
10007 "-h human readable device size, base 2\n"
10008 "-H human readable device size, base 10\n"
10009 "-N print the number of blocks instead of last block\n"
10010 "-q quiet, print numbers only\n"
10011 "-s only report the last block/device size\n"
10013 "-c cdb [args] specify the SCSI CDB\n"
10014 "-i len fmt specify input data and input data format\n"
10015 "-o len fmt [args] specify output data and output data fmt\n"
10016 "smpcmd arguments:\n"
10017 "-r len fmt [args] specify the SMP command to be sent\n"
10018 "-R len fmt [args] specify SMP response format\n"
10019 "smprg arguments:\n"
10020 "-l specify the long response format\n"
10021 "smppc arguments:\n"
10022 "-p phy specify the PHY to operate on\n"
10023 "-l specify the long request/response format\n"
10024 "-o operation specify the phy control operation\n"
10025 "-d name set the attached device name\n"
10026 "-m rate set the minimum physical link rate\n"
10027 "-M rate set the maximum physical link rate\n"
10028 "-T pp_timeout set the partial pathway timeout value\n"
10029 "-a enable|disable enable or disable SATA slumber\n"
10030 "-A enable|disable enable or disable SATA partial phy power\n"
10031 "-s enable|disable enable or disable SAS slumber\n"
10032 "-S enable|disable enable or disable SAS partial phy power\n"
10033 "smpphylist arguments:\n"
10034 "-l specify the long response format\n"
10035 "-q only print phys with attached devices\n"
10036 "smpmaninfo arguments:\n"
10037 "-l specify the long response format\n"
10038 "debug arguments:\n"
10039 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
10040 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
10041 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
10042 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
10043 "tags arguments:\n"
10044 "-N tags specify the number of tags to use for this device\n"
10045 "-q be quiet, don't report the number of tags\n"
10046 "-v report a number of tag-related parameters\n"
10047 "negotiate arguments:\n"
10048 "-a send a test unit ready after negotiation\n"
10049 "-c report/set current negotiation settings\n"
10050 "-D <arg> \"enable\" or \"disable\" disconnection\n"
10051 "-M mode set ATA mode\n"
10052 "-O offset set command delay offset\n"
10053 "-q be quiet, don't report anything\n"
10054 "-R syncrate synchronization rate in MHz\n"
10055 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
10056 "-U report/set user negotiation settings\n"
10057 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
10058 "-v also print a Path Inquiry CCB for the controller\n"
10059 "format arguments:\n"
10060 "-q be quiet, don't print status messages\n"
10061 "-r run in report only mode\n"
10062 "-w don't send immediate format command\n"
10063 "-y don't ask any questions\n"
10064 "sanitize arguments:\n"
10065 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
10066 "-c passes overwrite passes to perform (1 to 31)\n"
10067 "-I invert overwrite pattern after each pass\n"
10068 "-P pattern path to overwrite pattern file\n"
10069 "-q be quiet, don't print status messages\n"
10070 "-r run in report only mode\n"
10071 "-U run operation in unrestricted completion exit mode\n"
10072 "-w don't send immediate sanitize command\n"
10073 "-y don't ask any questions\n"
10074 "idle/standby arguments:\n"
10075 "-t <arg> number of seconds before respective state.\n"
10076 "fwdownload arguments:\n"
10077 "-f fw_image path to firmware image file\n"
10078 "-q don't print informational messages, only errors\n"
10079 "-s run in simulation mode\n"
10080 "-v print info for every firmware segment sent to device\n"
10081 "-y don't ask any questions\n"
10082 "security arguments:\n"
10083 "-d pwd disable security using the given password for the selected\n"
10085 "-e pwd erase the device using the given pwd for the selected user\n"
10086 "-f freeze the security configuration of the specified device\n"
10087 "-h pwd enhanced erase the device using the given pwd for the\n"
10089 "-k pwd unlock the device using the given pwd for the selected\n"
10091 "-l <high|maximum> specifies which security level to set: high or maximum\n"
10092 "-q be quiet, do not print any status messages\n"
10093 "-s pwd password the device (enable security) using the given\n"
10094 " pwd for the selected user\n"
10095 "-T timeout overrides the timeout (seconds) used for erase operation\n"
10096 "-U <user|master> specifies which user to set: user or master\n"
10097 "-y don't ask any questions\n"
10099 "-f freeze the HPA configuration of the device\n"
10100 "-l lock the HPA configuration of the device\n"
10101 "-P make the HPA max sectors persist\n"
10102 "-p pwd Set the HPA configuration password required for unlock\n"
10104 "-q be quiet, do not print any status messages\n"
10105 "-s sectors configures the maximum user accessible sectors of the\n"
10107 "-U pwd unlock the HPA configuration of the device\n"
10108 "-y don't ask any questions\n"
10110 "-f freeze the AMA configuration of the device\n"
10111 "-q be quiet, do not print any status messages\n"
10112 "-s sectors configures the maximum user accessible sectors of the\n"
10114 "persist arguments:\n"
10115 "-i action specify read_keys, read_reservation, report_cap, or\n"
10116 " read_full_status\n"
10117 "-o action specify register, register_ignore, reserve, release,\n"
10118 " clear, preempt, preempt_abort, register_move, replace_lost\n"
10119 "-a set the All Target Ports (ALL_TG_PT) bit\n"
10120 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
10121 "-k key specify the Reservation Key\n"
10122 "-K sa_key specify the Service Action Reservation Key\n"
10123 "-p set the Activate Persist Through Power Loss bit\n"
10124 "-R rtp specify the Relative Target Port\n"
10125 "-s scope specify the scope: lun, extent, element or a number\n"
10126 "-S specify Transport ID for register, requires -I\n"
10127 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
10128 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
10129 "-U unregister the current initiator for register_move\n"
10130 "attrib arguments:\n"
10131 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
10133 "-w attr specify an attribute to write, one -w argument per attr\n"
10134 "-a attr_num only display this attribute number\n"
10135 "-c get cached attributes\n"
10136 "-e elem_addr request attributes for the given element in a changer\n"
10137 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
10138 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
10139 " field_none, field_desc, field_num, field_size, field_rw\n"
10140 "-p partition request attributes for the given partition\n"
10141 "-s start_attr request attributes starting at the given number\n"
10142 "-T elem_type specify the element type (used with -e)\n"
10143 "-V logical_vol specify the logical volume ID\n"
10144 "opcodes arguments:\n"
10145 "-o opcode specify the individual opcode to list\n"
10146 "-s service_action specify the service action for the opcode\n"
10147 "-N do not return SCSI error for unsupported SA\n"
10148 "-T request nominal and recommended timeout values\n"
10149 "zone arguments:\n"
10150 "-c cmd required: rz, open, close, finish, or rwp\n"
10151 "-a apply the action to all zones\n"
10152 "-l LBA specify the zone starting LBA\n"
10153 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
10154 " closed, full, ro, offline, reset, nonseq, nonwp\n"
10155 "-P print_opt report zones printing: normal, summary, script\n"
10157 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
10158 " source, status, list\n"
10159 "-d disable power mode (timer, state)\n"
10160 "-D delayed entry (goto)\n"
10161 "-e enable power mode (timer, state)\n"
10162 "-H hold power mode (goto)\n"
10163 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
10165 "-P only display power mode (status)\n"
10166 "-r rst_src restore settings from: default, saved (restore)\n"
10167 "-s save mode (timer, state, restore)\n"
10168 "-S power_src set power source: battery, nonbattery (source)\n"
10169 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
10170 "timestamp arguments:\n"
10171 "-r report the timestamp of the device\n"
10172 "-f format report the timestamp of the device with the given\n"
10173 " strftime(3) format string\n"
10174 "-m report the timestamp of the device as milliseconds since\n"
10175 " January 1st, 1970\n"
10176 "-U report the time with UTC instead of the local time zone\n"
10177 "-s set the timestamp of the device\n"
10178 "-f format the format of the time string passed into strptime(3)\n"
10179 "-T time the time value passed into strptime(3)\n"
10180 "-U set the timestamp of the device to UTC time\n"
10185 main(int argc, char **argv)
10188 char *device = NULL;
10190 struct cam_device *cam_dev = NULL;
10191 int timeout = 0, retry_count = 1;
10192 camcontrol_optret optreturn;
10194 const char *mainopt = "C:En:Q:t:u:v";
10195 const char *subopt = NULL;
10196 char combinedopt[256];
10197 int error = 0, optstart = 2;
10198 int task_attr = MSG_SIMPLE_Q_TAG;
10201 target_id_t target;
10204 cmdlist = CAM_CMD_NONE;
10205 arglist = CAM_ARG_NONE;
10213 * Get the base option.
10215 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
10217 if (optreturn == CC_OR_AMBIGUOUS) {
10218 warnx("ambiguous option %s", argv[1]);
10221 } else if (optreturn == CC_OR_NOT_FOUND) {
10222 warnx("option %s not found", argv[1]);
10228 * Ahh, getopt(3) is a pain.
10230 * This is a gross hack. There really aren't many other good
10231 * options (excuse the pun) for parsing options in a situation like
10232 * this. getopt is kinda braindead, so you end up having to run
10233 * through the options twice, and give each invocation of getopt
10234 * the option string for the other invocation.
10236 * You would think that you could just have two groups of options.
10237 * The first group would get parsed by the first invocation of
10238 * getopt, and the second group would get parsed by the second
10239 * invocation of getopt. It doesn't quite work out that way. When
10240 * the first invocation of getopt finishes, it leaves optind pointing
10241 * to the argument _after_ the first argument in the second group.
10242 * So when the second invocation of getopt comes around, it doesn't
10243 * recognize the first argument it gets and then bails out.
10245 * A nice alternative would be to have a flag for getopt that says
10246 * "just keep parsing arguments even when you encounter an unknown
10247 * argument", but there isn't one. So there's no real clean way to
10248 * easily parse two sets of arguments without having one invocation
10249 * of getopt know about the other.
10251 * Without this hack, the first invocation of getopt would work as
10252 * long as the generic arguments are first, but the second invocation
10253 * (in the subfunction) would fail in one of two ways. In the case
10254 * where you don't set optreset, it would fail because optind may be
10255 * pointing to the argument after the one it should be pointing at.
10256 * In the case where you do set optreset, and reset optind, it would
10257 * fail because getopt would run into the first set of options, which
10258 * it doesn't understand.
10260 * All of this would "sort of" work if you could somehow figure out
10261 * whether optind had been incremented one option too far. The
10262 * mechanics of that, however, are more daunting than just giving
10263 * both invocations all of the expect options for either invocation.
10265 * Needless to say, I wouldn't mind if someone invented a better
10266 * (non-GPL!) command line parsing interface than getopt. I
10267 * wouldn't mind if someone added more knobs to getopt to make it
10268 * work better. Who knows, I may talk myself into doing it someday,
10269 * if the standards weenies let me. As it is, it just leads to
10270 * hackery like this and causes people to avoid it in some cases.
10272 * KDM, September 8th, 1998
10274 if (subopt != NULL)
10275 sprintf(combinedopt, "%s%s", mainopt, subopt);
10277 sprintf(combinedopt, "%s", mainopt);
10280 * For these options we do not parse optional device arguments and
10281 * we do not open a passthrough device.
10283 if ((cmdlist == CAM_CMD_RESCAN)
10284 || (cmdlist == CAM_CMD_RESET)
10285 || (cmdlist == CAM_CMD_DEVTREE)
10286 || (cmdlist == CAM_CMD_USAGE)
10287 || (cmdlist == CAM_CMD_DEBUG))
10291 && (argc > 2 && argv[2][0] != '-')) {
10295 if (isdigit(argv[2][0])) {
10296 /* device specified as bus:target[:lun] */
10297 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10299 errx(1, "numeric device specification must "
10300 "be either bus:target, or "
10302 /* default to 0 if lun was not specified */
10303 if ((arglist & CAM_ARG_LUN) == 0) {
10305 arglist |= CAM_ARG_LUN;
10309 if (cam_get_device(argv[2], name, sizeof name, &unit)
10311 errx(1, "%s", cam_errbuf);
10312 device = strdup(name);
10313 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10318 * Start getopt processing at argv[2/3], since we've already
10319 * accepted argv[1..2] as the command name, and as a possible
10325 * Now we run through the argument list looking for generic
10326 * options, and ignoring options that possibly belong to
10329 while ((c = getopt(argc, argv, combinedopt))!= -1){
10332 retry_count = strtol(optarg, NULL, 0);
10333 if (retry_count < 0)
10334 errx(1, "retry count %d is < 0",
10336 arglist |= CAM_ARG_RETRIES;
10339 arglist |= CAM_ARG_ERR_RECOVER;
10342 arglist |= CAM_ARG_DEVICE;
10344 while (isspace(*tstr) && (*tstr != '\0'))
10346 device = (char *)strdup(tstr);
10350 int table_entry = 0;
10353 while (isspace(*tstr) && (*tstr != '\0'))
10355 if (isdigit(*tstr)) {
10356 task_attr = strtol(tstr, &endptr, 0);
10357 if (*endptr != '\0') {
10358 errx(1, "Invalid queue option "
10363 scsi_nv_status status;
10365 table_size = sizeof(task_attrs) /
10366 sizeof(task_attrs[0]);
10367 status = scsi_get_nv(task_attrs,
10368 table_size, tstr, &table_entry,
10369 SCSI_NV_FLAG_IG_CASE);
10370 if (status == SCSI_NV_FOUND)
10371 task_attr = task_attrs[
10372 table_entry].value;
10374 errx(1, "%s option %s",
10375 (status == SCSI_NV_AMBIGUOUS)?
10376 "ambiguous" : "invalid",
10383 timeout = strtol(optarg, NULL, 0);
10385 errx(1, "invalid timeout %d", timeout);
10386 /* Convert the timeout from seconds to ms */
10388 arglist |= CAM_ARG_TIMEOUT;
10391 arglist |= CAM_ARG_UNIT;
10392 unit = strtol(optarg, NULL, 0);
10395 arglist |= CAM_ARG_VERBOSE;
10403 * For most commands we'll want to open the passthrough device
10404 * associated with the specified device. In the case of the rescan
10405 * commands, we don't use a passthrough device at all, just the
10406 * transport layer device.
10408 if (devopen == 1) {
10409 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10410 && (((arglist & CAM_ARG_DEVICE) == 0)
10411 || ((arglist & CAM_ARG_UNIT) == 0))) {
10412 errx(1, "subcommand \"%s\" requires a valid device "
10413 "identifier", argv[1]);
10416 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10417 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10418 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10420 errx(1,"%s", cam_errbuf);
10424 * Reset optind to 2, and reset getopt, so these routines can parse
10425 * the arguments again.
10431 case CAM_CMD_DEVLIST:
10432 error = getdevlist(cam_dev);
10435 error = atahpa(cam_dev, retry_count, timeout,
10436 argc, argv, combinedopt);
10439 error = ataama(cam_dev, retry_count, timeout,
10440 argc, argv, combinedopt);
10442 case CAM_CMD_DEVTREE:
10443 error = getdevtree(argc, argv, combinedopt);
10445 case CAM_CMD_DEVTYPE:
10446 error = getdevtype(cam_dev);
10449 error = testunitready(cam_dev, task_attr, retry_count,
10452 case CAM_CMD_INQUIRY:
10453 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10454 task_attr, retry_count, timeout);
10456 case CAM_CMD_IDENTIFY:
10457 error = identify(cam_dev, retry_count, timeout);
10459 case CAM_CMD_STARTSTOP:
10460 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10461 arglist & CAM_ARG_EJECT, task_attr,
10462 retry_count, timeout);
10464 case CAM_CMD_RESCAN:
10465 error = dorescan_or_reset(argc, argv, 1);
10467 case CAM_CMD_RESET:
10468 error = dorescan_or_reset(argc, argv, 0);
10470 case CAM_CMD_READ_DEFECTS:
10471 error = readdefects(cam_dev, argc, argv, combinedopt,
10472 task_attr, retry_count, timeout);
10474 case CAM_CMD_MODE_PAGE:
10475 modepage(cam_dev, argc, argv, combinedopt,
10476 task_attr, retry_count, timeout);
10478 case CAM_CMD_SCSI_CMD:
10479 error = scsicmd(cam_dev, argc, argv, combinedopt,
10480 task_attr, retry_count, timeout);
10482 case CAM_CMD_MMCSD_CMD:
10483 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10484 retry_count, timeout);
10486 case CAM_CMD_SMP_CMD:
10487 error = smpcmd(cam_dev, argc, argv, combinedopt,
10488 retry_count, timeout);
10490 case CAM_CMD_SMP_RG:
10491 error = smpreportgeneral(cam_dev, argc, argv,
10492 combinedopt, retry_count,
10495 case CAM_CMD_SMP_PC:
10496 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10497 retry_count, timeout);
10499 case CAM_CMD_SMP_PHYLIST:
10500 error = smpphylist(cam_dev, argc, argv, combinedopt,
10501 retry_count, timeout);
10503 case CAM_CMD_SMP_MANINFO:
10504 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10505 retry_count, timeout);
10507 case CAM_CMD_DEBUG:
10508 error = camdebug(argc, argv, combinedopt);
10511 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10514 error = ratecontrol(cam_dev, task_attr, retry_count,
10515 timeout, argc, argv, combinedopt);
10517 case CAM_CMD_FORMAT:
10518 error = scsiformat(cam_dev, argc, argv,
10519 combinedopt, task_attr, retry_count,
10522 case CAM_CMD_REPORTLUNS:
10523 error = scsireportluns(cam_dev, argc, argv,
10524 combinedopt, task_attr,
10525 retry_count, timeout);
10527 case CAM_CMD_READCAP:
10528 error = scsireadcapacity(cam_dev, argc, argv,
10529 combinedopt, task_attr,
10530 retry_count, timeout);
10533 case CAM_CMD_STANDBY:
10534 case CAM_CMD_SLEEP:
10535 case CAM_CMD_POWER_MODE:
10536 error = atapm(cam_dev, argc, argv,
10537 combinedopt, retry_count, timeout);
10541 error = ataaxm(cam_dev, argc, argv,
10542 combinedopt, retry_count, timeout);
10544 case CAM_CMD_SECURITY:
10545 error = atasecurity(cam_dev, retry_count, timeout,
10546 argc, argv, combinedopt);
10548 case CAM_CMD_DOWNLOAD_FW:
10549 error = fwdownload(cam_dev, argc, argv, combinedopt,
10550 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10553 case CAM_CMD_SANITIZE:
10554 error = sanitize(cam_dev, argc, argv, combinedopt, task_attr,
10555 retry_count, timeout);
10557 case CAM_CMD_PERSIST:
10558 error = scsipersist(cam_dev, argc, argv, combinedopt,
10559 task_attr, retry_count, timeout,
10560 arglist & CAM_ARG_VERBOSE,
10561 arglist & CAM_ARG_ERR_RECOVER);
10563 case CAM_CMD_ATTRIB:
10564 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10565 task_attr, retry_count, timeout,
10566 arglist & CAM_ARG_VERBOSE,
10567 arglist & CAM_ARG_ERR_RECOVER);
10569 case CAM_CMD_OPCODES:
10570 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10571 task_attr, retry_count, timeout,
10572 arglist & CAM_ARG_VERBOSE);
10574 case CAM_CMD_REPROBE:
10575 error = reprobe(cam_dev);
10578 error = zone(cam_dev, argc, argv, combinedopt,
10579 task_attr, retry_count, timeout,
10580 arglist & CAM_ARG_VERBOSE);
10583 error = epc(cam_dev, argc, argv, combinedopt,
10584 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10586 case CAM_CMD_TIMESTAMP:
10587 error = timestamp(cam_dev, argc, argv, combinedopt,
10588 task_attr, retry_count, timeout,
10589 arglist & CAM_ARG_VERBOSE);
10591 case CAM_CMD_USAGE:
10600 if (cam_dev != NULL)
10601 cam_close_device(cam_dev);