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, "bdelm:P:"},
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 dorescan_or_reset(int argc, char **argv, int rescan);
305 static int rescan_or_reset_bus(path_id_t bus, int rescan);
306 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
307 lun_id_t lun, int scan);
308 static int readdefects(struct cam_device *device, int argc, char **argv,
309 char *combinedopt, int task_attr, int retry_count,
311 static void modepage(struct cam_device *device, int argc, char **argv,
312 char *combinedopt, int task_attr, int retry_count,
314 static int scsicmd(struct cam_device *device, int argc, char **argv,
315 char *combinedopt, int task_attr, int retry_count,
317 static int smpcmd(struct cam_device *device, int argc, char **argv,
318 char *combinedopt, int retry_count, int timeout);
319 static int mmcsdcmd(struct cam_device *device, int argc, char **argv,
320 char *combinedopt, int retry_count, int timeout);
321 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
322 char *combinedopt, int retry_count, int timeout);
323 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
324 char *combinedopt, int retry_count, int timeout);
325 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
326 char *combinedopt, int retry_count, int timeout);
327 static int getdevid(struct cam_devitem *item);
328 static int buildbusdevlist(struct cam_devlist *devlist);
329 static void freebusdevlist(struct cam_devlist *devlist);
330 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
332 static int smpphylist(struct cam_device *device, int argc, char **argv,
333 char *combinedopt, int retry_count, int timeout);
334 static int tagcontrol(struct cam_device *device, int argc, char **argv,
336 static void cts_print(struct cam_device *device,
337 struct ccb_trans_settings *cts);
338 static void cpi_print(struct ccb_pathinq *cpi);
339 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
340 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
341 static int get_print_cts(struct cam_device *device, int user_settings,
342 int quiet, struct ccb_trans_settings *cts);
343 static int ratecontrol(struct cam_device *device, int task_attr,
344 int retry_count, int timeout, int argc, char **argv,
346 static int scsiformat(struct cam_device *device, int argc, char **argv,
347 char *combinedopt, int task_attr, int retry_count,
349 static int scsisanitize(struct cam_device *device, int argc, char **argv,
350 char *combinedopt, int task_attr, int retry_count,
352 static int scsireportluns(struct cam_device *device, int argc, char **argv,
353 char *combinedopt, int task_attr, int retry_count,
355 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
356 char *combinedopt, int task_attr, int retry_count,
358 static int atapm(struct cam_device *device, int argc, char **argv,
359 char *combinedopt, int retry_count, int timeout);
360 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
361 int argc, char **argv, char *combinedopt);
362 static int atahpa(struct cam_device *device, int retry_count, int timeout,
363 int argc, char **argv, char *combinedopt);
364 static int ataama(struct cam_device *device, int retry_count, int timeout,
365 int argc, char **argv, char *combinedopt);
366 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
367 int sa_set, int req_sa, uint8_t *buf,
369 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
371 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
372 char *combinedopt, int task_attr, int retry_count,
373 int timeout, int verbose);
374 static int scsireprobe(struct cam_device *device);
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 perror("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 CAMIOCOMMAND ioctl");
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 CAMIOCOMMAND ioctl");
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 perror("error sending test unit ready");
881 if (arglist & CAM_ARG_VERBOSE) {
882 cam_error_print(device, ccb, CAM_ESF_ALL,
883 CAM_EPF_ALL, stderr);
890 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
892 fprintf(stdout, "Unit is ready\n");
895 fprintf(stdout, "Unit is not ready\n");
898 if (arglist & CAM_ARG_VERBOSE) {
899 cam_error_print(device, ccb, CAM_ESF_ALL,
900 CAM_EPF_ALL, stderr);
910 scsistart(struct cam_device *device, int startstop, int loadeject,
911 int task_attr, int retry_count, int timeout)
916 ccb = cam_getccb(device);
919 * If we're stopping, send an ordered tag so the drive in question
920 * will finish any previously queued writes before stopping. If
921 * the device isn't capable of tagged queueing, or if tagged
922 * queueing is turned off, the tag action is a no-op. We override
923 * the default simple tag, although this also has the effect of
924 * overriding the user's wishes if he wanted to specify a simple
928 && (task_attr == MSG_SIMPLE_Q_TAG))
929 task_attr = MSG_ORDERED_Q_TAG;
931 scsi_start_stop(&ccb->csio,
932 /* retries */ retry_count,
934 /* tag_action */ task_attr,
935 /* start/stop */ startstop,
936 /* load_eject */ loadeject,
938 /* sense_len */ SSD_FULL_SIZE,
939 /* timeout */ timeout ? timeout : 120000);
941 /* Disable freezing the device queue */
942 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
944 if (arglist & CAM_ARG_ERR_RECOVER)
945 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
947 if (cam_send_ccb(device, ccb) < 0) {
948 perror("error sending start unit");
950 if (arglist & CAM_ARG_VERBOSE) {
951 cam_error_print(device, ccb, CAM_ESF_ALL,
952 CAM_EPF_ALL, stderr);
959 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
961 fprintf(stdout, "Unit started successfully");
963 fprintf(stdout,", Media loaded\n");
965 fprintf(stdout,"\n");
967 fprintf(stdout, "Unit stopped successfully");
969 fprintf(stdout, ", Media ejected\n");
971 fprintf(stdout, "\n");
977 "Error received from start unit command\n");
980 "Error received from stop unit command\n");
982 if (arglist & CAM_ARG_VERBOSE) {
983 cam_error_print(device, ccb, CAM_ESF_ALL,
984 CAM_EPF_ALL, stderr);
994 scsidoinquiry(struct cam_device *device, int argc, char **argv,
995 char *combinedopt, int task_attr, int retry_count, int timeout)
1000 while ((c = getopt(argc, argv, combinedopt)) != -1) {
1003 arglist |= CAM_ARG_GET_STDINQ;
1006 arglist |= CAM_ARG_GET_XFERRATE;
1009 arglist |= CAM_ARG_GET_SERIAL;
1017 * If the user didn't specify any inquiry options, he wants all of
1020 if ((arglist & CAM_ARG_INQ_MASK) == 0)
1021 arglist |= CAM_ARG_INQ_MASK;
1023 if (arglist & CAM_ARG_GET_STDINQ)
1024 error = scsiinquiry(device, task_attr, retry_count, timeout);
1029 if (arglist & CAM_ARG_GET_SERIAL)
1030 scsiserial(device, task_attr, retry_count, timeout);
1032 if (arglist & CAM_ARG_GET_XFERRATE)
1033 error = camxferrate(device);
1039 scsiinquiry(struct cam_device *device, int task_attr, int retry_count,
1043 struct scsi_inquiry_data *inq_buf;
1046 ccb = cam_getccb(device);
1049 warnx("couldn't allocate CCB");
1053 /* cam_getccb cleans up the header, caller has to zero the payload */
1054 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1056 inq_buf = (struct scsi_inquiry_data *)malloc(
1057 sizeof(struct scsi_inquiry_data));
1059 if (inq_buf == NULL) {
1061 warnx("can't malloc memory for inquiry\n");
1064 bzero(inq_buf, sizeof(*inq_buf));
1067 * Note that although the size of the inquiry buffer is the full
1068 * 256 bytes specified in the SCSI spec, we only tell the device
1069 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
1070 * two reasons for this:
1072 * - The SCSI spec says that when a length field is only 1 byte,
1073 * a value of 0 will be interpreted as 256. Therefore
1074 * scsi_inquiry() will convert an inq_len (which is passed in as
1075 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
1076 * to 0. Evidently, very few devices meet the spec in that
1077 * regard. Some devices, like many Seagate disks, take the 0 as
1078 * 0, and don't return any data. One Pioneer DVD-R drive
1079 * returns more data than the command asked for.
1081 * So, since there are numerous devices that just don't work
1082 * right with the full inquiry size, we don't send the full size.
1084 * - The second reason not to use the full inquiry data length is
1085 * that we don't need it here. The only reason we issue a
1086 * standard inquiry is to get the vendor name, device name,
1087 * and revision so scsi_print_inquiry() can print them.
1089 * If, at some point in the future, more inquiry data is needed for
1090 * some reason, this code should use a procedure similar to the
1091 * probe code. i.e., issue a short inquiry, and determine from
1092 * the additional length passed back from the device how much
1093 * inquiry data the device supports. Once the amount the device
1094 * supports is determined, issue an inquiry for that amount and no
1099 scsi_inquiry(&ccb->csio,
1100 /* retries */ retry_count,
1102 /* tag_action */ task_attr,
1103 /* inq_buf */ (u_int8_t *)inq_buf,
1104 /* inq_len */ SHORT_INQUIRY_LENGTH,
1107 /* sense_len */ SSD_FULL_SIZE,
1108 /* timeout */ timeout ? timeout : 5000);
1110 /* Disable freezing the device queue */
1111 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1113 if (arglist & CAM_ARG_ERR_RECOVER)
1114 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1116 if (cam_send_ccb(device, ccb) < 0) {
1117 perror("error sending SCSI inquiry");
1119 if (arglist & CAM_ARG_VERBOSE) {
1120 cam_error_print(device, ccb, CAM_ESF_ALL,
1121 CAM_EPF_ALL, stderr);
1128 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1131 if (arglist & CAM_ARG_VERBOSE) {
1132 cam_error_print(device, ccb, CAM_ESF_ALL,
1133 CAM_EPF_ALL, stderr);
1144 fprintf(stdout, "%s%d: ", device->device_name,
1145 device->dev_unit_num);
1146 scsi_print_inquiry(inq_buf);
1154 scsiserial(struct cam_device *device, int task_attr, int retry_count,
1158 struct scsi_vpd_unit_serial_number *serial_buf;
1159 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
1162 ccb = cam_getccb(device);
1165 warnx("couldn't allocate CCB");
1169 /* cam_getccb cleans up the header, caller has to zero the payload */
1170 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1172 serial_buf = (struct scsi_vpd_unit_serial_number *)
1173 malloc(sizeof(*serial_buf));
1175 if (serial_buf == NULL) {
1177 warnx("can't malloc memory for serial number");
1181 scsi_inquiry(&ccb->csio,
1182 /*retries*/ retry_count,
1184 /* tag_action */ task_attr,
1185 /* inq_buf */ (u_int8_t *)serial_buf,
1186 /* inq_len */ sizeof(*serial_buf),
1188 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
1189 /* sense_len */ SSD_FULL_SIZE,
1190 /* timeout */ timeout ? timeout : 5000);
1192 /* Disable freezing the device queue */
1193 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1195 if (arglist & CAM_ARG_ERR_RECOVER)
1196 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1198 if (cam_send_ccb(device, ccb) < 0) {
1199 warn("error getting serial number");
1201 if (arglist & CAM_ARG_VERBOSE) {
1202 cam_error_print(device, ccb, CAM_ESF_ALL,
1203 CAM_EPF_ALL, stderr);
1211 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1214 if (arglist & CAM_ARG_VERBOSE) {
1215 cam_error_print(device, ccb, CAM_ESF_ALL,
1216 CAM_EPF_ALL, stderr);
1227 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1228 serial_num[serial_buf->length] = '\0';
1230 if ((arglist & CAM_ARG_GET_STDINQ)
1231 || (arglist & CAM_ARG_GET_XFERRATE))
1232 fprintf(stdout, "%s%d: Serial Number ",
1233 device->device_name, device->dev_unit_num);
1235 fprintf(stdout, "%.60s\n", serial_num);
1243 camxferrate(struct cam_device *device)
1245 struct ccb_pathinq cpi;
1247 u_int32_t speed = 0;
1252 if ((retval = get_cpi(device, &cpi)) != 0)
1255 ccb = cam_getccb(device);
1258 warnx("couldn't allocate CCB");
1262 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
1264 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1265 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1267 if (((retval = cam_send_ccb(device, ccb)) < 0)
1268 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1269 const char error_string[] = "error getting transfer settings";
1274 warnx(error_string);
1276 if (arglist & CAM_ARG_VERBOSE)
1277 cam_error_print(device, ccb, CAM_ESF_ALL,
1278 CAM_EPF_ALL, stderr);
1282 goto xferrate_bailout;
1286 speed = cpi.base_transfer_speed;
1288 if (ccb->cts.transport == XPORT_SPI) {
1289 struct ccb_trans_settings_spi *spi =
1290 &ccb->cts.xport_specific.spi;
1292 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1293 freq = scsi_calc_syncsrate(spi->sync_period);
1296 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1297 speed *= (0x01 << spi->bus_width);
1299 } else if (ccb->cts.transport == XPORT_FC) {
1300 struct ccb_trans_settings_fc *fc =
1301 &ccb->cts.xport_specific.fc;
1303 if (fc->valid & CTS_FC_VALID_SPEED)
1304 speed = fc->bitrate;
1305 } else if (ccb->cts.transport == XPORT_SAS) {
1306 struct ccb_trans_settings_sas *sas =
1307 &ccb->cts.xport_specific.sas;
1309 if (sas->valid & CTS_SAS_VALID_SPEED)
1310 speed = sas->bitrate;
1311 } else if (ccb->cts.transport == XPORT_ATA) {
1312 struct ccb_trans_settings_pata *pata =
1313 &ccb->cts.xport_specific.ata;
1315 if (pata->valid & CTS_ATA_VALID_MODE)
1316 speed = ata_mode2speed(pata->mode);
1317 } else if (ccb->cts.transport == XPORT_SATA) {
1318 struct ccb_trans_settings_sata *sata =
1319 &ccb->cts.xport_specific.sata;
1321 if (sata->valid & CTS_SATA_VALID_REVISION)
1322 speed = ata_revision2speed(sata->revision);
1327 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1328 device->device_name, device->dev_unit_num,
1331 fprintf(stdout, "%s%d: %dKB/s transfers",
1332 device->device_name, device->dev_unit_num,
1336 if (ccb->cts.transport == XPORT_SPI) {
1337 struct ccb_trans_settings_spi *spi =
1338 &ccb->cts.xport_specific.spi;
1340 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1341 && (spi->sync_offset != 0))
1342 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1343 freq % 1000, spi->sync_offset);
1345 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1346 && (spi->bus_width > 0)) {
1347 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1348 && (spi->sync_offset != 0)) {
1349 fprintf(stdout, ", ");
1351 fprintf(stdout, " (");
1353 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1354 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1355 && (spi->sync_offset != 0)) {
1356 fprintf(stdout, ")");
1358 } else if (ccb->cts.transport == XPORT_ATA) {
1359 struct ccb_trans_settings_pata *pata =
1360 &ccb->cts.xport_specific.ata;
1363 if (pata->valid & CTS_ATA_VALID_MODE)
1364 printf("%s, ", ata_mode2string(pata->mode));
1365 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1366 printf("ATAPI %dbytes, ", pata->atapi);
1367 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1368 printf("PIO %dbytes", pata->bytecount);
1370 } else if (ccb->cts.transport == XPORT_SATA) {
1371 struct ccb_trans_settings_sata *sata =
1372 &ccb->cts.xport_specific.sata;
1375 if (sata->valid & CTS_SATA_VALID_REVISION)
1376 printf("SATA %d.x, ", sata->revision);
1379 if (sata->valid & CTS_SATA_VALID_MODE)
1380 printf("%s, ", ata_mode2string(sata->mode));
1381 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1382 printf("ATAPI %dbytes, ", sata->atapi);
1383 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1384 printf("PIO %dbytes", sata->bytecount);
1388 if (ccb->cts.protocol == PROTO_SCSI) {
1389 struct ccb_trans_settings_scsi *scsi =
1390 &ccb->cts.proto_specific.scsi;
1391 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1392 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1393 fprintf(stdout, ", Command Queueing Enabled");
1398 fprintf(stdout, "\n");
1408 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1410 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1411 ((u_int32_t)parm->lba_size_2 << 16);
1413 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1414 ((u_int64_t)parm->lba_size48_2 << 16) |
1415 ((u_int64_t)parm->lba_size48_3 << 32) |
1416 ((u_int64_t)parm->lba_size48_4 << 48);
1420 "Support Enabled Value\n");
1423 printf("Host Protected Area (HPA) ");
1424 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1425 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1426 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1429 printf("HPA - Security ");
1430 if (parm->support.command2 & ATA_SUPPORT_MAXSECURITY)
1431 printf("yes %s\n", (parm->enabled.command2 &
1432 ATA_SUPPORT_MAXSECURITY) ? "yes" : "no ");
1441 ataama_print(struct ata_params *parm, u_int64_t nativesize, int header)
1443 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1444 ((u_int32_t)parm->lba_size_2 << 16);
1446 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1447 ((u_int64_t)parm->lba_size48_2 << 16) |
1448 ((u_int64_t)parm->lba_size48_3 << 32) |
1449 ((u_int64_t)parm->lba_size48_4 << 48);
1453 "Support Enabled Value\n");
1456 printf("Accessible Max Address Config ");
1457 if (parm->support2 & ATA_SUPPORT_AMAX_ADDR) {
1458 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1459 printf("yes %s %ju/%ju\n",
1460 (nativesize > lba) ? "yes" : "no ", lba, nativesize);
1467 atasata(struct ata_params *parm)
1471 if (parm->satacapabilities != 0xffff &&
1472 parm->satacapabilities != 0x0000)
1479 atacapprint(struct ata_params *parm)
1481 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1482 ((u_int32_t)parm->lba_size_2 << 16);
1484 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1485 ((u_int64_t)parm->lba_size48_2 << 16) |
1486 ((u_int64_t)parm->lba_size48_3 << 32) |
1487 ((u_int64_t)parm->lba_size48_4 << 48);
1490 printf("protocol ");
1491 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1492 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1493 if (parm->satacapabilities & ATA_SATA_GEN3)
1494 printf(" SATA 3.x\n");
1495 else if (parm->satacapabilities & ATA_SATA_GEN2)
1496 printf(" SATA 2.x\n");
1497 else if (parm->satacapabilities & ATA_SATA_GEN1)
1498 printf(" SATA 1.x\n");
1504 printf("device model %.40s\n", parm->model);
1505 printf("firmware revision %.8s\n", parm->revision);
1506 printf("serial number %.20s\n", parm->serial);
1507 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1508 printf("WWN %04x%04x%04x%04x\n",
1509 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1511 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1512 printf("media serial number %.30s\n",
1513 parm->media_serial);
1516 printf("cylinders %d\n", parm->cylinders);
1517 printf("heads %d\n", parm->heads);
1518 printf("sectors/track %d\n", parm->sectors);
1519 printf("sector size logical %u, physical %lu, offset %lu\n",
1520 ata_logical_sector_size(parm),
1521 (unsigned long)ata_physical_sector_size(parm),
1522 (unsigned long)ata_logical_sector_offset(parm));
1524 if (parm->config == ATA_PROTO_CFA ||
1525 (parm->support.command2 & ATA_SUPPORT_CFA))
1526 printf("CFA supported\n");
1528 printf("LBA%ssupported ",
1529 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1531 printf("%d sectors\n", lbasize);
1535 printf("LBA48%ssupported ",
1536 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1538 printf("%ju sectors\n", (uintmax_t)lbasize48);
1542 printf("PIO supported PIO");
1543 switch (ata_max_pmode(parm)) {
1559 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1560 printf(" w/o IORDY");
1563 printf("DMA%ssupported ",
1564 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1565 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1566 if (parm->mwdmamodes & 0xff) {
1568 if (parm->mwdmamodes & 0x04)
1570 else if (parm->mwdmamodes & 0x02)
1572 else if (parm->mwdmamodes & 0x01)
1576 if ((parm->atavalid & ATA_FLAG_88) &&
1577 (parm->udmamodes & 0xff)) {
1579 if (parm->udmamodes & 0x40)
1581 else if (parm->udmamodes & 0x20)
1583 else if (parm->udmamodes & 0x10)
1585 else if (parm->udmamodes & 0x08)
1587 else if (parm->udmamodes & 0x04)
1589 else if (parm->udmamodes & 0x02)
1591 else if (parm->udmamodes & 0x01)
1598 if (parm->media_rotation_rate == 1) {
1599 printf("media RPM non-rotating\n");
1600 } else if (parm->media_rotation_rate >= 0x0401 &&
1601 parm->media_rotation_rate <= 0xFFFE) {
1602 printf("media RPM %d\n",
1603 parm->media_rotation_rate);
1606 printf("Zoned-Device Commands ");
1607 switch (parm->support3 & ATA_SUPPORT_ZONE_MASK) {
1608 case ATA_SUPPORT_ZONE_DEV_MANAGED:
1609 printf("device managed\n");
1611 case ATA_SUPPORT_ZONE_HOST_AWARE:
1612 printf("host aware\n");
1619 "Support Enabled Value Vendor\n");
1620 printf("read ahead %s %s\n",
1621 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1622 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1623 printf("write cache %s %s\n",
1624 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1625 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1626 printf("flush cache %s %s\n",
1627 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1628 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1629 printf("overlap %s\n",
1630 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1631 printf("Tagged Command Queuing (TCQ) %s %s",
1632 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1633 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1634 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1635 printf(" %d tags\n",
1636 ATA_QUEUE_LEN(parm->queue) + 1);
1639 printf("Native Command Queuing (NCQ) ");
1640 if (parm->satacapabilities != 0xffff &&
1641 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1642 printf("yes %d tags\n",
1643 ATA_QUEUE_LEN(parm->queue) + 1);
1647 printf("NCQ Queue Management %s\n", atasata(parm) &&
1648 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1650 printf("NCQ Streaming %s\n", atasata(parm) &&
1651 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1653 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1654 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1657 printf("SMART %s %s\n",
1658 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1659 parm->enabled.command1 & ATA_SUPPORT_SMART ? "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("security %s %s\n",
1664 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1665 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1666 printf("power management %s %s\n",
1667 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1668 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1669 printf("advanced power management %s %s",
1670 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1671 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1672 if (parm->support.command2 & ATA_SUPPORT_APM) {
1673 printf(" %d/0x%02X\n",
1674 parm->apm_value & 0xff, parm->apm_value & 0xff);
1677 printf("automatic acoustic management %s %s",
1678 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1679 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1680 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1681 printf(" %d/0x%02X %d/0x%02X\n",
1682 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1683 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1684 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1685 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1688 printf("media status notification %s %s\n",
1689 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1690 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1691 printf("power-up in Standby %s %s\n",
1692 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1693 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1694 printf("write-read-verify %s %s",
1695 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1696 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1697 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1698 printf(" %d/0x%x\n",
1699 parm->wrv_mode, parm->wrv_mode);
1702 printf("unload %s %s\n",
1703 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1704 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1705 printf("general purpose logging %s %s\n",
1706 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1707 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1708 printf("free-fall %s %s\n",
1709 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1710 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1711 printf("Data Set Management (DSM/TRIM) ");
1712 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1714 printf("DSM - max 512byte blocks ");
1715 if (parm->max_dsm_blocks == 0x00)
1716 printf("yes not specified\n");
1719 parm->max_dsm_blocks);
1721 printf("DSM - deterministic read ");
1722 if (parm->support3 & ATA_SUPPORT_DRAT) {
1723 if (parm->support3 & ATA_SUPPORT_RZAT)
1724 printf("yes zeroed\n");
1726 printf("yes any value\n");
1736 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1738 struct ata_pass_16 *ata_pass_16;
1739 struct ata_cmd ata_cmd;
1741 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1742 ata_cmd.command = ata_pass_16->command;
1743 ata_cmd.control = ata_pass_16->control;
1744 ata_cmd.features = ata_pass_16->features;
1746 if (arglist & CAM_ARG_VERBOSE) {
1747 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1748 ata_op_string(&ata_cmd),
1749 ccb->csio.ccb_h.timeout);
1752 /* Disable freezing the device queue */
1753 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1755 if (arglist & CAM_ARG_ERR_RECOVER)
1756 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1758 if (cam_send_ccb(device, ccb) < 0) {
1759 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1760 warn("error sending ATA %s via pass_16",
1761 ata_op_string(&ata_cmd));
1764 if (arglist & CAM_ARG_VERBOSE) {
1765 cam_error_print(device, ccb, CAM_ESF_ALL,
1766 CAM_EPF_ALL, stderr);
1772 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1773 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1774 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1775 warnx("ATA %s via pass_16 failed",
1776 ata_op_string(&ata_cmd));
1778 if (arglist & CAM_ARG_VERBOSE) {
1779 cam_error_print(device, ccb, CAM_ESF_ALL,
1780 CAM_EPF_ALL, stderr);
1791 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1793 if (arglist & CAM_ARG_VERBOSE) {
1794 warnx("sending ATA %s with timeout of %u msecs",
1795 ata_op_string(&(ccb->ataio.cmd)),
1796 ccb->ataio.ccb_h.timeout);
1799 /* Disable freezing the device queue */
1800 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1802 if (arglist & CAM_ARG_ERR_RECOVER)
1803 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1805 if (cam_send_ccb(device, ccb) < 0) {
1806 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1807 warn("error sending ATA %s",
1808 ata_op_string(&(ccb->ataio.cmd)));
1811 if (arglist & CAM_ARG_VERBOSE) {
1812 cam_error_print(device, ccb, CAM_ESF_ALL,
1813 CAM_EPF_ALL, stderr);
1819 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1820 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1821 warnx("ATA %s failed: %d",
1822 ata_op_string(&(ccb->ataio.cmd)), quiet);
1825 if (arglist & CAM_ARG_VERBOSE) {
1826 cam_error_print(device, ccb, CAM_ESF_ALL,
1827 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_int8_t features,
1840 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1841 u_int16_t dxfer_len, int timeout, int quiet)
1843 if (data_ptr != NULL) {
1844 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1845 AP_FLAG_TLEN_SECT_CNT;
1846 if (flags & CAM_DIR_OUT)
1847 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1849 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1851 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1854 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1856 scsi_ata_pass_16(&ccb->csio,
1870 /*sense_len*/SSD_FULL_SIZE,
1873 return scsi_cam_pass_16_send(device, ccb, quiet);
1877 ata_try_pass_16(struct cam_device *device)
1879 struct ccb_pathinq cpi;
1881 if (get_cpi(device, &cpi) != 0) {
1882 warnx("couldn't get CPI");
1886 if (cpi.protocol == PROTO_SCSI) {
1887 /* possibly compatible with pass_16 */
1891 /* likely not compatible with pass_16 */
1896 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1897 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1898 u_int8_t command, u_int8_t features, u_int32_t lba,
1899 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1900 int timeout, int quiet)
1904 switch (ata_try_pass_16(device)) {
1908 /* Try using SCSI Passthrough */
1909 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1910 0, tag_action, command, features, lba,
1911 sector_count, data_ptr, dxfer_len,
1915 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1916 cam_fill_ataio(&ccb->ataio,
1925 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1926 return ata_cam_send(device, ccb, quiet);
1930 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1931 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1932 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1933 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1934 u_int16_t dxfer_len, int timeout, int force48bit)
1938 retval = ata_try_pass_16(device);
1945 /* Try using SCSI Passthrough */
1946 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1947 ata_flags, tag_action, command, features,
1948 lba, sector_count, data_ptr, dxfer_len,
1951 if (ata_flags & AP_FLAG_CHK_COND) {
1952 /* Decode ata_res from sense data */
1953 struct ata_res_pass16 *res_pass16;
1954 struct ata_res *res;
1958 /* sense_data is 4 byte aligned */
1959 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1960 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1961 ptr[i] = le16toh(ptr[i]);
1963 /* sense_data is 4 byte aligned */
1964 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1965 &ccb->csio.sense_data;
1966 res = &ccb->ataio.res;
1967 res->flags = res_pass16->flags;
1968 res->status = res_pass16->status;
1969 res->error = res_pass16->error;
1970 res->lba_low = res_pass16->lba_low;
1971 res->lba_mid = res_pass16->lba_mid;
1972 res->lba_high = res_pass16->lba_high;
1973 res->device = res_pass16->device;
1974 res->lba_low_exp = res_pass16->lba_low_exp;
1975 res->lba_mid_exp = res_pass16->lba_mid_exp;
1976 res->lba_high_exp = res_pass16->lba_high_exp;
1977 res->sector_count = res_pass16->sector_count;
1978 res->sector_count_exp = res_pass16->sector_count_exp;
1984 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1985 cam_fill_ataio(&ccb->ataio,
1994 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1995 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1997 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1999 if (ata_flags & AP_FLAG_CHK_COND)
2000 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
2002 return ata_cam_send(device, ccb, 0);
2006 dump_data(uint16_t *ptr, uint32_t len)
2010 for (i = 0; i < len / 2; i++) {
2012 printf(" %3d: ", i);
2013 printf("%04hx ", ptr[i]);
2022 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
2023 int is48bit, u_int64_t *hpasize)
2025 struct ata_res *res;
2027 res = &ccb->ataio.res;
2028 if (res->status & ATA_STATUS_ERROR) {
2029 if (arglist & CAM_ARG_VERBOSE) {
2030 cam_error_print(device, ccb, CAM_ESF_ALL,
2031 CAM_EPF_ALL, stderr);
2032 printf("error = 0x%02x, sector_count = 0x%04x, "
2033 "device = 0x%02x, status = 0x%02x\n",
2034 res->error, res->sector_count,
2035 res->device, res->status);
2038 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
2039 warnx("Max address has already been set since "
2040 "last power-on or hardware reset");
2046 if (arglist & CAM_ARG_VERBOSE) {
2047 fprintf(stdout, "%s%d: Raw native max data:\n",
2048 device->device_name, device->dev_unit_num);
2049 /* res is 4 byte aligned */
2050 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
2052 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
2053 "status = 0x%02x\n", res->error, res->sector_count,
2054 res->device, res->status);
2057 if (hpasize != NULL) {
2059 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
2060 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
2061 ((res->lba_high << 16) | (res->lba_mid << 8) |
2064 *hpasize = (((res->device & 0x0f) << 24) |
2065 (res->lba_high << 16) | (res->lba_mid << 8) |
2074 ata_read_native_max(struct cam_device *device, int retry_count,
2075 u_int32_t timeout, union ccb *ccb,
2076 struct ata_params *parm, u_int64_t *hpasize)
2082 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
2083 protocol = AP_PROTO_NON_DATA;
2086 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
2087 protocol |= AP_EXTEND;
2089 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
2092 error = ata_do_cmd(device,
2095 /*flags*/CAM_DIR_NONE,
2096 /*protocol*/protocol,
2097 /*ata_flags*/AP_FLAG_CHK_COND,
2098 /*tag_action*/MSG_SIMPLE_Q_TAG,
2105 timeout ? timeout : 5000,
2111 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
2115 atahpa_set_max(struct cam_device *device, int retry_count,
2116 u_int32_t timeout, union ccb *ccb,
2117 int is48bit, u_int64_t maxsize, int persist)
2123 protocol = AP_PROTO_NON_DATA;
2126 cmd = ATA_SET_MAX_ADDRESS48;
2127 protocol |= AP_EXTEND;
2129 cmd = ATA_SET_MAX_ADDRESS;
2132 /* lba's are zero indexed so the max lba is requested max - 1 */
2136 error = ata_do_cmd(device,
2139 /*flags*/CAM_DIR_NONE,
2140 /*protocol*/protocol,
2141 /*ata_flags*/AP_FLAG_CHK_COND,
2142 /*tag_action*/MSG_SIMPLE_Q_TAG,
2144 /*features*/ATA_HPA_FEAT_MAX_ADDR,
2146 /*sector_count*/persist,
2149 timeout ? timeout : 1000,
2155 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2159 atahpa_password(struct cam_device *device, int retry_count,
2160 u_int32_t timeout, union ccb *ccb,
2161 int is48bit, struct ata_set_max_pwd *pwd)
2167 protocol = AP_PROTO_PIO_OUT;
2168 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2170 error = ata_do_cmd(device,
2173 /*flags*/CAM_DIR_OUT,
2174 /*protocol*/protocol,
2175 /*ata_flags*/AP_FLAG_CHK_COND,
2176 /*tag_action*/MSG_SIMPLE_Q_TAG,
2178 /*features*/ATA_HPA_FEAT_SET_PWD,
2181 /*data_ptr*/(u_int8_t*)pwd,
2182 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2183 timeout ? timeout : 1000,
2189 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2193 atahpa_lock(struct cam_device *device, int retry_count,
2194 u_int32_t timeout, union ccb *ccb, int is48bit)
2200 protocol = AP_PROTO_NON_DATA;
2201 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2203 error = ata_do_cmd(device,
2206 /*flags*/CAM_DIR_NONE,
2207 /*protocol*/protocol,
2208 /*ata_flags*/AP_FLAG_CHK_COND,
2209 /*tag_action*/MSG_SIMPLE_Q_TAG,
2211 /*features*/ATA_HPA_FEAT_LOCK,
2216 timeout ? timeout : 1000,
2222 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2226 atahpa_unlock(struct cam_device *device, int retry_count,
2227 u_int32_t timeout, union ccb *ccb,
2228 int is48bit, struct ata_set_max_pwd *pwd)
2234 protocol = AP_PROTO_PIO_OUT;
2235 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2237 error = ata_do_cmd(device,
2240 /*flags*/CAM_DIR_OUT,
2241 /*protocol*/protocol,
2242 /*ata_flags*/AP_FLAG_CHK_COND,
2243 /*tag_action*/MSG_SIMPLE_Q_TAG,
2245 /*features*/ATA_HPA_FEAT_UNLOCK,
2248 /*data_ptr*/(u_int8_t*)pwd,
2249 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2250 timeout ? timeout : 1000,
2256 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2260 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2261 u_int32_t timeout, union ccb *ccb, int is48bit)
2267 protocol = AP_PROTO_NON_DATA;
2268 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2270 error = ata_do_cmd(device,
2273 /*flags*/CAM_DIR_NONE,
2274 /*protocol*/protocol,
2275 /*ata_flags*/AP_FLAG_CHK_COND,
2276 /*tag_action*/MSG_SIMPLE_Q_TAG,
2278 /*features*/ATA_HPA_FEAT_FREEZE,
2283 timeout ? timeout : 1000,
2289 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2293 ata_get_native_max(struct cam_device *device, int retry_count,
2294 u_int32_t timeout, union ccb *ccb,
2295 u_int64_t *nativesize)
2299 error = ata_do_cmd(device,
2302 /*flags*/CAM_DIR_NONE,
2303 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2304 /*ata_flags*/AP_FLAG_CHK_COND,
2305 /*tag_action*/MSG_SIMPLE_Q_TAG,
2306 /*command*/ATA_AMAX_ADDR,
2307 /*features*/ATA_AMAX_ADDR_GET,
2312 timeout ? timeout : 30 * 1000,
2318 return atahpa_proc_resp(device, ccb, /*is48bit*/1, nativesize);
2322 ataama_set(struct cam_device *device, int retry_count,
2323 u_int32_t timeout, union ccb *ccb, u_int64_t maxsize)
2327 /* lba's are zero indexed so the max lba is requested max - 1 */
2331 error = ata_do_cmd(device,
2334 /*flags*/CAM_DIR_NONE,
2335 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2336 /*ata_flags*/AP_FLAG_CHK_COND,
2337 /*tag_action*/MSG_SIMPLE_Q_TAG,
2338 /*command*/ATA_AMAX_ADDR,
2339 /*features*/ATA_AMAX_ADDR_SET,
2344 timeout ? timeout : 30 * 1000,
2350 return atahpa_proc_resp(device, ccb, /*is48bit*/1, NULL);
2354 ataama_freeze(struct cam_device *device, int retry_count,
2355 u_int32_t timeout, union ccb *ccb)
2359 error = ata_do_cmd(device,
2362 /*flags*/CAM_DIR_NONE,
2363 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2364 /*ata_flags*/AP_FLAG_CHK_COND,
2365 /*tag_action*/MSG_SIMPLE_Q_TAG,
2366 /*command*/ATA_AMAX_ADDR,
2367 /*features*/ATA_AMAX_ADDR_FREEZE,
2372 timeout ? timeout : 30 * 1000,
2378 return atahpa_proc_resp(device, ccb, /*is48bit*/1, NULL);
2382 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2383 union ccb *ccb, struct ata_params** ident_bufp)
2385 struct ata_params *ident_buf;
2386 struct ccb_pathinq cpi;
2387 struct ccb_getdev cgd;
2390 u_int8_t command, retry_command;
2392 if (get_cpi(device, &cpi) != 0) {
2393 warnx("couldn't get CPI");
2397 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2398 if (cpi.protocol == PROTO_ATA) {
2399 if (get_cgd(device, &cgd) != 0) {
2400 warnx("couldn't get CGD");
2404 command = (cgd.protocol == PROTO_ATA) ?
2405 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2408 /* We don't know which for sure so try both */
2409 command = ATA_ATA_IDENTIFY;
2410 retry_command = ATA_ATAPI_IDENTIFY;
2413 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2415 warnx("can't calloc memory for identify\n");
2419 error = ata_do_28bit_cmd(device,
2421 /*retries*/retry_count,
2422 /*flags*/CAM_DIR_IN,
2423 /*protocol*/AP_PROTO_PIO_IN,
2424 /*tag_action*/MSG_SIMPLE_Q_TAG,
2429 /*data_ptr*/(u_int8_t *)ptr,
2430 /*dxfer_len*/sizeof(struct ata_params),
2431 /*timeout*/timeout ? timeout : 30 * 1000,
2435 if (retry_command == 0) {
2439 error = ata_do_28bit_cmd(device,
2441 /*retries*/retry_count,
2442 /*flags*/CAM_DIR_IN,
2443 /*protocol*/AP_PROTO_PIO_IN,
2444 /*tag_action*/MSG_SIMPLE_Q_TAG,
2445 /*command*/retry_command,
2449 /*data_ptr*/(u_int8_t *)ptr,
2450 /*dxfer_len*/sizeof(struct ata_params),
2451 /*timeout*/timeout ? timeout : 30 * 1000,
2460 ident_buf = (struct ata_params *)ptr;
2461 ata_param_fixup(ident_buf);
2464 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2469 if (arglist & CAM_ARG_VERBOSE) {
2470 fprintf(stdout, "%s%d: Raw identify data:\n",
2471 device->device_name, device->dev_unit_num);
2472 dump_data(ptr, sizeof(struct ata_params));
2475 /* check for invalid (all zero) response */
2477 warnx("Invalid identify response detected");
2482 *ident_bufp = ident_buf;
2489 ataidentify(struct cam_device *device, int retry_count, int timeout)
2492 struct ata_params *ident_buf;
2493 u_int64_t hpasize, nativesize;
2495 if ((ccb = cam_getccb(device)) == NULL) {
2496 warnx("couldn't allocate CCB");
2500 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2505 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2506 if (ata_read_native_max(device, retry_count, timeout, ccb,
2507 ident_buf, &hpasize) != 0) {
2514 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR) {
2515 if (ata_get_native_max(device, retry_count, timeout, ccb,
2516 &nativesize) != 0) {
2524 printf("%s%d: ", device->device_name, device->dev_unit_num);
2525 ata_print_ident(ident_buf);
2526 camxferrate(device);
2527 atacapprint(ident_buf);
2528 atahpa_print(ident_buf, hpasize, 0);
2529 ataama_print(ident_buf, nativesize, 0);
2539 nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused)
2541 struct nvme_controller_data cdata;
2543 if (nvme_get_cdata(device, &cdata))
2545 nvme_print_controller(&cdata);
2552 identify(struct cam_device *device, int retry_count, int timeout)
2555 struct ccb_pathinq cpi;
2557 if (get_cpi(device, &cpi) != 0) {
2558 warnx("couldn't get CPI");
2562 if (cpi.protocol == PROTO_NVME) {
2563 return (nvmeidentify(device, retry_count, timeout));
2566 return (ataidentify(device, retry_count, timeout));
2571 ATA_SECURITY_ACTION_PRINT,
2572 ATA_SECURITY_ACTION_FREEZE,
2573 ATA_SECURITY_ACTION_UNLOCK,
2574 ATA_SECURITY_ACTION_DISABLE,
2575 ATA_SECURITY_ACTION_ERASE,
2576 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2577 ATA_SECURITY_ACTION_SET_PASSWORD
2581 atasecurity_print_time(u_int16_t tw)
2585 printf("unspecified");
2587 printf("> 508 min");
2589 printf("%i min", 2 * tw);
2593 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2597 return 2 * 3600 * 1000; /* default: two hours */
2598 else if (timeout > 255)
2599 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2601 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2606 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2610 bzero(&cmd, sizeof(cmd));
2611 cmd.command = command;
2612 printf("Issuing %s", ata_op_string(&cmd));
2615 char pass[sizeof(pwd->password)+1];
2617 /* pwd->password may not be null terminated */
2618 pass[sizeof(pwd->password)] = '\0';
2619 strncpy(pass, pwd->password, sizeof(pwd->password));
2620 printf(" password='%s', user='%s'",
2622 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2625 if (command == ATA_SECURITY_SET_PASSWORD) {
2626 printf(", mode='%s'",
2627 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2628 "maximum" : "high");
2636 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2637 int retry_count, u_int32_t timeout, int quiet)
2641 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2643 return ata_do_28bit_cmd(device,
2646 /*flags*/CAM_DIR_NONE,
2647 /*protocol*/AP_PROTO_NON_DATA,
2648 /*tag_action*/MSG_SIMPLE_Q_TAG,
2649 /*command*/ATA_SECURITY_FREEZE_LOCK,
2660 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2661 int retry_count, u_int32_t timeout,
2662 struct ata_security_password *pwd, int quiet)
2666 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2668 return ata_do_28bit_cmd(device,
2671 /*flags*/CAM_DIR_OUT,
2672 /*protocol*/AP_PROTO_PIO_OUT,
2673 /*tag_action*/MSG_SIMPLE_Q_TAG,
2674 /*command*/ATA_SECURITY_UNLOCK,
2678 /*data_ptr*/(u_int8_t *)pwd,
2679 /*dxfer_len*/sizeof(*pwd),
2685 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2686 int retry_count, u_int32_t timeout,
2687 struct ata_security_password *pwd, int quiet)
2691 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2692 return ata_do_28bit_cmd(device,
2695 /*flags*/CAM_DIR_OUT,
2696 /*protocol*/AP_PROTO_PIO_OUT,
2697 /*tag_action*/MSG_SIMPLE_Q_TAG,
2698 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2702 /*data_ptr*/(u_int8_t *)pwd,
2703 /*dxfer_len*/sizeof(*pwd),
2710 atasecurity_erase_confirm(struct cam_device *device,
2711 struct ata_params* ident_buf)
2714 printf("\nYou are about to ERASE ALL DATA from the following"
2715 " device:\n%s%d,%s%d: ", device->device_name,
2716 device->dev_unit_num, device->given_dev_name,
2717 device->given_unit_number);
2718 ata_print_ident(ident_buf);
2722 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2724 if (fgets(str, sizeof(str), stdin) != NULL) {
2725 if (strncasecmp(str, "yes", 3) == 0) {
2727 } else if (strncasecmp(str, "no", 2) == 0) {
2730 printf("Please answer \"yes\" or "
2741 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2742 int retry_count, u_int32_t timeout,
2743 u_int32_t erase_timeout,
2744 struct ata_security_password *pwd, int quiet)
2749 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2751 error = ata_do_28bit_cmd(device,
2754 /*flags*/CAM_DIR_NONE,
2755 /*protocol*/AP_PROTO_NON_DATA,
2756 /*tag_action*/MSG_SIMPLE_Q_TAG,
2757 /*command*/ATA_SECURITY_ERASE_PREPARE,
2770 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2772 error = ata_do_28bit_cmd(device,
2775 /*flags*/CAM_DIR_OUT,
2776 /*protocol*/AP_PROTO_PIO_OUT,
2777 /*tag_action*/MSG_SIMPLE_Q_TAG,
2778 /*command*/ATA_SECURITY_ERASE_UNIT,
2782 /*data_ptr*/(u_int8_t *)pwd,
2783 /*dxfer_len*/sizeof(*pwd),
2784 /*timeout*/erase_timeout,
2787 if (error == 0 && quiet == 0)
2788 printf("\nErase Complete\n");
2794 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2795 int retry_count, u_int32_t timeout,
2796 struct ata_security_password *pwd, int quiet)
2800 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2802 return ata_do_28bit_cmd(device,
2805 /*flags*/CAM_DIR_OUT,
2806 /*protocol*/AP_PROTO_PIO_OUT,
2807 /*tag_action*/MSG_SIMPLE_Q_TAG,
2808 /*command*/ATA_SECURITY_SET_PASSWORD,
2812 /*data_ptr*/(u_int8_t *)pwd,
2813 /*dxfer_len*/sizeof(*pwd),
2819 atasecurity_print(struct ata_params *parm)
2822 printf("\nSecurity Option Value\n");
2823 if (arglist & CAM_ARG_VERBOSE) {
2824 printf("status %04x\n",
2825 parm->security_status);
2827 printf("supported %s\n",
2828 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2829 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2831 printf("enabled %s\n",
2832 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2833 printf("drive locked %s\n",
2834 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2835 printf("security config frozen %s\n",
2836 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2837 printf("count expired %s\n",
2838 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2839 printf("security level %s\n",
2840 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2841 printf("enhanced erase supported %s\n",
2842 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2843 printf("erase time ");
2844 atasecurity_print_time(parm->erase_time);
2846 printf("enhanced erase time ");
2847 atasecurity_print_time(parm->enhanced_erase_time);
2849 printf("master password rev %04x%s\n",
2850 parm->master_passwd_revision,
2851 parm->master_passwd_revision == 0x0000 ||
2852 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2856 * Validates and copies the password in optarg to the passed buffer.
2857 * If the password in optarg is the same length as the buffer then
2858 * the data will still be copied but no null termination will occur.
2861 ata_getpwd(u_int8_t *passwd, int max, char opt)
2865 len = strlen(optarg);
2867 warnx("-%c password is too long", opt);
2869 } else if (len == 0) {
2870 warnx("-%c password is missing", opt);
2872 } else if (optarg[0] == '-'){
2873 warnx("-%c password starts with '-' (generic arg?)", opt);
2875 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2876 warnx("-%c password conflicts with existing password from -%c",
2881 /* Callers pass in a buffer which does NOT need to be terminated */
2882 strncpy(passwd, optarg, max);
2889 ATA_HPA_ACTION_PRINT,
2890 ATA_HPA_ACTION_SET_MAX,
2891 ATA_HPA_ACTION_SET_PWD,
2892 ATA_HPA_ACTION_LOCK,
2893 ATA_HPA_ACTION_UNLOCK,
2894 ATA_HPA_ACTION_FREEZE_LOCK
2898 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2899 u_int64_t maxsize, int persist)
2901 printf("\nYou are about to configure HPA to limit the user accessible\n"
2902 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2903 persist ? "persistently" : "temporarily",
2904 device->device_name, device->dev_unit_num,
2905 device->given_dev_name, device->given_unit_number);
2906 ata_print_ident(ident_buf);
2910 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2912 if (NULL != fgets(str, sizeof(str), stdin)) {
2913 if (0 == strncasecmp(str, "yes", 3)) {
2915 } else if (0 == strncasecmp(str, "no", 2)) {
2918 printf("Please answer \"yes\" or "
2929 atahpa(struct cam_device *device, int retry_count, int timeout,
2930 int argc, char **argv, char *combinedopt)
2933 struct ata_params *ident_buf;
2934 struct ccb_getdev cgd;
2935 struct ata_set_max_pwd pwd;
2936 int error, confirm, quiet, c, action, actions, persist;
2937 int security, is48bit, pwdsize;
2938 u_int64_t hpasize, maxsize;
2947 memset(&pwd, 0, sizeof(pwd));
2949 /* default action is to print hpa information */
2950 action = ATA_HPA_ACTION_PRINT;
2951 pwdsize = sizeof(pwd.password);
2953 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2956 action = ATA_HPA_ACTION_SET_MAX;
2957 maxsize = strtoumax(optarg, NULL, 0);
2962 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2964 action = ATA_HPA_ACTION_SET_PWD;
2970 action = ATA_HPA_ACTION_LOCK;
2976 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2978 action = ATA_HPA_ACTION_UNLOCK;
2984 action = ATA_HPA_ACTION_FREEZE_LOCK;
3004 warnx("too many hpa actions specified");
3008 if (get_cgd(device, &cgd) != 0) {
3009 warnx("couldn't get CGD");
3013 ccb = cam_getccb(device);
3015 warnx("couldn't allocate CCB");
3019 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3026 printf("%s%d: ", device->device_name, device->dev_unit_num);
3027 ata_print_ident(ident_buf);
3028 camxferrate(device);
3031 if (action == ATA_HPA_ACTION_PRINT) {
3032 error = ata_read_native_max(device, retry_count, timeout, ccb,
3033 ident_buf, &hpasize);
3035 atahpa_print(ident_buf, hpasize, 1);
3042 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
3043 warnx("HPA is not supported by this device");
3049 if (security && !(ident_buf->support.command2 & ATA_SUPPORT_MAXSECURITY)) {
3050 warnx("HPA Security is not supported by this device");
3056 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
3059 * The ATA spec requires:
3060 * 1. Read native max addr is called directly before set max addr
3061 * 2. Read native max addr is NOT called before any other set max call
3064 case ATA_HPA_ACTION_SET_MAX:
3066 atahpa_set_confirm(device, ident_buf, maxsize,
3073 error = ata_read_native_max(device, retry_count, timeout,
3074 ccb, ident_buf, &hpasize);
3076 error = atahpa_set_max(device, retry_count, timeout,
3077 ccb, is48bit, maxsize, persist);
3078 if (error == 0 && quiet == 0) {
3079 /* redo identify to get new lba values */
3080 error = ata_do_identify(device, retry_count,
3083 atahpa_print(ident_buf, hpasize, 1);
3088 case ATA_HPA_ACTION_SET_PWD:
3089 error = atahpa_password(device, retry_count, timeout,
3090 ccb, is48bit, &pwd);
3091 if (error == 0 && quiet == 0)
3092 printf("HPA password has been set\n");
3095 case ATA_HPA_ACTION_LOCK:
3096 error = atahpa_lock(device, retry_count, timeout,
3098 if (error == 0 && quiet == 0)
3099 printf("HPA has been locked\n");
3102 case ATA_HPA_ACTION_UNLOCK:
3103 error = atahpa_unlock(device, retry_count, timeout,
3104 ccb, is48bit, &pwd);
3105 if (error == 0 && quiet == 0)
3106 printf("HPA has been unlocked\n");
3109 case ATA_HPA_ACTION_FREEZE_LOCK:
3110 error = atahpa_freeze_lock(device, retry_count, timeout,
3112 if (error == 0 && quiet == 0)
3113 printf("HPA has been frozen\n");
3117 errx(1, "Option currently not supported");
3127 ATA_AMA_ACTION_PRINT,
3128 ATA_AMA_ACTION_SET_MAX,
3129 ATA_AMA_ACTION_FREEZE_LOCK
3133 ataama(struct cam_device *device, int retry_count, int timeout,
3134 int argc, char **argv, char *combinedopt)
3137 struct ata_params *ident_buf;
3138 struct ccb_getdev cgd;
3139 int error, quiet, c, action, actions;
3140 u_int64_t nativesize, maxsize;
3146 /* default action is to print AMA information */
3147 action = ATA_AMA_ACTION_PRINT;
3149 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3152 action = ATA_AMA_ACTION_SET_MAX;
3153 maxsize = strtoumax(optarg, NULL, 0);
3158 action = ATA_AMA_ACTION_FREEZE_LOCK;
3169 warnx("too many AMA actions specified");
3173 if (get_cgd(device, &cgd) != 0) {
3174 warnx("couldn't get CGD");
3178 ccb = cam_getccb(device);
3180 warnx("couldn't allocate CCB");
3184 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3191 printf("%s%d: ", device->device_name, device->dev_unit_num);
3192 ata_print_ident(ident_buf);
3193 camxferrate(device);
3196 if (action == ATA_AMA_ACTION_PRINT) {
3197 error = ata_get_native_max(device, retry_count, timeout, ccb,
3200 ataama_print(ident_buf, nativesize, 1);
3207 if (!(ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)) {
3208 warnx("Accessible Max Address is not supported by this device");
3215 case ATA_AMA_ACTION_SET_MAX:
3216 error = ata_get_native_max(device, retry_count, timeout, ccb,
3219 error = ataama_set(device, retry_count, timeout,
3221 if (error == 0 && quiet == 0) {
3222 /* redo identify to get new lba values */
3223 error = ata_do_identify(device, retry_count,
3224 timeout, ccb, &ident_buf);
3225 ataama_print(ident_buf, nativesize, 1);
3230 case ATA_AMA_ACTION_FREEZE_LOCK:
3231 error = ataama_freeze(device, retry_count, timeout,
3233 if (error == 0 && quiet == 0)
3234 printf("Accessible Max Address has been frozen\n");
3238 errx(1, "Option currently not supported");
3248 atasecurity(struct cam_device *device, int retry_count, int timeout,
3249 int argc, char **argv, char *combinedopt)
3252 struct ata_params *ident_buf;
3253 int error, confirm, quiet, c, action, actions, setpwd;
3254 int security_enabled, erase_timeout, pwdsize;
3255 struct ata_security_password pwd;
3263 memset(&pwd, 0, sizeof(pwd));
3265 /* default action is to print security information */
3266 action = ATA_SECURITY_ACTION_PRINT;
3268 /* user is master by default as its safer that way */
3269 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3270 pwdsize = sizeof(pwd.password);
3272 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3275 action = ATA_SECURITY_ACTION_FREEZE;
3280 if (strcasecmp(optarg, "user") == 0) {
3281 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
3282 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
3283 } else if (strcasecmp(optarg, "master") == 0) {
3284 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3285 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
3287 warnx("-U argument '%s' is invalid (must be "
3288 "'user' or 'master')", optarg);
3294 if (strcasecmp(optarg, "high") == 0) {
3295 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3296 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3297 } else if (strcasecmp(optarg, "maximum") == 0) {
3298 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3299 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3301 warnx("-l argument '%s' is unknown (must be "
3302 "'high' or 'maximum')", optarg);
3308 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3310 action = ATA_SECURITY_ACTION_UNLOCK;
3315 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3317 action = ATA_SECURITY_ACTION_DISABLE;
3322 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3324 action = ATA_SECURITY_ACTION_ERASE;
3329 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3331 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3332 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3337 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3340 if (action == ATA_SECURITY_ACTION_PRINT)
3341 action = ATA_SECURITY_ACTION_SET_PASSWORD;
3343 * Don't increment action as this can be combined
3344 * with other actions.
3357 erase_timeout = atoi(optarg) * 1000;
3363 warnx("too many security actions specified");
3367 if ((ccb = cam_getccb(device)) == NULL) {
3368 warnx("couldn't allocate CCB");
3372 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3379 printf("%s%d: ", device->device_name, device->dev_unit_num);
3380 ata_print_ident(ident_buf);
3381 camxferrate(device);
3384 if (action == ATA_SECURITY_ACTION_PRINT) {
3385 atasecurity_print(ident_buf);
3391 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3392 warnx("Security not supported");
3398 /* default timeout 15 seconds the same as linux hdparm */
3399 timeout = timeout ? timeout : 15 * 1000;
3401 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3403 /* first set the password if requested */
3405 /* confirm we can erase before setting the password if erasing */
3407 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3408 action == ATA_SECURITY_ACTION_ERASE) &&
3409 atasecurity_erase_confirm(device, ident_buf) == 0) {
3415 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3416 pwd.revision = ident_buf->master_passwd_revision;
3417 if (pwd.revision != 0 && pwd.revision != 0xfff &&
3418 --pwd.revision == 0) {
3419 pwd.revision = 0xfffe;
3422 error = atasecurity_set_password(device, ccb, retry_count,
3423 timeout, &pwd, quiet);
3429 security_enabled = 1;
3433 case ATA_SECURITY_ACTION_FREEZE:
3434 error = atasecurity_freeze(device, ccb, retry_count,
3438 case ATA_SECURITY_ACTION_UNLOCK:
3439 if (security_enabled) {
3440 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3441 error = atasecurity_unlock(device, ccb,
3442 retry_count, timeout, &pwd, quiet);
3444 warnx("Can't unlock, drive is not locked");
3448 warnx("Can't unlock, security is disabled");
3453 case ATA_SECURITY_ACTION_DISABLE:
3454 if (security_enabled) {
3455 /* First unlock the drive if its locked */
3456 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3457 error = atasecurity_unlock(device, ccb,
3465 error = atasecurity_disable(device,
3473 warnx("Can't disable security (already disabled)");
3478 case ATA_SECURITY_ACTION_ERASE:
3479 if (security_enabled) {
3480 if (erase_timeout == 0) {
3481 erase_timeout = atasecurity_erase_timeout_msecs(
3482 ident_buf->erase_time);
3485 error = atasecurity_erase(device, ccb, retry_count,
3486 timeout, erase_timeout, &pwd, quiet);
3488 warnx("Can't secure erase (security is disabled)");
3493 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3494 if (security_enabled) {
3495 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3496 if (erase_timeout == 0) {
3498 atasecurity_erase_timeout_msecs(
3499 ident_buf->enhanced_erase_time);
3502 error = atasecurity_erase(device, ccb,
3503 retry_count, timeout,
3504 erase_timeout, &pwd,
3507 warnx("Enhanced erase is not supported");
3511 warnx("Can't secure erase (enhanced), "
3512 "(security is disabled)");
3525 * Parse out a bus, or a bus, target and lun in the following
3531 * Returns the number of parsed components, or 0.
3534 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3535 cam_argmask *arglst)
3540 while (isspace(*tstr) && (*tstr != '\0'))
3543 tmpstr = (char *)strtok(tstr, ":");
3544 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3545 *bus = strtol(tmpstr, NULL, 0);
3546 *arglst |= CAM_ARG_BUS;
3548 tmpstr = (char *)strtok(NULL, ":");
3549 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3550 *target = strtol(tmpstr, NULL, 0);
3551 *arglst |= CAM_ARG_TARGET;
3553 tmpstr = (char *)strtok(NULL, ":");
3554 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3555 *lun = strtol(tmpstr, NULL, 0);
3556 *arglst |= CAM_ARG_LUN;
3566 dorescan_or_reset(int argc, char **argv, int rescan)
3568 static const char must[] =
3569 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3571 path_id_t bus = CAM_BUS_WILDCARD;
3572 target_id_t target = CAM_TARGET_WILDCARD;
3573 lun_id_t lun = CAM_LUN_WILDCARD;
3577 warnx(must, rescan? "rescan" : "reset");
3581 tstr = argv[optind];
3582 while (isspace(*tstr) && (*tstr != '\0'))
3584 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3585 arglist |= CAM_ARG_BUS;
3586 else if (isdigit(*tstr)) {
3587 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3588 if (rv != 1 && rv != 3) {
3589 warnx(must, rescan? "rescan" : "reset");
3599 * Note that resetting or rescanning a device used to
3600 * require a bus or bus:target:lun. This is because the
3601 * device in question may not exist and you're trying to
3602 * get the controller to rescan to find it. It may also be
3603 * because the device is hung / unresponsive, and opening
3604 * an unresponsive device is not desireable.
3606 * It can be more convenient to reference a device by
3607 * peripheral name and unit number, though, and it is
3608 * possible to get the bus:target:lun for devices that
3609 * currently exist in the EDT. So this can work for
3610 * devices that we want to reset, or devices that exist
3611 * that we want to rescan, but not devices that do not
3614 * So, we are careful here to look up the bus/target/lun
3615 * for the device the user wants to operate on, specified
3616 * by peripheral instance (e.g. da0, pass32) without
3617 * actually opening that device. The process is similar to
3618 * what cam_lookup_pass() does, except that we don't
3619 * actually open the passthrough driver instance in the end.
3622 if (cam_get_device(tstr, name, sizeof(name), &unit) == -1) {
3623 warnx("%s", cam_errbuf);
3628 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3629 warn("Unable to open %s", XPT_DEVICE);
3634 bzero(&ccb, sizeof(ccb));
3637 * The function code isn't strictly necessary for the
3638 * GETPASSTHRU ioctl.
3640 ccb.ccb_h.func_code = XPT_GDEVLIST;
3643 * These two are necessary for the GETPASSTHRU ioctl to
3646 strlcpy(ccb.cgdl.periph_name, name,
3647 sizeof(ccb.cgdl.periph_name));
3648 ccb.cgdl.unit_number = unit;
3651 * Attempt to get the passthrough device. This ioctl will
3652 * fail if the device name is null, if the device doesn't
3653 * exist, or if the passthrough driver isn't in the kernel.
3655 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3656 warn("Unable to find bus:target:lun for device %s%d",
3662 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3663 const struct cam_status_entry *entry;
3665 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3666 warnx("Unable to find bus:target_lun for device %s%d, "
3667 "CAM status: %s (%#x)", name, unit,
3668 entry ? entry->status_text : "Unknown",
3676 * The kernel fills in the bus/target/lun. We don't
3677 * need the passthrough device name and unit number since
3678 * we aren't going to open it.
3680 bus = ccb.ccb_h.path_id;
3681 target = ccb.ccb_h.target_id;
3682 lun = ccb.ccb_h.target_lun;
3684 arglist |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3689 if ((arglist & CAM_ARG_BUS)
3690 && (arglist & CAM_ARG_TARGET)
3691 && (arglist & CAM_ARG_LUN))
3692 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3694 error = rescan_or_reset_bus(bus, rescan);
3702 rescan_or_reset_bus(path_id_t bus, int rescan)
3704 union ccb *ccb = NULL, *matchccb = NULL;
3705 int fd = -1, retval;
3710 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3711 warnx("error opening transport layer device %s", XPT_DEVICE);
3712 warn("%s", XPT_DEVICE);
3716 ccb = malloc(sizeof(*ccb));
3718 warn("failed to allocate CCB");
3722 bzero(ccb, sizeof(*ccb));
3724 if (bus != CAM_BUS_WILDCARD) {
3725 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3726 ccb->ccb_h.path_id = bus;
3727 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3728 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3729 ccb->crcn.flags = CAM_FLAG_NONE;
3731 /* run this at a low priority */
3732 ccb->ccb_h.pinfo.priority = 5;
3734 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3735 warn("CAMIOCOMMAND ioctl failed");
3740 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3741 fprintf(stdout, "%s of bus %d was successful\n",
3742 rescan ? "Re-scan" : "Reset", bus);
3744 fprintf(stdout, "%s of bus %d returned error %#x\n",
3745 rescan ? "Re-scan" : "Reset", bus,
3746 ccb->ccb_h.status & CAM_STATUS_MASK);
3755 * The right way to handle this is to modify the xpt so that it can
3756 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3757 * that isn't implemented, so instead we enumerate the buses and
3758 * send the rescan or reset to those buses in the case where the
3759 * given bus is -1 (wildcard). We don't send a rescan or reset
3760 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3761 * no-op, sending a rescan to the xpt bus would result in a status of
3764 matchccb = malloc(sizeof(*matchccb));
3765 if (matchccb == NULL) {
3766 warn("failed to allocate CCB");
3770 bzero(matchccb, sizeof(*matchccb));
3771 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3772 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3773 bufsize = sizeof(struct dev_match_result) * 20;
3774 matchccb->cdm.match_buf_len = bufsize;
3775 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3776 if (matchccb->cdm.matches == NULL) {
3777 warnx("can't malloc memory for matches");
3781 matchccb->cdm.num_matches = 0;
3783 matchccb->cdm.num_patterns = 1;
3784 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3786 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3787 matchccb->cdm.pattern_buf_len);
3788 if (matchccb->cdm.patterns == NULL) {
3789 warnx("can't malloc memory for patterns");
3793 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3794 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3799 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3800 warn("CAMIOCOMMAND ioctl failed");
3805 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3806 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3807 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3808 warnx("got CAM error %#x, CDM error %d\n",
3809 matchccb->ccb_h.status, matchccb->cdm.status);
3814 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3815 struct bus_match_result *bus_result;
3817 /* This shouldn't happen. */
3818 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3821 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3824 * We don't want to rescan or reset the xpt bus.
3827 if (bus_result->path_id == CAM_XPT_PATH_ID)
3830 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3832 ccb->ccb_h.path_id = bus_result->path_id;
3833 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3834 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3835 ccb->crcn.flags = CAM_FLAG_NONE;
3837 /* run this at a low priority */
3838 ccb->ccb_h.pinfo.priority = 5;
3840 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3841 warn("CAMIOCOMMAND ioctl failed");
3846 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3847 fprintf(stdout, "%s of bus %d was successful\n",
3848 rescan? "Re-scan" : "Reset",
3849 bus_result->path_id);
3852 * Don't bail out just yet, maybe the other
3853 * rescan or reset commands will complete
3856 fprintf(stderr, "%s of bus %d returned error "
3857 "%#x\n", rescan? "Re-scan" : "Reset",
3858 bus_result->path_id,
3859 ccb->ccb_h.status & CAM_STATUS_MASK);
3863 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3864 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3871 if (matchccb != NULL) {
3872 free(matchccb->cdm.patterns);
3873 free(matchccb->cdm.matches);
3882 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3885 struct cam_device *device;
3890 if (bus == CAM_BUS_WILDCARD) {
3891 warnx("invalid bus number %d", bus);
3895 if (target == CAM_TARGET_WILDCARD) {
3896 warnx("invalid target number %d", target);
3900 if (lun == CAM_LUN_WILDCARD) {
3901 warnx("invalid lun number %jx", (uintmax_t)lun);
3907 bzero(&ccb, sizeof(union ccb));
3910 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3911 warnx("error opening transport layer device %s\n",
3913 warn("%s", XPT_DEVICE);
3917 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3918 if (device == NULL) {
3919 warnx("%s", cam_errbuf);
3924 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3925 ccb.ccb_h.path_id = bus;
3926 ccb.ccb_h.target_id = target;
3927 ccb.ccb_h.target_lun = lun;
3928 ccb.ccb_h.timeout = 5000;
3929 ccb.crcn.flags = CAM_FLAG_NONE;
3931 /* run this at a low priority */
3932 ccb.ccb_h.pinfo.priority = 5;
3935 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3936 warn("CAMIOCOMMAND ioctl failed");
3941 if (cam_send_ccb(device, &ccb) < 0) {
3942 warn("error sending XPT_RESET_DEV CCB");
3943 cam_close_device(device);
3951 cam_close_device(device);
3954 * An error code of CAM_BDR_SENT is normal for a BDR request.
3956 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3958 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3959 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3960 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3963 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3964 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3965 ccb.ccb_h.status & CAM_STATUS_MASK);
3971 static struct scsi_nv defect_list_type_map[] = {
3972 { "block", SRDD10_BLOCK_FORMAT },
3973 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3974 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3975 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3976 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3977 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3981 readdefects(struct cam_device *device, int argc, char **argv,
3982 char *combinedopt, int task_attr, int retry_count, int timeout)
3984 union ccb *ccb = NULL;
3985 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3986 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3987 size_t hdr_size = 0, entry_size = 0;
3990 u_int8_t *defect_list = NULL;
3991 u_int8_t list_format = 0;
3992 int list_type_set = 0;
3993 u_int32_t dlist_length = 0;
3994 u_int32_t returned_length = 0, valid_len = 0;
3995 u_int32_t num_returned = 0, num_valid = 0;
3996 u_int32_t max_possible_size = 0, hdr_max = 0;
3997 u_int32_t starting_offset = 0;
3998 u_int8_t returned_format, returned_type;
4000 int summary = 0, quiet = 0;
4002 int lists_specified = 0;
4003 int get_length = 1, first_pass = 1;
4006 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4010 scsi_nv_status status;
4013 status = scsi_get_nv(defect_list_type_map,
4014 sizeof(defect_list_type_map) /
4015 sizeof(defect_list_type_map[0]), optarg,
4016 &entry_num, SCSI_NV_FLAG_IG_CASE);
4018 if (status == SCSI_NV_FOUND) {
4019 list_format = defect_list_type_map[
4023 warnx("%s: %s %s option %s", __func__,
4024 (status == SCSI_NV_AMBIGUOUS) ?
4025 "ambiguous" : "invalid", "defect list type",
4028 goto defect_bailout;
4033 arglist |= CAM_ARG_GLIST;
4036 arglist |= CAM_ARG_PLIST;
4047 starting_offset = strtoul(optarg, &endptr, 0);
4048 if (*endptr != '\0') {
4050 warnx("invalid starting offset %s", optarg);
4051 goto defect_bailout;
4063 if (list_type_set == 0) {
4065 warnx("no defect list format specified");
4066 goto defect_bailout;
4069 if (arglist & CAM_ARG_PLIST) {
4070 list_format |= SRDD10_PLIST;
4074 if (arglist & CAM_ARG_GLIST) {
4075 list_format |= SRDD10_GLIST;
4080 * This implies a summary, and was the previous behavior.
4082 if (lists_specified == 0)
4085 ccb = cam_getccb(device);
4090 * We start off asking for just the header to determine how much
4091 * defect data is available. Some Hitachi drives return an error
4092 * if you ask for more data than the drive has. Once we know the
4093 * length, we retry the command with the returned length.
4095 if (use_12byte == 0)
4096 dlist_length = sizeof(*hdr10);
4098 dlist_length = sizeof(*hdr12);
4101 if (defect_list != NULL) {
4105 defect_list = malloc(dlist_length);
4106 if (defect_list == NULL) {
4107 warnx("can't malloc memory for defect list");
4109 goto defect_bailout;
4113 bzero(defect_list, dlist_length);
4116 * cam_getccb() zeros the CCB header only. So we need to zero the
4117 * payload portion of the ccb.
4119 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4121 scsi_read_defects(&ccb->csio,
4122 /*retries*/ retry_count,
4124 /*tag_action*/ task_attr,
4125 /*list_format*/ list_format,
4126 /*addr_desc_index*/ starting_offset,
4127 /*data_ptr*/ defect_list,
4128 /*dxfer_len*/ dlist_length,
4129 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
4130 /*sense_len*/ SSD_FULL_SIZE,
4131 /*timeout*/ timeout ? timeout : 5000);
4133 /* Disable freezing the device queue */
4134 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4136 if (cam_send_ccb(device, ccb) < 0) {
4137 perror("error reading defect list");
4139 if (arglist & CAM_ARG_VERBOSE) {
4140 cam_error_print(device, ccb, CAM_ESF_ALL,
4141 CAM_EPF_ALL, stderr);
4145 goto defect_bailout;
4148 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
4150 if (use_12byte == 0) {
4151 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
4152 hdr_size = sizeof(*hdr10);
4153 hdr_max = SRDDH10_MAX_LENGTH;
4155 if (valid_len >= hdr_size) {
4156 returned_length = scsi_2btoul(hdr10->length);
4157 returned_format = hdr10->format;
4159 returned_length = 0;
4160 returned_format = 0;
4163 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
4164 hdr_size = sizeof(*hdr12);
4165 hdr_max = SRDDH12_MAX_LENGTH;
4167 if (valid_len >= hdr_size) {
4168 returned_length = scsi_4btoul(hdr12->length);
4169 returned_format = hdr12->format;
4171 returned_length = 0;
4172 returned_format = 0;
4176 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
4177 switch (returned_type) {
4178 case SRDD10_BLOCK_FORMAT:
4179 entry_size = sizeof(struct scsi_defect_desc_block);
4181 case SRDD10_LONG_BLOCK_FORMAT:
4182 entry_size = sizeof(struct scsi_defect_desc_long_block);
4184 case SRDD10_EXT_PHYS_FORMAT:
4185 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4186 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
4188 case SRDD10_EXT_BFI_FORMAT:
4189 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4190 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
4193 warnx("Unknown defect format 0x%x\n", returned_type);
4195 goto defect_bailout;
4199 max_possible_size = (hdr_max / entry_size) * entry_size;
4200 num_returned = returned_length / entry_size;
4201 num_valid = min(returned_length, valid_len - hdr_size);
4202 num_valid /= entry_size;
4204 if (get_length != 0) {
4207 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
4208 CAM_SCSI_STATUS_ERROR) {
4209 struct scsi_sense_data *sense;
4210 int error_code, sense_key, asc, ascq;
4212 sense = &ccb->csio.sense_data;
4213 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4214 ccb->csio.sense_resid, &error_code, &sense_key,
4215 &asc, &ascq, /*show_errors*/ 1);
4218 * If the drive is reporting that it just doesn't
4219 * support the defect list format, go ahead and use
4220 * the length it reported. Otherwise, the length
4221 * may not be valid, so use the maximum.
4223 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4224 && (asc == 0x1c) && (ascq == 0x00)
4225 && (returned_length > 0)) {
4226 if ((use_12byte == 0)
4227 && (returned_length >= max_possible_size)) {
4232 dlist_length = returned_length + hdr_size;
4233 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4234 && (asc == 0x1f) && (ascq == 0x00)
4235 && (returned_length > 0)) {
4236 /* Partial defect list transfer */
4238 * Hitachi drives return this error
4239 * along with a partial defect list if they
4240 * have more defects than the 10 byte
4241 * command can support. Retry with the 12
4244 if (use_12byte == 0) {
4249 dlist_length = returned_length + hdr_size;
4250 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
4251 && (asc == 0x24) && (ascq == 0x00)) {
4252 /* Invalid field in CDB */
4254 * SBC-3 says that if the drive has more
4255 * defects than can be reported with the
4256 * 10 byte command, it should return this
4257 * error and no data. Retry with the 12
4260 if (use_12byte == 0) {
4265 dlist_length = returned_length + hdr_size;
4268 * If we got a SCSI error and no valid length,
4269 * just use the 10 byte maximum. The 12
4270 * byte maximum is too large.
4272 if (returned_length == 0)
4273 dlist_length = SRDD10_MAX_LENGTH;
4275 if ((use_12byte == 0)
4276 && (returned_length >=
4277 max_possible_size)) {
4282 dlist_length = returned_length +
4286 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4289 warnx("Error reading defect header");
4290 if (arglist & CAM_ARG_VERBOSE)
4291 cam_error_print(device, ccb, CAM_ESF_ALL,
4292 CAM_EPF_ALL, stderr);
4293 goto defect_bailout;
4295 if ((use_12byte == 0)
4296 && (returned_length >= max_possible_size)) {
4301 dlist_length = returned_length + hdr_size;
4304 fprintf(stdout, "%u", num_returned);
4306 fprintf(stdout, " defect%s",
4307 (num_returned != 1) ? "s" : "");
4309 fprintf(stdout, "\n");
4311 goto defect_bailout;
4315 * We always limit the list length to the 10-byte maximum
4316 * length (0xffff). The reason is that some controllers
4317 * can't handle larger I/Os, and we can transfer the entire
4318 * 10 byte list in one shot. For drives that support the 12
4319 * byte read defects command, we'll step through the list
4320 * by specifying a starting offset. For drives that don't
4321 * support the 12 byte command's starting offset, we'll
4322 * just display the first 64K.
4324 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4330 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4331 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4332 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4333 struct scsi_sense_data *sense;
4334 int error_code, sense_key, asc, ascq;
4336 sense = &ccb->csio.sense_data;
4337 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4338 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4339 &ascq, /*show_errors*/ 1);
4342 * According to the SCSI spec, if the disk doesn't support
4343 * the requested format, it will generally return a sense
4344 * key of RECOVERED ERROR, and an additional sense code
4345 * of "DEFECT LIST NOT FOUND". HGST drives also return
4346 * Primary/Grown defect list not found errors. So just
4347 * check for an ASC of 0x1c.
4349 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4351 const char *format_str;
4353 format_str = scsi_nv_to_str(defect_list_type_map,
4354 sizeof(defect_list_type_map) /
4355 sizeof(defect_list_type_map[0]),
4356 list_format & SRDD10_DLIST_FORMAT_MASK);
4357 warnx("requested defect format %s not available",
4358 format_str ? format_str : "unknown");
4360 format_str = scsi_nv_to_str(defect_list_type_map,
4361 sizeof(defect_list_type_map) /
4362 sizeof(defect_list_type_map[0]), returned_type);
4363 if (format_str != NULL) {
4364 warnx("Device returned %s format",
4368 warnx("Device returned unknown defect"
4369 " data format %#x", returned_type);
4370 goto defect_bailout;
4374 warnx("Error returned from read defect data command");
4375 if (arglist & CAM_ARG_VERBOSE)
4376 cam_error_print(device, ccb, CAM_ESF_ALL,
4377 CAM_EPF_ALL, stderr);
4378 goto defect_bailout;
4380 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4382 warnx("Error returned from read defect data command");
4383 if (arglist & CAM_ARG_VERBOSE)
4384 cam_error_print(device, ccb, CAM_ESF_ALL,
4385 CAM_EPF_ALL, stderr);
4386 goto defect_bailout;
4389 if (first_pass != 0) {
4390 fprintf(stderr, "Got %d defect", num_returned);
4392 if ((lists_specified == 0) || (num_returned == 0)) {
4393 fprintf(stderr, "s.\n");
4394 goto defect_bailout;
4395 } else if (num_returned == 1)
4396 fprintf(stderr, ":\n");
4398 fprintf(stderr, "s:\n");
4404 * XXX KDM I should probably clean up the printout format for the
4407 switch (returned_type) {
4408 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4409 case SRDD10_EXT_PHYS_FORMAT:
4411 struct scsi_defect_desc_phys_sector *dlist;
4413 dlist = (struct scsi_defect_desc_phys_sector *)
4414 (defect_list + hdr_size);
4416 for (i = 0; i < num_valid; i++) {
4419 sector = scsi_4btoul(dlist[i].sector);
4420 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4421 mads = (sector & SDD_EXT_PHYS_MADS) ?
4423 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4425 if (hex_format == 0)
4426 fprintf(stdout, "%d:%d:%d%s",
4427 scsi_3btoul(dlist[i].cylinder),
4429 scsi_4btoul(dlist[i].sector),
4430 mads ? " - " : "\n");
4432 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4433 scsi_3btoul(dlist[i].cylinder),
4435 scsi_4btoul(dlist[i].sector),
4436 mads ? " - " : "\n");
4439 if (num_valid < num_returned) {
4440 starting_offset += num_valid;
4445 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4446 case SRDD10_EXT_BFI_FORMAT:
4448 struct scsi_defect_desc_bytes_from_index *dlist;
4450 dlist = (struct scsi_defect_desc_bytes_from_index *)
4451 (defect_list + hdr_size);
4453 for (i = 0; i < num_valid; i++) {
4456 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4457 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4458 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4459 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4461 if (hex_format == 0)
4462 fprintf(stdout, "%d:%d:%d%s",
4463 scsi_3btoul(dlist[i].cylinder),
4465 scsi_4btoul(dlist[i].bytes_from_index),
4466 mads ? " - " : "\n");
4468 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4469 scsi_3btoul(dlist[i].cylinder),
4471 scsi_4btoul(dlist[i].bytes_from_index),
4472 mads ? " - " : "\n");
4476 if (num_valid < num_returned) {
4477 starting_offset += num_valid;
4482 case SRDDH10_BLOCK_FORMAT:
4484 struct scsi_defect_desc_block *dlist;
4486 dlist = (struct scsi_defect_desc_block *)
4487 (defect_list + hdr_size);
4489 for (i = 0; i < num_valid; i++) {
4490 if (hex_format == 0)
4491 fprintf(stdout, "%u\n",
4492 scsi_4btoul(dlist[i].address));
4494 fprintf(stdout, "0x%x\n",
4495 scsi_4btoul(dlist[i].address));
4498 if (num_valid < num_returned) {
4499 starting_offset += num_valid;
4505 case SRDD10_LONG_BLOCK_FORMAT:
4507 struct scsi_defect_desc_long_block *dlist;
4509 dlist = (struct scsi_defect_desc_long_block *)
4510 (defect_list + hdr_size);
4512 for (i = 0; i < num_valid; i++) {
4513 if (hex_format == 0)
4514 fprintf(stdout, "%ju\n",
4515 (uintmax_t)scsi_8btou64(
4518 fprintf(stdout, "0x%jx\n",
4519 (uintmax_t)scsi_8btou64(
4523 if (num_valid < num_returned) {
4524 starting_offset += num_valid;
4530 fprintf(stderr, "Unknown defect format 0x%x\n",
4537 if (defect_list != NULL)
4548 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4552 ccb = cam_getccb(device);
4559 mode_sense(struct cam_device *device, int dbd, int pc, int page, int subpage,
4560 int task_attr, int retry_count, int timeout, u_int8_t *data,
4566 ccb = cam_getccb(device);
4569 errx(1, "mode_sense: couldn't allocate CCB");
4571 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4573 scsi_mode_sense_subpage(&ccb->csio,
4574 /* retries */ retry_count,
4576 /* tag_action */ task_attr,
4580 /* subpage */ subpage,
4581 /* param_buf */ data,
4582 /* param_len */ datalen,
4583 /* minimum_cmd_size */ 0,
4584 /* sense_len */ SSD_FULL_SIZE,
4585 /* timeout */ timeout ? timeout : 5000);
4587 if (arglist & CAM_ARG_ERR_RECOVER)
4588 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4590 /* Disable freezing the device queue */
4591 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4593 if (((retval = cam_send_ccb(device, ccb)) < 0)
4594 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4595 if (arglist & CAM_ARG_VERBOSE) {
4596 cam_error_print(device, ccb, CAM_ESF_ALL,
4597 CAM_EPF_ALL, stderr);
4600 cam_close_device(device);
4602 err(1, "error sending mode sense command");
4604 errx(1, "error sending mode sense command");
4611 mode_select(struct cam_device *device, int save_pages, int task_attr,
4612 int retry_count, int timeout, u_int8_t *data, int datalen)
4617 ccb = cam_getccb(device);
4620 errx(1, "mode_select: couldn't allocate CCB");
4622 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4624 scsi_mode_select(&ccb->csio,
4625 /* retries */ retry_count,
4627 /* tag_action */ task_attr,
4628 /* scsi_page_fmt */ 1,
4629 /* save_pages */ save_pages,
4630 /* param_buf */ data,
4631 /* param_len */ datalen,
4632 /* sense_len */ SSD_FULL_SIZE,
4633 /* timeout */ timeout ? timeout : 5000);
4635 if (arglist & CAM_ARG_ERR_RECOVER)
4636 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4638 /* Disable freezing the device queue */
4639 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4641 if (((retval = cam_send_ccb(device, ccb)) < 0)
4642 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4643 if (arglist & CAM_ARG_VERBOSE) {
4644 cam_error_print(device, ccb, CAM_ESF_ALL,
4645 CAM_EPF_ALL, stderr);
4648 cam_close_device(device);
4651 err(1, "error sending mode select command");
4653 errx(1, "error sending mode select command");
4661 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4662 int task_attr, int retry_count, int timeout)
4665 int c, page = -1, subpage = -1, pc = 0;
4666 int binary = 0, dbd = 0, edit = 0, list = 0;
4668 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4683 str_subpage = optarg;
4684 strsep(&str_subpage, ",");
4685 page = strtol(optarg, NULL, 0);
4687 subpage = strtol(str_subpage, NULL, 0);
4691 errx(1, "invalid mode page %d", page);
4693 errx(1, "invalid mode subpage %d", subpage);
4696 pc = strtol(optarg, NULL, 0);
4697 if ((pc < 0) || (pc > 3))
4698 errx(1, "invalid page control field %d", pc);
4705 if (page == -1 && list == 0)
4706 errx(1, "you must specify a mode page!");
4709 mode_list(device, dbd, pc, list > 1, task_attr, retry_count,
4712 mode_edit(device, dbd, pc, page, subpage, edit, binary,
4713 task_attr, retry_count, timeout);
4718 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4719 int task_attr, int retry_count, int timeout)
4722 u_int32_t flags = CAM_DIR_NONE;
4723 u_int8_t *data_ptr = NULL;
4725 u_int8_t atacmd[12];
4726 struct get_hook hook;
4727 int c, data_bytes = 0, valid_bytes;
4733 char *datastr = NULL, *tstr, *resstr = NULL;
4735 int fd_data = 0, fd_res = 0;
4738 ccb = cam_getccb(device);
4741 warnx("scsicmd: error allocating ccb");
4745 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4747 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4751 while (isspace(*tstr) && (*tstr != '\0'))
4753 hook.argc = argc - optind;
4754 hook.argv = argv + optind;
4756 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4759 * Increment optind by the number of arguments the
4760 * encoding routine processed. After each call to
4761 * getopt(3), optind points to the argument that
4762 * getopt should process _next_. In this case,
4763 * that means it points to the first command string
4764 * argument, if there is one. Once we increment
4765 * this, it should point to either the next command
4766 * line argument, or it should be past the end of
4773 while (isspace(*tstr) && (*tstr != '\0'))
4775 hook.argc = argc - optind;
4776 hook.argv = argv + optind;
4778 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4781 * Increment optind by the number of arguments the
4782 * encoding routine processed. After each call to
4783 * getopt(3), optind points to the argument that
4784 * getopt should process _next_. In this case,
4785 * that means it points to the first command string
4786 * argument, if there is one. Once we increment
4787 * this, it should point to either the next command
4788 * line argument, or it should be past the end of
4800 if (arglist & CAM_ARG_CMD_OUT) {
4801 warnx("command must either be "
4802 "read or write, not both");
4804 goto scsicmd_bailout;
4806 arglist |= CAM_ARG_CMD_IN;
4808 data_bytes = strtol(optarg, NULL, 0);
4809 if (data_bytes <= 0) {
4810 warnx("invalid number of input bytes %d",
4813 goto scsicmd_bailout;
4815 hook.argc = argc - optind;
4816 hook.argv = argv + optind;
4819 datastr = cget(&hook, NULL);
4821 * If the user supplied "-" instead of a format, he
4822 * wants the data to be written to stdout.
4824 if ((datastr != NULL)
4825 && (datastr[0] == '-'))
4828 data_ptr = (u_int8_t *)malloc(data_bytes);
4829 if (data_ptr == NULL) {
4830 warnx("can't malloc memory for data_ptr");
4832 goto scsicmd_bailout;
4836 if (arglist & CAM_ARG_CMD_IN) {
4837 warnx("command must either be "
4838 "read or write, not both");
4840 goto scsicmd_bailout;
4842 arglist |= CAM_ARG_CMD_OUT;
4843 flags = CAM_DIR_OUT;
4844 data_bytes = strtol(optarg, NULL, 0);
4845 if (data_bytes <= 0) {
4846 warnx("invalid number of output bytes %d",
4849 goto scsicmd_bailout;
4851 hook.argc = argc - optind;
4852 hook.argv = argv + optind;
4854 datastr = cget(&hook, NULL);
4855 data_ptr = (u_int8_t *)malloc(data_bytes);
4856 if (data_ptr == NULL) {
4857 warnx("can't malloc memory for data_ptr");
4859 goto scsicmd_bailout;
4861 bzero(data_ptr, data_bytes);
4863 * If the user supplied "-" instead of a format, he
4864 * wants the data to be read from stdin.
4866 if ((datastr != NULL)
4867 && (datastr[0] == '-'))
4870 buff_encode_visit(data_ptr, data_bytes, datastr,
4876 hook.argc = argc - optind;
4877 hook.argv = argv + optind;
4879 resstr = cget(&hook, NULL);
4880 if ((resstr != NULL) && (resstr[0] == '-'))
4890 * If fd_data is set, and we're writing to the device, we need to
4891 * read the data the user wants written from stdin.
4893 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4895 int amt_to_read = data_bytes;
4896 u_int8_t *buf_ptr = data_ptr;
4898 for (amt_read = 0; amt_to_read > 0;
4899 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4900 if (amt_read == -1) {
4901 warn("error reading data from stdin");
4903 goto scsicmd_bailout;
4905 amt_to_read -= amt_read;
4906 buf_ptr += amt_read;
4910 if (arglist & CAM_ARG_ERR_RECOVER)
4911 flags |= CAM_PASS_ERR_RECOVER;
4913 /* Disable freezing the device queue */
4914 flags |= CAM_DEV_QFRZDIS;
4918 * This is taken from the SCSI-3 draft spec.
4919 * (T10/1157D revision 0.3)
4920 * The top 3 bits of an opcode are the group code.
4921 * The next 5 bits are the command code.
4922 * Group 0: six byte commands
4923 * Group 1: ten byte commands
4924 * Group 2: ten byte commands
4926 * Group 4: sixteen byte commands
4927 * Group 5: twelve byte commands
4928 * Group 6: vendor specific
4929 * Group 7: vendor specific
4931 switch((cdb[0] >> 5) & 0x7) {
4942 /* computed by buff_encode_visit */
4953 * We should probably use csio_build_visit or something like that
4954 * here, but it's easier to encode arguments as you go. The
4955 * alternative would be skipping the CDB argument and then encoding
4956 * it here, since we've got the data buffer argument by now.
4958 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4960 cam_fill_csio(&ccb->csio,
4961 /*retries*/ retry_count,
4964 /*tag_action*/ task_attr,
4965 /*data_ptr*/ data_ptr,
4966 /*dxfer_len*/ data_bytes,
4967 /*sense_len*/ SSD_FULL_SIZE,
4968 /*cdb_len*/ cdb_len,
4969 /*timeout*/ timeout ? timeout : 5000);
4972 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4974 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4976 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4978 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4980 cam_fill_ataio(&ccb->ataio,
4981 /*retries*/ retry_count,
4985 /*data_ptr*/ data_ptr,
4986 /*dxfer_len*/ data_bytes,
4987 /*timeout*/ timeout ? timeout : 5000);
4990 if (((retval = cam_send_ccb(device, ccb)) < 0)
4991 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4992 const char warnstr[] = "error sending command";
4999 if (arglist & CAM_ARG_VERBOSE) {
5000 cam_error_print(device, ccb, CAM_ESF_ALL,
5001 CAM_EPF_ALL, stderr);
5005 goto scsicmd_bailout;
5008 if (atacmd_len && need_res) {
5010 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
5012 fprintf(stdout, "\n");
5015 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
5016 ccb->ataio.res.status,
5017 ccb->ataio.res.error,
5018 ccb->ataio.res.lba_low,
5019 ccb->ataio.res.lba_mid,
5020 ccb->ataio.res.lba_high,
5021 ccb->ataio.res.device,
5022 ccb->ataio.res.lba_low_exp,
5023 ccb->ataio.res.lba_mid_exp,
5024 ccb->ataio.res.lba_high_exp,
5025 ccb->ataio.res.sector_count,
5026 ccb->ataio.res.sector_count_exp);
5032 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
5034 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
5035 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
5036 && (arglist & CAM_ARG_CMD_IN)
5037 && (valid_bytes > 0)) {
5039 buff_decode_visit(data_ptr, valid_bytes, datastr,
5041 fprintf(stdout, "\n");
5043 ssize_t amt_written;
5044 int amt_to_write = valid_bytes;
5045 u_int8_t *buf_ptr = data_ptr;
5047 for (amt_written = 0; (amt_to_write > 0) &&
5048 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
5049 amt_to_write -= amt_written;
5050 buf_ptr += amt_written;
5052 if (amt_written == -1) {
5053 warn("error writing data to stdout");
5055 goto scsicmd_bailout;
5056 } else if ((amt_written == 0)
5057 && (amt_to_write > 0)) {
5058 warnx("only wrote %u bytes out of %u",
5059 valid_bytes - amt_to_write, valid_bytes);
5066 if ((data_bytes > 0) && (data_ptr != NULL))
5075 camdebug(int argc, char **argv, char *combinedopt)
5078 path_id_t bus = CAM_BUS_WILDCARD;
5079 target_id_t target = CAM_TARGET_WILDCARD;
5080 lun_id_t lun = CAM_LUN_WILDCARD;
5081 char *tstr, *tmpstr = NULL;
5085 bzero(&ccb, sizeof(union ccb));
5087 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5090 arglist |= CAM_ARG_DEBUG_INFO;
5091 ccb.cdbg.flags |= CAM_DEBUG_INFO;
5094 arglist |= CAM_ARG_DEBUG_PERIPH;
5095 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
5098 arglist |= CAM_ARG_DEBUG_SUBTRACE;
5099 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
5102 arglist |= CAM_ARG_DEBUG_TRACE;
5103 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
5106 arglist |= CAM_ARG_DEBUG_XPT;
5107 ccb.cdbg.flags |= CAM_DEBUG_XPT;
5110 arglist |= CAM_ARG_DEBUG_CDB;
5111 ccb.cdbg.flags |= CAM_DEBUG_CDB;
5114 arglist |= CAM_ARG_DEBUG_PROBE;
5115 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
5122 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
5123 warnx("error opening transport layer device %s", XPT_DEVICE);
5124 warn("%s", XPT_DEVICE);
5131 warnx("you must specify \"off\", \"all\" or a bus,");
5132 warnx("bus:target, or bus:target:lun");
5139 while (isspace(*tstr) && (*tstr != '\0'))
5142 if (strncmp(tstr, "off", 3) == 0) {
5143 ccb.cdbg.flags = CAM_DEBUG_NONE;
5144 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
5145 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
5146 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
5147 } else if (strncmp(tstr, "all", 3) != 0) {
5148 tmpstr = (char *)strtok(tstr, ":");
5149 if ((tmpstr != NULL) && (*tmpstr != '\0')){
5150 bus = strtol(tmpstr, NULL, 0);
5151 arglist |= CAM_ARG_BUS;
5152 tmpstr = (char *)strtok(NULL, ":");
5153 if ((tmpstr != NULL) && (*tmpstr != '\0')){
5154 target = strtol(tmpstr, NULL, 0);
5155 arglist |= CAM_ARG_TARGET;
5156 tmpstr = (char *)strtok(NULL, ":");
5157 if ((tmpstr != NULL) && (*tmpstr != '\0')){
5158 lun = strtol(tmpstr, NULL, 0);
5159 arglist |= CAM_ARG_LUN;
5164 warnx("you must specify \"all\", \"off\", or a bus,");
5165 warnx("bus:target, or bus:target:lun to debug");
5171 ccb.ccb_h.func_code = XPT_DEBUG;
5172 ccb.ccb_h.path_id = bus;
5173 ccb.ccb_h.target_id = target;
5174 ccb.ccb_h.target_lun = lun;
5176 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
5177 warn("CAMIOCOMMAND ioctl failed");
5182 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
5183 CAM_FUNC_NOTAVAIL) {
5184 warnx("CAM debugging not available");
5185 warnx("you need to put options CAMDEBUG in"
5186 " your kernel config file!");
5188 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
5190 warnx("XPT_DEBUG CCB failed with status %#x",
5194 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
5196 "Debugging turned off\n");
5199 "Debugging enabled for "
5201 bus, target, (uintmax_t)lun);
5212 tagcontrol(struct cam_device *device, int argc, char **argv,
5222 ccb = cam_getccb(device);
5225 warnx("tagcontrol: error allocating ccb");
5229 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5232 numtags = strtol(optarg, NULL, 0);
5234 warnx("tag count %d is < 0", numtags);
5236 goto tagcontrol_bailout;
5247 cam_path_string(device, pathstr, sizeof(pathstr));
5250 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
5251 ccb->ccb_h.func_code = XPT_REL_SIMQ;
5252 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5253 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5254 ccb->crs.openings = numtags;
5257 if (cam_send_ccb(device, ccb) < 0) {
5258 perror("error sending XPT_REL_SIMQ CCB");
5260 goto tagcontrol_bailout;
5263 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5264 warnx("XPT_REL_SIMQ CCB failed");
5265 cam_error_print(device, ccb, CAM_ESF_ALL,
5266 CAM_EPF_ALL, stderr);
5268 goto tagcontrol_bailout;
5273 fprintf(stdout, "%stagged openings now %d\n",
5274 pathstr, ccb->crs.openings);
5277 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5279 ccb->ccb_h.func_code = XPT_GDEV_STATS;
5281 if (cam_send_ccb(device, ccb) < 0) {
5282 perror("error sending XPT_GDEV_STATS CCB");
5284 goto tagcontrol_bailout;
5287 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5288 warnx("XPT_GDEV_STATS CCB failed");
5289 cam_error_print(device, ccb, CAM_ESF_ALL,
5290 CAM_EPF_ALL, stderr);
5292 goto tagcontrol_bailout;
5295 if (arglist & CAM_ARG_VERBOSE) {
5296 fprintf(stdout, "%s", pathstr);
5297 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5298 fprintf(stdout, "%s", pathstr);
5299 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5300 fprintf(stdout, "%s", pathstr);
5301 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5302 fprintf(stdout, "%s", pathstr);
5303 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5304 fprintf(stdout, "%s", pathstr);
5305 fprintf(stdout, "held %d\n", ccb->cgds.held);
5306 fprintf(stdout, "%s", pathstr);
5307 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5308 fprintf(stdout, "%s", pathstr);
5309 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5312 fprintf(stdout, "%s", pathstr);
5313 fprintf(stdout, "device openings: ");
5315 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5316 ccb->cgds.dev_active);
5326 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5330 cam_path_string(device, pathstr, sizeof(pathstr));
5332 if (cts->transport == XPORT_SPI) {
5333 struct ccb_trans_settings_spi *spi =
5334 &cts->xport_specific.spi;
5336 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5338 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5341 if (spi->sync_offset != 0) {
5344 freq = scsi_calc_syncsrate(spi->sync_period);
5345 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5346 pathstr, freq / 1000, freq % 1000);
5350 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5351 fprintf(stdout, "%soffset: %d\n", pathstr,
5355 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5356 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5357 (0x01 << spi->bus_width) * 8);
5360 if (spi->valid & CTS_SPI_VALID_DISC) {
5361 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5362 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5363 "enabled" : "disabled");
5366 if (cts->transport == XPORT_FC) {
5367 struct ccb_trans_settings_fc *fc =
5368 &cts->xport_specific.fc;
5370 if (fc->valid & CTS_FC_VALID_WWNN)
5371 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5372 (long long) fc->wwnn);
5373 if (fc->valid & CTS_FC_VALID_WWPN)
5374 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5375 (long long) fc->wwpn);
5376 if (fc->valid & CTS_FC_VALID_PORT)
5377 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5378 if (fc->valid & CTS_FC_VALID_SPEED)
5379 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5380 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5382 if (cts->transport == XPORT_SAS) {
5383 struct ccb_trans_settings_sas *sas =
5384 &cts->xport_specific.sas;
5386 if (sas->valid & CTS_SAS_VALID_SPEED)
5387 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5388 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5390 if (cts->transport == XPORT_ATA) {
5391 struct ccb_trans_settings_pata *pata =
5392 &cts->xport_specific.ata;
5394 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5395 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5396 ata_mode2string(pata->mode));
5398 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5399 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5402 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5403 fprintf(stdout, "%sPIO transaction length: %d\n",
5404 pathstr, pata->bytecount);
5407 if (cts->transport == XPORT_SATA) {
5408 struct ccb_trans_settings_sata *sata =
5409 &cts->xport_specific.sata;
5411 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5412 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5415 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5416 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5417 ata_mode2string(sata->mode));
5419 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5420 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5423 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5424 fprintf(stdout, "%sPIO transaction length: %d\n",
5425 pathstr, sata->bytecount);
5427 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5428 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5431 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5432 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5435 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5436 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5440 if (cts->protocol == PROTO_ATA) {
5441 struct ccb_trans_settings_ata *ata=
5442 &cts->proto_specific.ata;
5444 if (ata->valid & CTS_ATA_VALID_TQ) {
5445 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5446 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5447 "enabled" : "disabled");
5450 if (cts->protocol == PROTO_SCSI) {
5451 struct ccb_trans_settings_scsi *scsi=
5452 &cts->proto_specific.scsi;
5454 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5455 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5456 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5457 "enabled" : "disabled");
5461 if (cts->protocol == PROTO_NVME) {
5462 struct ccb_trans_settings_nvme *nvmex =
5463 &cts->xport_specific.nvme;
5465 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5466 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5467 NVME_MAJOR(nvmex->spec),
5468 NVME_MINOR(nvmex->spec));
5470 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5471 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5472 nvmex->lanes, nvmex->max_lanes);
5473 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5474 nvmex->speed, nvmex->max_speed);
5481 * Get a path inquiry CCB for the specified device.
5484 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5489 ccb = cam_getccb(device);
5491 warnx("get_cpi: couldn't allocate CCB");
5494 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5495 ccb->ccb_h.func_code = XPT_PATH_INQ;
5496 if (cam_send_ccb(device, ccb) < 0) {
5497 warn("get_cpi: error sending Path Inquiry CCB");
5498 if (arglist & CAM_ARG_VERBOSE)
5499 cam_error_print(device, ccb, CAM_ESF_ALL,
5500 CAM_EPF_ALL, stderr);
5502 goto get_cpi_bailout;
5504 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5505 if (arglist & CAM_ARG_VERBOSE)
5506 cam_error_print(device, ccb, CAM_ESF_ALL,
5507 CAM_EPF_ALL, stderr);
5509 goto get_cpi_bailout;
5511 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5519 * Get a get device CCB for the specified device.
5522 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5527 ccb = cam_getccb(device);
5529 warnx("get_cgd: couldn't allocate CCB");
5532 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5533 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5534 if (cam_send_ccb(device, ccb) < 0) {
5535 warn("get_cgd: error sending Path Inquiry CCB");
5536 if (arglist & CAM_ARG_VERBOSE)
5537 cam_error_print(device, ccb, CAM_ESF_ALL,
5538 CAM_EPF_ALL, stderr);
5540 goto get_cgd_bailout;
5542 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5543 if (arglist & CAM_ARG_VERBOSE)
5544 cam_error_print(device, ccb, CAM_ESF_ALL,
5545 CAM_EPF_ALL, stderr);
5547 goto get_cgd_bailout;
5549 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5557 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5561 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5562 int timeout, int verbosemode)
5564 union ccb *ccb = NULL;
5565 struct scsi_vpd_supported_page_list sup_pages;
5569 ccb = cam_getccb(dev);
5571 warn("Unable to allocate CCB");
5576 /* cam_getccb cleans up the header, caller has to zero the payload */
5577 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5579 bzero(&sup_pages, sizeof(sup_pages));
5581 scsi_inquiry(&ccb->csio,
5582 /*retries*/ retry_count,
5584 /* tag_action */ MSG_SIMPLE_Q_TAG,
5585 /* inq_buf */ (u_int8_t *)&sup_pages,
5586 /* inq_len */ sizeof(sup_pages),
5588 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5589 /* sense_len */ SSD_FULL_SIZE,
5590 /* timeout */ timeout ? timeout : 5000);
5592 /* Disable freezing the device queue */
5593 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5595 if (retry_count != 0)
5596 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5598 if (cam_send_ccb(dev, ccb) < 0) {
5605 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5606 if (verbosemode != 0)
5607 cam_error_print(dev, ccb, CAM_ESF_ALL,
5608 CAM_EPF_ALL, stderr);
5613 for (i = 0; i < sup_pages.length; i++) {
5614 if (sup_pages.list[i] == page_id) {
5627 * devtype is filled in with the type of device.
5628 * Returns 0 for success, non-zero for failure.
5631 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5632 int verbosemode, camcontrol_devtype *devtype)
5634 struct ccb_getdev cgd;
5637 retval = get_cgd(dev, &cgd);
5641 switch (cgd.protocol) {
5647 *devtype = CC_DT_ATA;
5649 break; /*NOTREACHED*/
5651 *devtype = CC_DT_NVME;
5653 break; /*NOTREACHED*/
5655 *devtype = CC_DT_MMCSD;
5657 break; /*NOTREACHED*/
5659 *devtype = CC_DT_UNKNOWN;
5661 break; /*NOTREACHED*/
5664 if (retry_count == -1) {
5666 * For a retry count of -1, used only the cached data to avoid
5667 * I/O to the drive. Sending the identify command to the drive
5668 * can cause issues for SATL attachaed drives since identify is
5669 * not an NCQ command.
5671 if (cgd.ident_data.config != 0)
5672 *devtype = CC_DT_SATL;
5674 *devtype = CC_DT_SCSI;
5677 * Check for the ATA Information VPD page (0x89). If this is an
5678 * ATA device behind a SCSI to ATA translation layer (SATL),
5679 * this VPD page should be present.
5681 * If that VPD page isn't present, or we get an error back from
5682 * the INQUIRY command, we'll just treat it as a normal SCSI
5685 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5686 timeout, verbosemode);
5688 *devtype = CC_DT_SATL;
5690 *devtype = CC_DT_SCSI;
5699 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5700 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5701 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5702 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5703 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5704 int is48bit, camcontrol_devtype devtype)
5708 if (devtype == CC_DT_ATA) {
5709 cam_fill_ataio(&ccb->ataio,
5710 /*retries*/ retry_count,
5713 /*tag_action*/ tag_action,
5714 /*data_ptr*/ data_ptr,
5715 /*dxfer_len*/ dxfer_len,
5716 /*timeout*/ timeout);
5717 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5718 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5721 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5724 if (auxiliary != 0) {
5725 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5726 ccb->ataio.aux = auxiliary;
5729 if (ata_flags & AP_FLAG_CHK_COND)
5730 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5732 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5733 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5734 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5735 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5737 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5738 protocol |= AP_EXTEND;
5740 retval = scsi_ata_pass(&ccb->csio,
5741 /*retries*/ retry_count,
5744 /*tag_action*/ tag_action,
5745 /*protocol*/ protocol,
5746 /*ata_flags*/ ata_flags,
5747 /*features*/ features,
5748 /*sector_count*/ sector_count,
5750 /*command*/ command,
5753 /*auxiliary*/ auxiliary,
5755 /*data_ptr*/ data_ptr,
5756 /*dxfer_len*/ dxfer_len,
5757 /*cdb_storage*/ cdb_storage,
5758 /*cdb_storage_len*/ cdb_storage_len,
5759 /*minimum_cmd_size*/ 0,
5760 /*sense_len*/ sense_len,
5761 /*timeout*/ timeout);
5768 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5769 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5773 switch (ccb->ccb_h.func_code) {
5776 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5779 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5780 * or 16 byte, and need to see what
5782 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5783 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5785 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5786 if ((opcode != ATA_PASS_12)
5787 && (opcode != ATA_PASS_16)) {
5789 warnx("%s: unsupported opcode %02x", __func__, opcode);
5793 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5795 /* Note: the _ccb() variant returns 0 for an error */
5802 switch (error_code) {
5803 case SSD_DESC_CURRENT_ERROR:
5804 case SSD_DESC_DEFERRED_ERROR: {
5805 struct scsi_sense_data_desc *sense;
5806 struct scsi_sense_ata_ret_desc *desc;
5809 sense = (struct scsi_sense_data_desc *)
5810 &ccb->csio.sense_data;
5812 desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len -
5813 ccb->csio.sense_resid, SSD_DESC_ATA);
5814 if (desc_ptr == NULL) {
5815 cam_error_print(dev, ccb, CAM_ESF_ALL,
5816 CAM_EPF_ALL, stderr);
5820 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5822 *error = desc->error;
5823 *count = (desc->count_15_8 << 8) |
5825 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5826 ((uint64_t)desc->lba_39_32 << 32) |
5827 ((uint64_t)desc->lba_31_24 << 24) |
5828 (desc->lba_23_16 << 16) |
5829 (desc->lba_15_8 << 8) |
5831 *device = desc->device;
5832 *status = desc->status;
5835 * If the extend bit isn't set, the result is for a
5836 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5837 * command without the extend bit set. This means
5838 * that the device is supposed to return 28-bit
5839 * status. The count field is only 8 bits, and the
5840 * LBA field is only 8 bits.
5842 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5848 case SSD_CURRENT_ERROR:
5849 case SSD_DEFERRED_ERROR: {
5851 struct scsi_sense_data_fixed *sense;
5854 * XXX KDM need to support fixed sense data.
5856 warnx("%s: Fixed sense data not supported yet",
5860 break; /*NOTREACHED*/
5871 struct ata_res *res;
5874 * In this case, we have an ATA command, and we need to
5875 * fill in the requested values from the result register
5878 res = &ccb->ataio.res;
5879 *error = res->error;
5880 *status = res->status;
5881 *device = res->device;
5882 *count = res->sector_count;
5883 *lba = (res->lba_high << 16) |
5884 (res->lba_mid << 8) |
5886 if (res->flags & CAM_ATAIO_48BIT) {
5887 *count |= (res->sector_count_exp << 8);
5888 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5889 ((uint64_t)res->lba_mid_exp << 32) |
5890 ((uint64_t)res->lba_high_exp << 40);
5892 *lba |= (res->device & 0xf) << 24;
5905 cpi_print(struct ccb_pathinq *cpi)
5907 char adapter_str[1024];
5910 snprintf(adapter_str, sizeof(adapter_str),
5911 "%s%d:", cpi->dev_name, cpi->unit_number);
5913 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5916 for (i = 1; i < UINT8_MAX; i = i << 1) {
5919 if ((i & cpi->hba_inquiry) == 0)
5922 fprintf(stdout, "%s supports ", adapter_str);
5926 str = "MDP message";
5929 str = "32 bit wide SCSI";
5932 str = "16 bit wide SCSI";
5935 str = "SDTR message";
5938 str = "linked CDBs";
5941 str = "tag queue messages";
5944 str = "soft reset alternative";
5947 str = "SATA Port Multiplier";
5950 str = "unknown PI bit set";
5953 fprintf(stdout, "%s\n", str);
5956 for (i = 1; i < UINT32_MAX; i = i << 1) {
5959 if ((i & cpi->hba_misc) == 0)
5962 fprintf(stdout, "%s ", adapter_str);
5966 str = "can understand ata_ext requests";
5969 str = "64bit extended LUNs supported";
5972 str = "bus scans from high ID to low ID";
5975 str = "removable devices not included in scan";
5977 case PIM_NOINITIATOR:
5978 str = "initiator role not supported";
5980 case PIM_NOBUSRESET:
5981 str = "user has disabled initial BUS RESET or"
5982 " controller is in target/mixed mode";
5985 str = "do not send 6-byte commands";
5988 str = "scan bus sequentially";
5991 str = "unmapped I/O supported";
5994 str = "does its own scanning";
5997 str = "unknown PIM bit set";
6000 fprintf(stdout, "%s\n", str);
6003 for (i = 1; i < UINT16_MAX; i = i << 1) {
6006 if ((i & cpi->target_sprt) == 0)
6009 fprintf(stdout, "%s supports ", adapter_str);
6012 str = "target mode processor mode";
6015 str = "target mode phase cog. mode";
6017 case PIT_DISCONNECT:
6018 str = "disconnects in target mode";
6021 str = "terminate I/O message in target mode";
6024 str = "group 6 commands in target mode";
6027 str = "group 7 commands in target mode";
6030 str = "unknown PIT bit set";
6034 fprintf(stdout, "%s\n", str);
6036 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
6038 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
6040 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
6042 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
6043 adapter_str, cpi->hpath_id);
6044 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
6046 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
6047 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
6048 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
6049 adapter_str, cpi->hba_vendor);
6050 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
6051 adapter_str, cpi->hba_device);
6052 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
6053 adapter_str, cpi->hba_subvendor);
6054 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
6055 adapter_str, cpi->hba_subdevice);
6056 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
6057 fprintf(stdout, "%s base transfer speed: ", adapter_str);
6058 if (cpi->base_transfer_speed > 1000)
6059 fprintf(stdout, "%d.%03dMB/sec\n",
6060 cpi->base_transfer_speed / 1000,
6061 cpi->base_transfer_speed % 1000);
6063 fprintf(stdout, "%dKB/sec\n",
6064 (cpi->base_transfer_speed % 1000) * 1000);
6065 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
6066 adapter_str, cpi->maxio);
6070 get_print_cts(struct cam_device *device, int user_settings, int quiet,
6071 struct ccb_trans_settings *cts)
6077 ccb = cam_getccb(device);
6080 warnx("get_print_cts: error allocating ccb");
6084 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
6086 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
6088 if (user_settings == 0)
6089 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
6091 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
6093 if (cam_send_ccb(device, ccb) < 0) {
6094 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
6095 if (arglist & CAM_ARG_VERBOSE)
6096 cam_error_print(device, ccb, CAM_ESF_ALL,
6097 CAM_EPF_ALL, stderr);
6099 goto get_print_cts_bailout;
6102 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6103 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
6104 if (arglist & CAM_ARG_VERBOSE)
6105 cam_error_print(device, ccb, CAM_ESF_ALL,
6106 CAM_EPF_ALL, stderr);
6108 goto get_print_cts_bailout;
6112 cts_print(device, &ccb->cts);
6115 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
6117 get_print_cts_bailout:
6125 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
6126 int timeout, int argc, char **argv, char *combinedopt)
6130 int user_settings = 0;
6132 int disc_enable = -1, tag_enable = -1;
6135 double syncrate = -1;
6138 int change_settings = 0, send_tur = 0;
6139 struct ccb_pathinq cpi;
6141 ccb = cam_getccb(device);
6143 warnx("ratecontrol: error allocating ccb");
6146 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6155 if (strncasecmp(optarg, "enable", 6) == 0)
6157 else if (strncasecmp(optarg, "disable", 7) == 0)
6160 warnx("-D argument \"%s\" is unknown", optarg);
6162 goto ratecontrol_bailout;
6164 change_settings = 1;
6167 mode = ata_string2mode(optarg);
6169 warnx("unknown mode '%s'", optarg);
6171 goto ratecontrol_bailout;
6173 change_settings = 1;
6176 offset = strtol(optarg, NULL, 0);
6178 warnx("offset value %d is < 0", offset);
6180 goto ratecontrol_bailout;
6182 change_settings = 1;
6188 syncrate = atof(optarg);
6190 warnx("sync rate %f is < 0", syncrate);
6192 goto ratecontrol_bailout;
6194 change_settings = 1;
6197 if (strncasecmp(optarg, "enable", 6) == 0)
6199 else if (strncasecmp(optarg, "disable", 7) == 0)
6202 warnx("-T argument \"%s\" is unknown", optarg);
6204 goto ratecontrol_bailout;
6206 change_settings = 1;
6212 bus_width = strtol(optarg, NULL, 0);
6213 if (bus_width < 0) {
6214 warnx("bus width %d is < 0", bus_width);
6216 goto ratecontrol_bailout;
6218 change_settings = 1;
6224 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
6226 * Grab path inquiry information, so we can determine whether
6227 * or not the initiator is capable of the things that the user
6230 ccb->ccb_h.func_code = XPT_PATH_INQ;
6231 if (cam_send_ccb(device, ccb) < 0) {
6232 perror("error sending XPT_PATH_INQ CCB");
6233 if (arglist & CAM_ARG_VERBOSE) {
6234 cam_error_print(device, ccb, CAM_ESF_ALL,
6235 CAM_EPF_ALL, stderr);
6238 goto ratecontrol_bailout;
6240 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6241 warnx("XPT_PATH_INQ CCB failed");
6242 if (arglist & CAM_ARG_VERBOSE) {
6243 cam_error_print(device, ccb, CAM_ESF_ALL,
6244 CAM_EPF_ALL, stderr);
6247 goto ratecontrol_bailout;
6249 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
6250 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
6252 fprintf(stdout, "%s parameters:\n",
6253 user_settings ? "User" : "Current");
6255 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
6257 goto ratecontrol_bailout;
6259 if (arglist & CAM_ARG_VERBOSE)
6262 if (change_settings) {
6263 int didsettings = 0;
6264 struct ccb_trans_settings_spi *spi = NULL;
6265 struct ccb_trans_settings_pata *pata = NULL;
6266 struct ccb_trans_settings_sata *sata = NULL;
6267 struct ccb_trans_settings_ata *ata = NULL;
6268 struct ccb_trans_settings_scsi *scsi = NULL;
6270 if (ccb->cts.transport == XPORT_SPI)
6271 spi = &ccb->cts.xport_specific.spi;
6272 if (ccb->cts.transport == XPORT_ATA)
6273 pata = &ccb->cts.xport_specific.ata;
6274 if (ccb->cts.transport == XPORT_SATA)
6275 sata = &ccb->cts.xport_specific.sata;
6276 if (ccb->cts.protocol == PROTO_ATA)
6277 ata = &ccb->cts.proto_specific.ata;
6278 if (ccb->cts.protocol == PROTO_SCSI)
6279 scsi = &ccb->cts.proto_specific.scsi;
6280 ccb->cts.xport_specific.valid = 0;
6281 ccb->cts.proto_specific.valid = 0;
6282 if (spi && disc_enable != -1) {
6283 spi->valid |= CTS_SPI_VALID_DISC;
6284 if (disc_enable == 0)
6285 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6287 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6290 if (tag_enable != -1) {
6291 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6292 warnx("HBA does not support tagged queueing, "
6293 "so you cannot modify tag settings");
6295 goto ratecontrol_bailout;
6298 ata->valid |= CTS_SCSI_VALID_TQ;
6299 if (tag_enable == 0)
6300 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6302 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6305 scsi->valid |= CTS_SCSI_VALID_TQ;
6306 if (tag_enable == 0)
6307 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6309 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6313 if (spi && offset != -1) {
6314 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6315 warnx("HBA is not capable of changing offset");
6317 goto ratecontrol_bailout;
6319 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6320 spi->sync_offset = offset;
6323 if (spi && syncrate != -1) {
6324 int prelim_sync_period;
6326 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6327 warnx("HBA is not capable of changing "
6330 goto ratecontrol_bailout;
6332 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6334 * The sync rate the user gives us is in MHz.
6335 * We need to translate it into KHz for this
6340 * Next, we calculate a "preliminary" sync period
6341 * in tenths of a nanosecond.
6344 prelim_sync_period = 0;
6346 prelim_sync_period = 10000000 / syncrate;
6348 scsi_calc_syncparam(prelim_sync_period);
6351 if (sata && syncrate != -1) {
6352 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6353 warnx("HBA is not capable of changing "
6356 goto ratecontrol_bailout;
6358 if (!user_settings) {
6359 warnx("You can modify only user rate "
6360 "settings for SATA");
6362 goto ratecontrol_bailout;
6364 sata->revision = ata_speed2revision(syncrate * 100);
6365 if (sata->revision < 0) {
6366 warnx("Invalid rate %f", syncrate);
6368 goto ratecontrol_bailout;
6370 sata->valid |= CTS_SATA_VALID_REVISION;
6373 if ((pata || sata) && mode != -1) {
6374 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6375 warnx("HBA is not capable of changing "
6378 goto ratecontrol_bailout;
6380 if (!user_settings) {
6381 warnx("You can modify only user mode "
6382 "settings for ATA/SATA");
6384 goto ratecontrol_bailout;
6388 pata->valid |= CTS_ATA_VALID_MODE;
6391 sata->valid |= CTS_SATA_VALID_MODE;
6396 * The bus_width argument goes like this:
6400 * Therefore, if you shift the number of bits given on the
6401 * command line right by 4, you should get the correct
6404 if (spi && bus_width != -1) {
6406 * We might as well validate things here with a
6407 * decipherable error message, rather than what
6408 * will probably be an indecipherable error message
6409 * by the time it gets back to us.
6411 if ((bus_width == 16)
6412 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6413 warnx("HBA does not support 16 bit bus width");
6415 goto ratecontrol_bailout;
6416 } else if ((bus_width == 32)
6417 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6418 warnx("HBA does not support 32 bit bus width");
6420 goto ratecontrol_bailout;
6421 } else if ((bus_width != 8)
6422 && (bus_width != 16)
6423 && (bus_width != 32)) {
6424 warnx("Invalid bus width %d", bus_width);
6426 goto ratecontrol_bailout;
6428 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6429 spi->bus_width = bus_width >> 4;
6432 if (didsettings == 0) {
6433 goto ratecontrol_bailout;
6435 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6436 if (cam_send_ccb(device, ccb) < 0) {
6437 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
6438 if (arglist & CAM_ARG_VERBOSE) {
6439 cam_error_print(device, ccb, CAM_ESF_ALL,
6440 CAM_EPF_ALL, stderr);
6443 goto ratecontrol_bailout;
6445 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6446 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6447 if (arglist & CAM_ARG_VERBOSE) {
6448 cam_error_print(device, ccb, CAM_ESF_ALL,
6449 CAM_EPF_ALL, stderr);
6452 goto ratecontrol_bailout;
6456 retval = testunitready(device, task_attr, retry_count, timeout,
6457 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6459 * If the TUR didn't succeed, just bail.
6463 fprintf(stderr, "Test Unit Ready failed\n");
6464 goto ratecontrol_bailout;
6467 if ((change_settings || send_tur) && !quiet &&
6468 (ccb->cts.transport == XPORT_ATA ||
6469 ccb->cts.transport == XPORT_SATA || send_tur)) {
6470 fprintf(stdout, "New parameters:\n");
6471 retval = get_print_cts(device, user_settings, 0, NULL);
6474 ratecontrol_bailout:
6480 scsiformat(struct cam_device *device, int argc, char **argv,
6481 char *combinedopt, int task_attr, int retry_count, int timeout)
6485 int ycount = 0, quiet = 0;
6486 int error = 0, retval = 0;
6487 int use_timeout = 10800 * 1000;
6489 struct format_defect_list_header fh;
6490 u_int8_t *data_ptr = NULL;
6491 u_int32_t dxfer_len = 0;
6493 int num_warnings = 0;
6496 ccb = cam_getccb(device);
6499 warnx("scsiformat: error allocating ccb");
6503 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6505 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6526 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6527 "following device:\n");
6529 error = scsidoinquiry(device, argc, argv, combinedopt,
6530 task_attr, retry_count, timeout);
6533 warnx("scsiformat: error sending inquiry");
6534 goto scsiformat_bailout;
6539 if (!get_confirmation()) {
6541 goto scsiformat_bailout;
6546 use_timeout = timeout;
6549 fprintf(stdout, "Current format timeout is %d seconds\n",
6550 use_timeout / 1000);
6554 * If the user hasn't disabled questions and didn't specify a
6555 * timeout on the command line, ask them if they want the current
6559 && (timeout == 0)) {
6561 int new_timeout = 0;
6563 fprintf(stdout, "Enter new timeout in seconds or press\n"
6564 "return to keep the current timeout [%d] ",
6565 use_timeout / 1000);
6567 if (fgets(str, sizeof(str), stdin) != NULL) {
6569 new_timeout = atoi(str);
6572 if (new_timeout != 0) {
6573 use_timeout = new_timeout * 1000;
6574 fprintf(stdout, "Using new timeout value %d\n",
6575 use_timeout / 1000);
6580 * Keep this outside the if block below to silence any unused
6581 * variable warnings.
6583 bzero(&fh, sizeof(fh));
6586 * If we're in immediate mode, we've got to include the format
6589 if (immediate != 0) {
6590 fh.byte2 = FU_DLH_IMMED;
6591 data_ptr = (u_int8_t *)&fh;
6592 dxfer_len = sizeof(fh);
6593 byte2 = FU_FMT_DATA;
6594 } else if (quiet == 0) {
6595 fprintf(stdout, "Formatting...");
6599 scsi_format_unit(&ccb->csio,
6600 /* retries */ retry_count,
6602 /* tag_action */ task_attr,
6605 /* data_ptr */ data_ptr,
6606 /* dxfer_len */ dxfer_len,
6607 /* sense_len */ SSD_FULL_SIZE,
6608 /* timeout */ use_timeout);
6610 /* Disable freezing the device queue */
6611 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6613 if (arglist & CAM_ARG_ERR_RECOVER)
6614 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6616 if (((retval = cam_send_ccb(device, ccb)) < 0)
6617 || ((immediate == 0)
6618 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6619 const char errstr[] = "error sending format command";
6626 if (arglist & CAM_ARG_VERBOSE) {
6627 cam_error_print(device, ccb, CAM_ESF_ALL,
6628 CAM_EPF_ALL, stderr);
6631 goto scsiformat_bailout;
6635 * If we ran in non-immediate mode, we already checked for errors
6636 * above and printed out any necessary information. If we're in
6637 * immediate mode, we need to loop through and get status
6638 * information periodically.
6640 if (immediate == 0) {
6642 fprintf(stdout, "Format Complete\n");
6644 goto scsiformat_bailout;
6651 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6654 * There's really no need to do error recovery or
6655 * retries here, since we're just going to sit in a
6656 * loop and wait for the device to finish formatting.
6658 scsi_test_unit_ready(&ccb->csio,
6661 /* tag_action */ task_attr,
6662 /* sense_len */ SSD_FULL_SIZE,
6663 /* timeout */ 5000);
6665 /* Disable freezing the device queue */
6666 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6668 retval = cam_send_ccb(device, ccb);
6671 * If we get an error from the ioctl, bail out. SCSI
6672 * errors are expected.
6675 warn("error sending CAMIOCOMMAND ioctl");
6676 if (arglist & CAM_ARG_VERBOSE) {
6677 cam_error_print(device, ccb, CAM_ESF_ALL,
6678 CAM_EPF_ALL, stderr);
6681 goto scsiformat_bailout;
6684 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6686 if ((status != CAM_REQ_CMP)
6687 && (status == CAM_SCSI_STATUS_ERROR)
6688 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6689 struct scsi_sense_data *sense;
6690 int error_code, sense_key, asc, ascq;
6692 sense = &ccb->csio.sense_data;
6693 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6694 ccb->csio.sense_resid, &error_code, &sense_key,
6695 &asc, &ascq, /*show_errors*/ 1);
6698 * According to the SCSI-2 and SCSI-3 specs, a
6699 * drive that is in the middle of a format should
6700 * return NOT READY with an ASC of "logical unit
6701 * not ready, format in progress". The sense key
6702 * specific bytes will then be a progress indicator.
6704 if ((sense_key == SSD_KEY_NOT_READY)
6705 && (asc == 0x04) && (ascq == 0x04)) {
6708 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6709 ccb->csio.sense_resid, sks) == 0)
6712 u_int64_t percentage;
6714 val = scsi_2btoul(&sks[1]);
6715 percentage = 10000ull * val;
6718 "\rFormatting: %ju.%02u %% "
6720 (uintmax_t)(percentage /
6722 (unsigned)((percentage /
6726 } else if ((quiet == 0)
6727 && (++num_warnings <= 1)) {
6728 warnx("Unexpected SCSI Sense Key "
6729 "Specific value returned "
6731 scsi_sense_print(device, &ccb->csio,
6733 warnx("Unable to print status "
6734 "information, but format will "
6736 warnx("will exit when format is "
6741 warnx("Unexpected SCSI error during format");
6742 cam_error_print(device, ccb, CAM_ESF_ALL,
6743 CAM_EPF_ALL, stderr);
6745 goto scsiformat_bailout;
6748 } else if (status != CAM_REQ_CMP) {
6749 warnx("Unexpected CAM status %#x", status);
6750 if (arglist & CAM_ARG_VERBOSE)
6751 cam_error_print(device, ccb, CAM_ESF_ALL,
6752 CAM_EPF_ALL, stderr);
6754 goto scsiformat_bailout;
6757 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6760 fprintf(stdout, "\nFormat Complete\n");
6770 scsisanitize(struct cam_device *device, int argc, char **argv,
6771 char *combinedopt, int task_attr, int retry_count, int timeout)
6774 u_int8_t action = 0;
6776 int ycount = 0, quiet = 0;
6777 int error = 0, retval = 0;
6778 int use_timeout = 10800 * 1000;
6784 const char *pattern = NULL;
6785 u_int8_t *data_ptr = NULL;
6786 u_int32_t dxfer_len = 0;
6788 int num_warnings = 0;
6791 ccb = cam_getccb(device);
6794 warnx("scsisanitize: error allocating ccb");
6798 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6800 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6803 if (strcasecmp(optarg, "overwrite") == 0)
6804 action = SSZ_SERVICE_ACTION_OVERWRITE;
6805 else if (strcasecmp(optarg, "block") == 0)
6806 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6807 else if (strcasecmp(optarg, "crypto") == 0)
6808 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6809 else if (strcasecmp(optarg, "exitfailure") == 0)
6810 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6812 warnx("invalid service operation \"%s\"",
6815 goto scsisanitize_bailout;
6819 passes = strtol(optarg, NULL, 0);
6820 if (passes < 1 || passes > 31) {
6821 warnx("invalid passes value %d", passes);
6823 goto scsisanitize_bailout;
6854 warnx("an action is required");
6856 goto scsisanitize_bailout;
6857 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6858 struct scsi_sanitize_parameter_list *pl;
6862 if (pattern == NULL) {
6863 warnx("overwrite action requires -P argument");
6865 goto scsisanitize_bailout;
6867 fd = open(pattern, O_RDONLY);
6869 warn("cannot open pattern file %s", pattern);
6871 goto scsisanitize_bailout;
6873 if (fstat(fd, &sb) < 0) {
6874 warn("cannot stat pattern file %s", pattern);
6876 goto scsisanitize_bailout;
6879 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6880 warnx("pattern file size exceeds maximum value %d",
6881 SSZPL_MAX_PATTERN_LENGTH);
6883 goto scsisanitize_bailout;
6885 dxfer_len = sizeof(*pl) + sz;
6886 data_ptr = calloc(1, dxfer_len);
6887 if (data_ptr == NULL) {
6888 warnx("cannot allocate parameter list buffer");
6890 goto scsisanitize_bailout;
6893 amt = read(fd, data_ptr + sizeof(*pl), sz);
6895 warn("cannot read pattern file");
6897 goto scsisanitize_bailout;
6898 } else if (amt != sz) {
6899 warnx("short pattern file read");
6901 goto scsisanitize_bailout;
6904 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6910 pl->byte1 |= SSZPL_INVERT;
6911 scsi_ulto2b(sz, pl->length);
6917 else if (invert != 0)
6919 else if (pattern != NULL)
6924 warnx("%s argument only valid with overwrite "
6927 goto scsisanitize_bailout;
6932 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6933 "following device:\n");
6935 error = scsidoinquiry(device, argc, argv, combinedopt,
6936 task_attr, retry_count, timeout);
6939 warnx("scsisanitize: error sending inquiry");
6940 goto scsisanitize_bailout;
6945 if (!get_confirmation()) {
6947 goto scsisanitize_bailout;
6952 use_timeout = timeout;
6955 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6956 use_timeout / 1000);
6960 * If the user hasn't disabled questions and didn't specify a
6961 * timeout on the command line, ask them if they want the current
6965 && (timeout == 0)) {
6967 int new_timeout = 0;
6969 fprintf(stdout, "Enter new timeout in seconds or press\n"
6970 "return to keep the current timeout [%d] ",
6971 use_timeout / 1000);
6973 if (fgets(str, sizeof(str), stdin) != NULL) {
6975 new_timeout = atoi(str);
6978 if (new_timeout != 0) {
6979 use_timeout = new_timeout * 1000;
6980 fprintf(stdout, "Using new timeout value %d\n",
6981 use_timeout / 1000);
6987 byte2 |= SSZ_UNRESTRICTED_EXIT;
6991 scsi_sanitize(&ccb->csio,
6992 /* retries */ retry_count,
6994 /* tag_action */ task_attr,
6997 /* data_ptr */ data_ptr,
6998 /* dxfer_len */ dxfer_len,
6999 /* sense_len */ SSD_FULL_SIZE,
7000 /* timeout */ use_timeout);
7002 /* Disable freezing the device queue */
7003 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7005 if (arglist & CAM_ARG_ERR_RECOVER)
7006 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7008 if (cam_send_ccb(device, ccb) < 0) {
7009 warn("error sending sanitize command");
7011 goto scsisanitize_bailout;
7014 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7015 struct scsi_sense_data *sense;
7016 int error_code, sense_key, asc, ascq;
7018 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
7019 CAM_SCSI_STATUS_ERROR) {
7020 sense = &ccb->csio.sense_data;
7021 scsi_extract_sense_len(sense, ccb->csio.sense_len -
7022 ccb->csio.sense_resid, &error_code, &sense_key,
7023 &asc, &ascq, /*show_errors*/ 1);
7025 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
7026 asc == 0x20 && ascq == 0x00)
7027 warnx("sanitize is not supported by "
7030 warnx("error sanitizing this device");
7032 warnx("error sanitizing this device");
7034 if (arglist & CAM_ARG_VERBOSE) {
7035 cam_error_print(device, ccb, CAM_ESF_ALL,
7036 CAM_EPF_ALL, stderr);
7039 goto scsisanitize_bailout;
7043 * If we ran in non-immediate mode, we already checked for errors
7044 * above and printed out any necessary information. If we're in
7045 * immediate mode, we need to loop through and get status
7046 * information periodically.
7048 if (immediate == 0) {
7050 fprintf(stdout, "Sanitize Complete\n");
7052 goto scsisanitize_bailout;
7059 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7062 * There's really no need to do error recovery or
7063 * retries here, since we're just going to sit in a
7064 * loop and wait for the device to finish sanitizing.
7066 scsi_test_unit_ready(&ccb->csio,
7069 /* tag_action */ task_attr,
7070 /* sense_len */ SSD_FULL_SIZE,
7071 /* timeout */ 5000);
7073 /* Disable freezing the device queue */
7074 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7076 retval = cam_send_ccb(device, ccb);
7079 * If we get an error from the ioctl, bail out. SCSI
7080 * errors are expected.
7083 warn("error sending CAMIOCOMMAND ioctl");
7084 if (arglist & CAM_ARG_VERBOSE) {
7085 cam_error_print(device, ccb, CAM_ESF_ALL,
7086 CAM_EPF_ALL, stderr);
7089 goto scsisanitize_bailout;
7092 status = ccb->ccb_h.status & CAM_STATUS_MASK;
7094 if ((status != CAM_REQ_CMP)
7095 && (status == CAM_SCSI_STATUS_ERROR)
7096 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
7097 struct scsi_sense_data *sense;
7098 int error_code, sense_key, asc, ascq;
7100 sense = &ccb->csio.sense_data;
7101 scsi_extract_sense_len(sense, ccb->csio.sense_len -
7102 ccb->csio.sense_resid, &error_code, &sense_key,
7103 &asc, &ascq, /*show_errors*/ 1);
7106 * According to the SCSI-3 spec, a drive that is in the
7107 * middle of a sanitize should return NOT READY with an
7108 * ASC of "logical unit not ready, sanitize in
7109 * progress". The sense key specific bytes will then
7110 * be a progress indicator.
7112 if ((sense_key == SSD_KEY_NOT_READY)
7113 && (asc == 0x04) && (ascq == 0x1b)) {
7116 if ((scsi_get_sks(sense, ccb->csio.sense_len -
7117 ccb->csio.sense_resid, sks) == 0)
7120 u_int64_t percentage;
7122 val = scsi_2btoul(&sks[1]);
7123 percentage = 10000 * val;
7126 "\rSanitizing: %ju.%02u %% "
7128 (uintmax_t)(percentage /
7130 (unsigned)((percentage /
7134 } else if ((quiet == 0)
7135 && (++num_warnings <= 1)) {
7136 warnx("Unexpected SCSI Sense Key "
7137 "Specific value returned "
7138 "during sanitize:");
7139 scsi_sense_print(device, &ccb->csio,
7141 warnx("Unable to print status "
7142 "information, but sanitze will "
7144 warnx("will exit when sanitize is "
7149 warnx("Unexpected SCSI error during sanitize");
7150 cam_error_print(device, ccb, CAM_ESF_ALL,
7151 CAM_EPF_ALL, stderr);
7153 goto scsisanitize_bailout;
7156 } else if (status != CAM_REQ_CMP) {
7157 warnx("Unexpected CAM status %#x", status);
7158 if (arglist & CAM_ARG_VERBOSE)
7159 cam_error_print(device, ccb, CAM_ESF_ALL,
7160 CAM_EPF_ALL, stderr);
7162 goto scsisanitize_bailout;
7164 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
7167 fprintf(stdout, "\nSanitize Complete\n");
7169 scsisanitize_bailout:
7172 if (data_ptr != NULL)
7180 scsireportluns(struct cam_device *device, int argc, char **argv,
7181 char *combinedopt, int task_attr, int retry_count, int timeout)
7184 int c, countonly, lunsonly;
7185 struct scsi_report_luns_data *lundata;
7187 uint8_t report_type;
7188 uint32_t list_len, i, j;
7193 report_type = RPL_REPORT_DEFAULT;
7194 ccb = cam_getccb(device);
7197 warnx("%s: error allocating ccb", __func__);
7201 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7206 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7215 if (strcasecmp(optarg, "default") == 0)
7216 report_type = RPL_REPORT_DEFAULT;
7217 else if (strcasecmp(optarg, "wellknown") == 0)
7218 report_type = RPL_REPORT_WELLKNOWN;
7219 else if (strcasecmp(optarg, "all") == 0)
7220 report_type = RPL_REPORT_ALL;
7222 warnx("%s: invalid report type \"%s\"",
7233 if ((countonly != 0)
7234 && (lunsonly != 0)) {
7235 warnx("%s: you can only specify one of -c or -l", __func__);
7240 * According to SPC-4, the allocation length must be at least 16
7241 * bytes -- enough for the header and one LUN.
7243 alloc_len = sizeof(*lundata) + 8;
7247 lundata = malloc(alloc_len);
7249 if (lundata == NULL) {
7250 warn("%s: error mallocing %d bytes", __func__, alloc_len);
7255 scsi_report_luns(&ccb->csio,
7256 /*retries*/ retry_count,
7258 /*tag_action*/ task_attr,
7259 /*select_report*/ report_type,
7260 /*rpl_buf*/ lundata,
7261 /*alloc_len*/ alloc_len,
7262 /*sense_len*/ SSD_FULL_SIZE,
7263 /*timeout*/ timeout ? timeout : 5000);
7265 /* Disable freezing the device queue */
7266 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7268 if (arglist & CAM_ARG_ERR_RECOVER)
7269 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7271 if (cam_send_ccb(device, ccb) < 0) {
7272 warn("error sending REPORT LUNS command");
7274 if (arglist & CAM_ARG_VERBOSE)
7275 cam_error_print(device, ccb, CAM_ESF_ALL,
7276 CAM_EPF_ALL, stderr);
7282 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7283 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7289 list_len = scsi_4btoul(lundata->length);
7292 * If we need to list the LUNs, and our allocation
7293 * length was too short, reallocate and retry.
7295 if ((countonly == 0)
7296 && (list_len > (alloc_len - sizeof(*lundata)))) {
7297 alloc_len = list_len + sizeof(*lundata);
7303 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7304 ((list_len / 8) > 1) ? "s" : "");
7309 for (i = 0; i < (list_len / 8); i++) {
7313 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7315 fprintf(stdout, ",");
7316 switch (lundata->luns[i].lundata[j] &
7317 RPL_LUNDATA_ATYP_MASK) {
7318 case RPL_LUNDATA_ATYP_PERIPH:
7319 if ((lundata->luns[i].lundata[j] &
7320 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7321 fprintf(stdout, "%d:",
7322 lundata->luns[i].lundata[j] &
7323 RPL_LUNDATA_PERIPH_BUS_MASK);
7325 && ((lundata->luns[i].lundata[j+2] &
7326 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7329 fprintf(stdout, "%d",
7330 lundata->luns[i].lundata[j+1]);
7332 case RPL_LUNDATA_ATYP_FLAT: {
7334 tmplun[0] = lundata->luns[i].lundata[j] &
7335 RPL_LUNDATA_FLAT_LUN_MASK;
7336 tmplun[1] = lundata->luns[i].lundata[j+1];
7338 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7342 case RPL_LUNDATA_ATYP_LUN:
7343 fprintf(stdout, "%d:%d:%d",
7344 (lundata->luns[i].lundata[j+1] &
7345 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7346 lundata->luns[i].lundata[j] &
7347 RPL_LUNDATA_LUN_TARG_MASK,
7348 lundata->luns[i].lundata[j+1] &
7349 RPL_LUNDATA_LUN_LUN_MASK);
7351 case RPL_LUNDATA_ATYP_EXTLUN: {
7352 int field_len_code, eam_code;
7354 eam_code = lundata->luns[i].lundata[j] &
7355 RPL_LUNDATA_EXT_EAM_MASK;
7356 field_len_code = (lundata->luns[i].lundata[j] &
7357 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7359 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7360 && (field_len_code == 0x00)) {
7361 fprintf(stdout, "%d",
7362 lundata->luns[i].lundata[j+1]);
7363 } else if ((eam_code ==
7364 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7365 && (field_len_code == 0x03)) {
7369 * This format takes up all 8 bytes.
7370 * If we aren't starting at offset 0,
7374 fprintf(stdout, "Invalid "
7377 "specified format", j);
7381 bzero(tmp_lun, sizeof(tmp_lun));
7382 bcopy(&lundata->luns[i].lundata[j+1],
7383 &tmp_lun[1], sizeof(tmp_lun) - 1);
7384 fprintf(stdout, "%#jx",
7385 (intmax_t)scsi_8btou64(tmp_lun));
7388 fprintf(stderr, "Unknown Extended LUN"
7389 "Address method %#x, length "
7390 "code %#x", eam_code,
7397 fprintf(stderr, "Unknown LUN address method "
7398 "%#x\n", lundata->luns[i].lundata[0] &
7399 RPL_LUNDATA_ATYP_MASK);
7403 * For the flat addressing method, there are no
7404 * other levels after it.
7409 fprintf(stdout, "\n");
7422 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7423 char *combinedopt, int task_attr, int retry_count, int timeout)
7426 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7427 struct scsi_read_capacity_data rcap;
7428 struct scsi_read_capacity_data_long rcaplong;
7443 ccb = cam_getccb(device);
7446 warnx("%s: error allocating ccb", __func__);
7450 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7452 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7482 if ((blocksizeonly != 0)
7483 && (numblocks != 0)) {
7484 warnx("%s: you can only specify one of -b or -N", __func__);
7489 if ((blocksizeonly != 0)
7490 && (sizeonly != 0)) {
7491 warnx("%s: you can only specify one of -b or -s", __func__);
7498 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7504 && (blocksizeonly != 0)) {
7505 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7513 scsi_read_capacity(&ccb->csio,
7514 /*retries*/ retry_count,
7516 /*tag_action*/ task_attr,
7519 /*timeout*/ timeout ? timeout : 5000);
7521 /* Disable freezing the device queue */
7522 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7524 if (arglist & CAM_ARG_ERR_RECOVER)
7525 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7527 if (cam_send_ccb(device, ccb) < 0) {
7528 warn("error sending READ CAPACITY command");
7530 if (arglist & CAM_ARG_VERBOSE)
7531 cam_error_print(device, ccb, CAM_ESF_ALL,
7532 CAM_EPF_ALL, stderr);
7538 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7539 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7544 maxsector = scsi_4btoul(rcap.addr);
7545 block_len = scsi_4btoul(rcap.length);
7548 * A last block of 2^32-1 means that the true capacity is over 2TB,
7549 * and we need to issue the long READ CAPACITY to get the real
7550 * capacity. Otherwise, we're all set.
7552 if (maxsector != 0xffffffff)
7556 scsi_read_capacity_16(&ccb->csio,
7557 /*retries*/ retry_count,
7559 /*tag_action*/ task_attr,
7563 /*rcap_buf*/ (uint8_t *)&rcaplong,
7564 /*rcap_buf_len*/ sizeof(rcaplong),
7565 /*sense_len*/ SSD_FULL_SIZE,
7566 /*timeout*/ timeout ? timeout : 5000);
7568 /* Disable freezing the device queue */
7569 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7571 if (arglist & CAM_ARG_ERR_RECOVER)
7572 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7574 if (cam_send_ccb(device, ccb) < 0) {
7575 warn("error sending READ CAPACITY (16) command");
7577 if (arglist & CAM_ARG_VERBOSE)
7578 cam_error_print(device, ccb, CAM_ESF_ALL,
7579 CAM_EPF_ALL, stderr);
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 struct ata_res *res;
9153 res = &ccb->ataio.res;
9154 if (res->status & ATA_STATUS_ERROR) {
9155 if (arglist & CAM_ARG_VERBOSE) {
9156 cam_error_print(device, ccb, CAM_ESF_ALL,
9157 CAM_EPF_ALL, stderr);
9158 printf("error = 0x%02x, sector_count = 0x%04x, "
9159 "device = 0x%02x, status = 0x%02x\n",
9160 res->error, res->sector_count,
9161 res->device, res->status);
9167 if (arglist & CAM_ARG_VERBOSE) {
9168 fprintf(stdout, "%s%d: Raw native check power data:\n",
9169 device->device_name, device->dev_unit_num);
9170 /* res is 4 byte aligned */
9171 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
9173 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
9174 "status = 0x%02x\n", res->error, res->sector_count,
9175 res->device, res->status);
9178 printf("%s%d: ", device->device_name, device->dev_unit_num);
9179 switch (res->sector_count) {
9181 printf("Standby mode\n");
9184 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
9187 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
9190 printf("Idle mode\n");
9193 printf("Active or Idle mode\n");
9196 printf("Unknown mode 0x%02x\n", res->sector_count);
9204 atapm(struct cam_device *device, int argc, char **argv,
9205 char *combinedopt, int retry_count, int timeout)
9211 u_int8_t ata_flags = 0;
9214 ccb = cam_getccb(device);
9217 warnx("%s: error allocating ccb", __func__);
9221 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9230 if (strcmp(argv[1], "idle") == 0) {
9232 cmd = ATA_IDLE_IMMEDIATE;
9235 } else if (strcmp(argv[1], "standby") == 0) {
9237 cmd = ATA_STANDBY_IMMEDIATE;
9239 cmd = ATA_STANDBY_CMD;
9240 } else if (strcmp(argv[1], "powermode") == 0) {
9241 cmd = ATA_CHECK_POWER_MODE;
9242 ata_flags = AP_FLAG_CHK_COND;
9251 else if (t <= (240 * 5))
9253 else if (t <= (252 * 5))
9254 /* special encoding for 21 minutes */
9256 else if (t <= (11 * 30 * 60))
9257 sc = (t - 1) / (30 * 60) + 241;
9261 retval = ata_do_cmd(device,
9263 /*retries*/retry_count,
9264 /*flags*/CAM_DIR_NONE,
9265 /*protocol*/AP_PROTO_NON_DATA,
9266 /*ata_flags*/ata_flags,
9267 /*tag_action*/MSG_SIMPLE_Q_TAG,
9274 /*timeout*/timeout ? timeout : 30 * 1000,
9279 if (retval || cmd != ATA_CHECK_POWER_MODE)
9282 return (atapm_proc_resp(device, ccb));
9286 ataaxm(struct cam_device *device, int argc, char **argv,
9287 char *combinedopt, int retry_count, int timeout)
9295 ccb = cam_getccb(device);
9298 warnx("%s: error allocating ccb", __func__);
9302 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9312 if (strcmp(argv[1], "apm") == 0) {
9328 retval = ata_do_28bit_cmd(device,
9330 /*retries*/retry_count,
9331 /*flags*/CAM_DIR_NONE,
9332 /*protocol*/AP_PROTO_NON_DATA,
9333 /*tag_action*/MSG_SIMPLE_Q_TAG,
9334 /*command*/ATA_SETFEATURES,
9340 /*timeout*/timeout ? timeout : 30 * 1000,
9348 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9349 int show_sa_errors, int sa_set, int service_action,
9350 int timeout_desc, int task_attr, int retry_count, int timeout,
9351 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9353 union ccb *ccb = NULL;
9354 uint8_t *buf = NULL;
9355 uint32_t alloc_len = 0, num_opcodes;
9356 uint32_t valid_len = 0;
9357 uint32_t avail_len = 0;
9358 struct scsi_report_supported_opcodes_all *all_hdr;
9359 struct scsi_report_supported_opcodes_one *one;
9364 * Make it clear that we haven't yet allocated or filled anything.
9369 ccb = cam_getccb(device);
9371 warnx("couldn't allocate CCB");
9376 /* cam_getccb cleans up the header, caller has to zero the payload */
9377 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9379 if (opcode_set != 0) {
9380 options |= RSO_OPTIONS_OC;
9382 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9385 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9386 sizeof(struct scsi_report_supported_opcodes_descr));
9389 if (timeout_desc != 0) {
9390 options |= RSO_RCTD;
9391 alloc_len += num_opcodes *
9392 sizeof(struct scsi_report_supported_opcodes_timeout);
9396 options |= RSO_OPTIONS_OC_SA;
9397 if (show_sa_errors != 0)
9398 options &= ~RSO_OPTIONS_OC;
9407 buf = malloc(alloc_len);
9409 warn("Unable to allocate %u bytes", alloc_len);
9413 bzero(buf, alloc_len);
9415 scsi_report_supported_opcodes(&ccb->csio,
9416 /*retries*/ retry_count,
9418 /*tag_action*/ task_attr,
9419 /*options*/ options,
9420 /*req_opcode*/ opcode,
9421 /*req_service_action*/ service_action,
9423 /*dxfer_len*/ alloc_len,
9424 /*sense_len*/ SSD_FULL_SIZE,
9425 /*timeout*/ timeout ? timeout : 10000);
9427 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9429 if (retry_count != 0)
9430 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9432 if (cam_send_ccb(device, ccb) < 0) {
9433 perror("error sending REPORT SUPPORTED OPERATION CODES");
9438 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9439 if (verbosemode != 0)
9440 cam_error_print(device, ccb, CAM_ESF_ALL,
9441 CAM_EPF_ALL, stderr);
9446 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9448 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9449 && (valid_len >= sizeof(*all_hdr))) {
9450 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9451 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9452 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9453 && (valid_len >= sizeof(*one))) {
9454 uint32_t cdb_length;
9456 one = (struct scsi_report_supported_opcodes_one *)buf;
9457 cdb_length = scsi_2btoul(one->cdb_length);
9458 avail_len = sizeof(*one) + cdb_length;
9459 if (one->support & RSO_ONE_CTDP) {
9460 struct scsi_report_supported_opcodes_timeout *td;
9462 td = (struct scsi_report_supported_opcodes_timeout *)
9464 if (valid_len >= (avail_len + sizeof(td->length))) {
9465 avail_len += scsi_2btoul(td->length) +
9468 avail_len += sizeof(*td);
9474 * avail_len could be zero if we didn't get enough data back from
9475 * thet target to determine
9477 if ((avail_len != 0)
9478 && (avail_len > valid_len)) {
9479 alloc_len = avail_len;
9483 *fill_len = valid_len;
9495 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9496 int req_sa, uint8_t *buf, uint32_t valid_len)
9498 struct scsi_report_supported_opcodes_one *one;
9499 struct scsi_report_supported_opcodes_timeout *td;
9500 uint32_t cdb_len = 0, td_len = 0;
9501 const char *op_desc = NULL;
9505 one = (struct scsi_report_supported_opcodes_one *)buf;
9508 * If we don't have the full single opcode descriptor, no point in
9511 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9513 warnx("Only %u bytes returned, not enough to verify support",
9519 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9521 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9524 printf(", SA 0x%x", req_sa);
9527 switch (one->support & RSO_ONE_SUP_MASK) {
9528 case RSO_ONE_SUP_UNAVAIL:
9529 printf("No command support information currently available\n");
9531 case RSO_ONE_SUP_NOT_SUP:
9532 printf("Command not supported\n");
9535 break; /*NOTREACHED*/
9536 case RSO_ONE_SUP_AVAIL:
9537 printf("Command is supported, complies with a SCSI standard\n");
9539 case RSO_ONE_SUP_VENDOR:
9540 printf("Command is supported, vendor-specific "
9541 "implementation\n");
9544 printf("Unknown command support flags 0x%#x\n",
9545 one->support & RSO_ONE_SUP_MASK);
9550 * If we don't have the CDB length, it isn't exactly an error, the
9551 * command probably isn't supported.
9553 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9557 cdb_len = scsi_2btoul(one->cdb_length);
9560 * If our valid data doesn't include the full reported length,
9561 * return. The caller should have detected this and adjusted his
9562 * allocation length to get all of the available data.
9564 if (valid_len < sizeof(*one) + cdb_len) {
9570 * If all we have is the opcode, there is no point in printing out
9578 printf("CDB usage bitmap:");
9579 for (i = 0; i < cdb_len; i++) {
9580 printf(" %02x", one->cdb_usage[i]);
9585 * If we don't have a timeout descriptor, we're done.
9587 if ((one->support & RSO_ONE_CTDP) == 0)
9591 * If we don't have enough valid length to include the timeout
9592 * descriptor length, we're done.
9594 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9597 td = (struct scsi_report_supported_opcodes_timeout *)
9598 &buf[sizeof(*one) + cdb_len];
9599 td_len = scsi_2btoul(td->length);
9600 td_len += sizeof(td->length);
9603 * If we don't have the full timeout descriptor, we're done.
9605 if (td_len < sizeof(*td))
9609 * If we don't have enough valid length to contain the full timeout
9610 * descriptor, we're done.
9612 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9615 printf("Timeout information:\n");
9616 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9617 printf("Nominal timeout: %u seconds\n",
9618 scsi_4btoul(td->nominal_time));
9619 printf("Recommended timeout: %u seconds\n",
9620 scsi_4btoul(td->recommended_time));
9627 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9630 struct scsi_report_supported_opcodes_all *hdr;
9631 struct scsi_report_supported_opcodes_descr *desc;
9632 uint32_t avail_len = 0, used_len = 0;
9636 if (valid_len < sizeof(*hdr)) {
9637 warnx("%s: not enough returned data (%u bytes) opcode list",
9638 __func__, valid_len);
9642 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9643 avail_len = scsi_4btoul(hdr->length);
9644 avail_len += sizeof(hdr->length);
9646 * Take the lesser of the amount of data the drive claims is
9647 * available, and the amount of data the HBA says was returned.
9649 avail_len = MIN(avail_len, valid_len);
9651 used_len = sizeof(hdr->length);
9653 printf("%-6s %4s %8s ",
9654 "Opcode", "SA", "CDB len" );
9657 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9658 printf(" Description\n");
9660 while ((avail_len - used_len) > sizeof(*desc)) {
9661 struct scsi_report_supported_opcodes_timeout *td;
9663 const char *op_desc = NULL;
9665 cur_ptr = &buf[used_len];
9666 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9668 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9669 if (op_desc == NULL)
9670 op_desc = "UNKNOWN";
9672 printf("0x%02x %#4x %8u ", desc->opcode,
9673 scsi_2btoul(desc->service_action),
9674 scsi_2btoul(desc->cdb_length));
9676 used_len += sizeof(*desc);
9678 if ((desc->flags & RSO_CTDP) == 0) {
9679 printf(" %s\n", op_desc);
9684 * If we don't have enough space to fit a timeout
9685 * descriptor, then we're done.
9687 if (avail_len - used_len < sizeof(*td)) {
9688 used_len = avail_len;
9689 printf(" %s\n", op_desc);
9692 cur_ptr = &buf[used_len];
9693 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9694 td_len = scsi_2btoul(td->length);
9695 td_len += sizeof(td->length);
9699 * If the given timeout descriptor length is less than what
9700 * we understand, skip it.
9702 if (td_len < sizeof(*td)) {
9703 printf(" %s\n", op_desc);
9707 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9708 scsi_4btoul(td->nominal_time),
9709 scsi_4btoul(td->recommended_time), op_desc);
9716 scsiopcodes(struct cam_device *device, int argc, char **argv,
9717 char *combinedopt, int task_attr, int retry_count, int timeout,
9721 uint32_t opcode = 0, service_action = 0;
9722 int td_set = 0, opcode_set = 0, sa_set = 0;
9723 int show_sa_errors = 1;
9724 uint32_t valid_len = 0;
9725 uint8_t *buf = NULL;
9729 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9735 opcode = strtoul(optarg, &endptr, 0);
9736 if (*endptr != '\0') {
9737 warnx("Invalid opcode \"%s\", must be a number",
9742 if (opcode > 0xff) {
9743 warnx("Invalid opcode 0x%#x, must be between"
9744 "0 and 0xff inclusive", opcode);
9751 service_action = strtoul(optarg, &endptr, 0);
9752 if (*endptr != '\0') {
9753 warnx("Invalid service action \"%s\", must "
9754 "be a number", optarg);
9758 if (service_action > 0xffff) {
9759 warnx("Invalid service action 0x%#x, must "
9760 "be between 0 and 0xffff inclusive",
9775 && (opcode_set == 0)) {
9776 warnx("You must specify an opcode with -o if a service "
9781 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9782 sa_set, service_action, td_set, task_attr,
9783 retry_count, timeout, verbosemode, &valid_len,
9788 if ((opcode_set != 0)
9790 retval = scsiprintoneopcode(device, opcode, sa_set,
9791 service_action, buf, valid_len);
9793 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9804 scsireprobe(struct cam_device *device)
9809 ccb = cam_getccb(device);
9812 warnx("%s: error allocating ccb", __func__);
9816 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9818 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9820 if (cam_send_ccb(device, ccb) < 0) {
9821 warn("error sending XPT_REPROBE_LUN CCB");
9826 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9827 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9839 usage(int printlong)
9842 fprintf(printlong ? stdout : stderr,
9843 "usage: camcontrol <command> [device id][generic args][command args]\n"
9844 " camcontrol devlist [-b] [-v]\n"
9845 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9846 " camcontrol tur [dev_id][generic args]\n"
9847 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9848 " camcontrol identify [dev_id][generic args] [-v]\n"
9849 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9850 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9852 " camcontrol start [dev_id][generic args]\n"
9853 " camcontrol stop [dev_id][generic args]\n"
9854 " camcontrol load [dev_id][generic args]\n"
9855 " camcontrol eject [dev_id][generic args]\n"
9856 " camcontrol reprobe [dev_id][generic args]\n"
9857 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9858 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9859 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9860 " [-q][-s][-S offset][-X]\n"
9861 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9862 " [-P pagectl][-e | -b][-d]\n"
9863 " camcontrol cmd [dev_id][generic args]\n"
9864 " <-a cmd [args] | -c cmd [args]>\n"
9865 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9866 " camcontrol smpcmd [dev_id][generic args]\n"
9867 " <-r len fmt [args]> <-R len fmt [args]>\n"
9868 " camcontrol smprg [dev_id][generic args][-l]\n"
9869 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9870 " [-o operation][-d name][-m rate][-M rate]\n"
9871 " [-T pp_timeout][-a enable|disable]\n"
9872 " [-A enable|disable][-s enable|disable]\n"
9873 " [-S enable|disable]\n"
9874 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9875 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9876 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9877 " <all|bus[:target[:lun]]|off>\n"
9878 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9879 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9880 " [-D <enable|disable>][-M mode][-O offset]\n"
9881 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9882 " [-U][-W bus_width]\n"
9883 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9884 " camcontrol sanitize [dev_id][generic args]\n"
9885 " [-a overwrite|block|crypto|exitfailure]\n"
9886 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9888 " camcontrol idle [dev_id][generic args][-t time]\n"
9889 " camcontrol standby [dev_id][generic args][-t time]\n"
9890 " camcontrol sleep [dev_id][generic args]\n"
9891 " camcontrol powermode [dev_id][generic args]\n"
9892 " camcontrol apm [dev_id][generic args][-l level]\n"
9893 " camcontrol aam [dev_id][generic args][-l level]\n"
9894 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9896 " camcontrol security [dev_id][generic args]\n"
9897 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9898 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9899 " [-U <user|master>] [-y]\n"
9900 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9901 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9902 " camcontrol ama [dev_id][generic args] [-f] [-q] [-s max_sectors]\n"
9903 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9904 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9905 " [-s scope][-S][-T type][-U]\n"
9906 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9907 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9908 " [-p part][-s start][-T type][-V vol]\n"
9909 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9911 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9912 " [-o rep_opts] [-P print_opts]\n"
9913 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9914 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9915 " [-S power_src] [-T timer]\n"
9916 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9917 " <-s <-f format -T time | -U >>\n"
9918 " camcontrol devtype [dev_id]\n"
9920 " camcontrol help\n");
9924 "Specify one of the following options:\n"
9925 "devlist list all CAM devices\n"
9926 "periphlist list all CAM peripheral drivers attached to a device\n"
9927 "tur send a test unit ready to the named device\n"
9928 "inquiry send a SCSI inquiry command to the named device\n"
9929 "identify send a ATA identify command to the named device\n"
9930 "reportluns send a SCSI report luns command to the device\n"
9931 "readcap send a SCSI read capacity command to the device\n"
9932 "start send a Start Unit command to the device\n"
9933 "stop send a Stop Unit command to the device\n"
9934 "load send a Start Unit command to the device with the load bit set\n"
9935 "eject send a Stop Unit command to the device with the eject bit set\n"
9936 "reprobe update capacity information of the given device\n"
9937 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9938 "reset reset all buses, the given bus, bus:target:lun or device\n"
9939 "defects read the defect list of the specified device\n"
9940 "modepage display or edit (-e) the given mode page\n"
9941 "cmd send the given SCSI command, may need -i or -o as well\n"
9942 "smpcmd send the given SMP command, requires -o and -i\n"
9943 "smprg send the SMP Report General command\n"
9944 "smppc send the SMP PHY Control command, requires -p\n"
9945 "smpphylist display phys attached to a SAS expander\n"
9946 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9947 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9948 "tags report or set the number of transaction slots for a device\n"
9949 "negotiate report or set device negotiation parameters\n"
9950 "format send the SCSI FORMAT UNIT command to the named device\n"
9951 "sanitize send the SCSI SANITIZE command to the named device\n"
9952 "idle send the ATA IDLE command to the named device\n"
9953 "standby send the ATA STANDBY command to the named device\n"
9954 "sleep send the ATA SLEEP command to the named device\n"
9955 "powermode send the ATA CHECK POWER MODE command to the named device\n"
9956 "fwdownload program firmware of the named device with the given image\n"
9957 "security report or send ATA security commands to the named device\n"
9958 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9959 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9960 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9961 "zone manage Zoned Block (Shingled) devices\n"
9962 "epc send ATA Extended Power Conditions commands\n"
9963 "timestamp report or set the device's timestamp\n"
9964 "devtype report the type of device\n"
9965 "help this message\n"
9966 "Device Identifiers:\n"
9967 "bus:target specify the bus and target, lun defaults to 0\n"
9968 "bus:target:lun specify the bus, target and lun\n"
9969 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
9970 "Generic arguments:\n"
9971 "-v be verbose, print out sense information\n"
9972 "-t timeout command timeout in seconds, overrides default timeout\n"
9973 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
9974 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
9975 "-E have the kernel attempt to perform SCSI error recovery\n"
9976 "-C count specify the SCSI command retry count (needs -E to work)\n"
9977 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
9978 "modepage arguments:\n"
9979 "-l list all available mode pages\n"
9980 "-m page specify the mode page to view or edit\n"
9981 "-e edit the specified mode page\n"
9982 "-b force view to binary mode\n"
9983 "-d disable block descriptors for mode sense\n"
9984 "-P pgctl page control field 0-3\n"
9985 "defects arguments:\n"
9986 "-f format specify defect list format (block, bfi or phys)\n"
9987 "-G get the grown defect list\n"
9988 "-P get the permanent defect list\n"
9989 "inquiry arguments:\n"
9990 "-D get the standard inquiry data\n"
9991 "-S get the serial number\n"
9992 "-R get the transfer rate, etc.\n"
9993 "reportluns arguments:\n"
9994 "-c only report a count of available LUNs\n"
9995 "-l only print out luns, and not a count\n"
9996 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
9997 "readcap arguments\n"
9998 "-b only report the blocksize\n"
9999 "-h human readable device size, base 2\n"
10000 "-H human readable device size, base 10\n"
10001 "-N print the number of blocks instead of last block\n"
10002 "-q quiet, print numbers only\n"
10003 "-s only report the last block/device size\n"
10005 "-c cdb [args] specify the SCSI CDB\n"
10006 "-i len fmt specify input data and input data format\n"
10007 "-o len fmt [args] specify output data and output data fmt\n"
10008 "smpcmd arguments:\n"
10009 "-r len fmt [args] specify the SMP command to be sent\n"
10010 "-R len fmt [args] specify SMP response format\n"
10011 "smprg arguments:\n"
10012 "-l specify the long response format\n"
10013 "smppc arguments:\n"
10014 "-p phy specify the PHY to operate on\n"
10015 "-l specify the long request/response format\n"
10016 "-o operation specify the phy control operation\n"
10017 "-d name set the attached device name\n"
10018 "-m rate set the minimum physical link rate\n"
10019 "-M rate set the maximum physical link rate\n"
10020 "-T pp_timeout set the partial pathway timeout value\n"
10021 "-a enable|disable enable or disable SATA slumber\n"
10022 "-A enable|disable enable or disable SATA partial phy power\n"
10023 "-s enable|disable enable or disable SAS slumber\n"
10024 "-S enable|disable enable or disable SAS partial phy power\n"
10025 "smpphylist arguments:\n"
10026 "-l specify the long response format\n"
10027 "-q only print phys with attached devices\n"
10028 "smpmaninfo arguments:\n"
10029 "-l specify the long response format\n"
10030 "debug arguments:\n"
10031 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
10032 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
10033 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
10034 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
10035 "tags arguments:\n"
10036 "-N tags specify the number of tags to use for this device\n"
10037 "-q be quiet, don't report the number of tags\n"
10038 "-v report a number of tag-related parameters\n"
10039 "negotiate arguments:\n"
10040 "-a send a test unit ready after negotiation\n"
10041 "-c report/set current negotiation settings\n"
10042 "-D <arg> \"enable\" or \"disable\" disconnection\n"
10043 "-M mode set ATA mode\n"
10044 "-O offset set command delay offset\n"
10045 "-q be quiet, don't report anything\n"
10046 "-R syncrate synchronization rate in MHz\n"
10047 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
10048 "-U report/set user negotiation settings\n"
10049 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
10050 "-v also print a Path Inquiry CCB for the controller\n"
10051 "format arguments:\n"
10052 "-q be quiet, don't print status messages\n"
10053 "-r run in report only mode\n"
10054 "-w don't send immediate format command\n"
10055 "-y don't ask any questions\n"
10056 "sanitize arguments:\n"
10057 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
10058 "-c passes overwrite passes to perform (1 to 31)\n"
10059 "-I invert overwrite pattern after each pass\n"
10060 "-P pattern path to overwrite pattern file\n"
10061 "-q be quiet, don't print status messages\n"
10062 "-r run in report only mode\n"
10063 "-U run operation in unrestricted completion exit mode\n"
10064 "-w don't send immediate sanitize command\n"
10065 "-y don't ask any questions\n"
10066 "idle/standby arguments:\n"
10067 "-t <arg> number of seconds before respective state.\n"
10068 "fwdownload arguments:\n"
10069 "-f fw_image path to firmware image file\n"
10070 "-q don't print informational messages, only errors\n"
10071 "-s run in simulation mode\n"
10072 "-v print info for every firmware segment sent to device\n"
10073 "-y don't ask any questions\n"
10074 "security arguments:\n"
10075 "-d pwd disable security using the given password for the selected\n"
10077 "-e pwd erase the device using the given pwd for the selected user\n"
10078 "-f freeze the security configuration of the specified device\n"
10079 "-h pwd enhanced erase the device using the given pwd for the\n"
10081 "-k pwd unlock the device using the given pwd for the selected\n"
10083 "-l <high|maximum> specifies which security level to set: high or maximum\n"
10084 "-q be quiet, do not print any status messages\n"
10085 "-s pwd password the device (enable security) using the given\n"
10086 " pwd for the selected user\n"
10087 "-T timeout overrides the timeout (seconds) used for erase operation\n"
10088 "-U <user|master> specifies which user to set: user or master\n"
10089 "-y don't ask any questions\n"
10091 "-f freeze the HPA configuration of the device\n"
10092 "-l lock the HPA configuration of the device\n"
10093 "-P make the HPA max sectors persist\n"
10094 "-p pwd Set the HPA configuration password required for unlock\n"
10096 "-q be quiet, do not print any status messages\n"
10097 "-s sectors configures the maximum user accessible sectors of the\n"
10099 "-U pwd unlock the HPA configuration of the device\n"
10100 "-y don't ask any questions\n"
10102 "-f freeze the AMA configuration of the device\n"
10103 "-q be quiet, do not print any status messages\n"
10104 "-s sectors configures the maximum user accessible sectors of the\n"
10106 "persist arguments:\n"
10107 "-i action specify read_keys, read_reservation, report_cap, or\n"
10108 " read_full_status\n"
10109 "-o action specify register, register_ignore, reserve, release,\n"
10110 " clear, preempt, preempt_abort, register_move, replace_lost\n"
10111 "-a set the All Target Ports (ALL_TG_PT) bit\n"
10112 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
10113 "-k key specify the Reservation Key\n"
10114 "-K sa_key specify the Service Action Reservation Key\n"
10115 "-p set the Activate Persist Through Power Loss bit\n"
10116 "-R rtp specify the Relative Target Port\n"
10117 "-s scope specify the scope: lun, extent, element or a number\n"
10118 "-S specify Transport ID for register, requires -I\n"
10119 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
10120 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
10121 "-U unregister the current initiator for register_move\n"
10122 "attrib arguments:\n"
10123 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
10125 "-w attr specify an attribute to write, one -w argument per attr\n"
10126 "-a attr_num only display this attribute number\n"
10127 "-c get cached attributes\n"
10128 "-e elem_addr request attributes for the given element in a changer\n"
10129 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
10130 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
10131 " field_none, field_desc, field_num, field_size, field_rw\n"
10132 "-p partition request attributes for the given partition\n"
10133 "-s start_attr request attributes starting at the given number\n"
10134 "-T elem_type specify the element type (used with -e)\n"
10135 "-V logical_vol specify the logical volume ID\n"
10136 "opcodes arguments:\n"
10137 "-o opcode specify the individual opcode to list\n"
10138 "-s service_action specify the service action for the opcode\n"
10139 "-N do not return SCSI error for unsupported SA\n"
10140 "-T request nominal and recommended timeout values\n"
10141 "zone arguments:\n"
10142 "-c cmd required: rz, open, close, finish, or rwp\n"
10143 "-a apply the action to all zones\n"
10144 "-l LBA specify the zone starting LBA\n"
10145 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
10146 " closed, full, ro, offline, reset, nonseq, nonwp\n"
10147 "-P print_opt report zones printing: normal, summary, script\n"
10149 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
10150 " source, status, list\n"
10151 "-d disable power mode (timer, state)\n"
10152 "-D delayed entry (goto)\n"
10153 "-e enable power mode (timer, state)\n"
10154 "-H hold power mode (goto)\n"
10155 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
10157 "-P only display power mode (status)\n"
10158 "-r rst_src restore settings from: default, saved (restore)\n"
10159 "-s save mode (timer, state, restore)\n"
10160 "-S power_src set power source: battery, nonbattery (source)\n"
10161 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
10162 "timestamp arguments:\n"
10163 "-r report the timestamp of the device\n"
10164 "-f format report the timestamp of the device with the given\n"
10165 " strftime(3) format string\n"
10166 "-m report the timestamp of the device as milliseconds since\n"
10167 " January 1st, 1970\n"
10168 "-U report the time with UTC instead of the local time zone\n"
10169 "-s set the timestamp of the device\n"
10170 "-f format the format of the time string passed into strptime(3)\n"
10171 "-T time the time value passed into strptime(3)\n"
10172 "-U set the timestamp of the device to UTC time\n"
10177 main(int argc, char **argv)
10180 char *device = NULL;
10182 struct cam_device *cam_dev = NULL;
10183 int timeout = 0, retry_count = 1;
10184 camcontrol_optret optreturn;
10186 const char *mainopt = "C:En:Q:t:u:v";
10187 const char *subopt = NULL;
10188 char combinedopt[256];
10189 int error = 0, optstart = 2;
10190 int task_attr = MSG_SIMPLE_Q_TAG;
10193 target_id_t target;
10196 cmdlist = CAM_CMD_NONE;
10197 arglist = CAM_ARG_NONE;
10205 * Get the base option.
10207 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
10209 if (optreturn == CC_OR_AMBIGUOUS) {
10210 warnx("ambiguous option %s", argv[1]);
10213 } else if (optreturn == CC_OR_NOT_FOUND) {
10214 warnx("option %s not found", argv[1]);
10220 * Ahh, getopt(3) is a pain.
10222 * This is a gross hack. There really aren't many other good
10223 * options (excuse the pun) for parsing options in a situation like
10224 * this. getopt is kinda braindead, so you end up having to run
10225 * through the options twice, and give each invocation of getopt
10226 * the option string for the other invocation.
10228 * You would think that you could just have two groups of options.
10229 * The first group would get parsed by the first invocation of
10230 * getopt, and the second group would get parsed by the second
10231 * invocation of getopt. It doesn't quite work out that way. When
10232 * the first invocation of getopt finishes, it leaves optind pointing
10233 * to the argument _after_ the first argument in the second group.
10234 * So when the second invocation of getopt comes around, it doesn't
10235 * recognize the first argument it gets and then bails out.
10237 * A nice alternative would be to have a flag for getopt that says
10238 * "just keep parsing arguments even when you encounter an unknown
10239 * argument", but there isn't one. So there's no real clean way to
10240 * easily parse two sets of arguments without having one invocation
10241 * of getopt know about the other.
10243 * Without this hack, the first invocation of getopt would work as
10244 * long as the generic arguments are first, but the second invocation
10245 * (in the subfunction) would fail in one of two ways. In the case
10246 * where you don't set optreset, it would fail because optind may be
10247 * pointing to the argument after the one it should be pointing at.
10248 * In the case where you do set optreset, and reset optind, it would
10249 * fail because getopt would run into the first set of options, which
10250 * it doesn't understand.
10252 * All of this would "sort of" work if you could somehow figure out
10253 * whether optind had been incremented one option too far. The
10254 * mechanics of that, however, are more daunting than just giving
10255 * both invocations all of the expect options for either invocation.
10257 * Needless to say, I wouldn't mind if someone invented a better
10258 * (non-GPL!) command line parsing interface than getopt. I
10259 * wouldn't mind if someone added more knobs to getopt to make it
10260 * work better. Who knows, I may talk myself into doing it someday,
10261 * if the standards weenies let me. As it is, it just leads to
10262 * hackery like this and causes people to avoid it in some cases.
10264 * KDM, September 8th, 1998
10266 if (subopt != NULL)
10267 sprintf(combinedopt, "%s%s", mainopt, subopt);
10269 sprintf(combinedopt, "%s", mainopt);
10272 * For these options we do not parse optional device arguments and
10273 * we do not open a passthrough device.
10275 if ((cmdlist == CAM_CMD_RESCAN)
10276 || (cmdlist == CAM_CMD_RESET)
10277 || (cmdlist == CAM_CMD_DEVTREE)
10278 || (cmdlist == CAM_CMD_USAGE)
10279 || (cmdlist == CAM_CMD_DEBUG))
10283 && (argc > 2 && argv[2][0] != '-')) {
10287 if (isdigit(argv[2][0])) {
10288 /* device specified as bus:target[:lun] */
10289 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10291 errx(1, "numeric device specification must "
10292 "be either bus:target, or "
10294 /* default to 0 if lun was not specified */
10295 if ((arglist & CAM_ARG_LUN) == 0) {
10297 arglist |= CAM_ARG_LUN;
10301 if (cam_get_device(argv[2], name, sizeof name, &unit)
10303 errx(1, "%s", cam_errbuf);
10304 device = strdup(name);
10305 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10310 * Start getopt processing at argv[2/3], since we've already
10311 * accepted argv[1..2] as the command name, and as a possible
10317 * Now we run through the argument list looking for generic
10318 * options, and ignoring options that possibly belong to
10321 while ((c = getopt(argc, argv, combinedopt))!= -1){
10324 retry_count = strtol(optarg, NULL, 0);
10325 if (retry_count < 0)
10326 errx(1, "retry count %d is < 0",
10328 arglist |= CAM_ARG_RETRIES;
10331 arglist |= CAM_ARG_ERR_RECOVER;
10334 arglist |= CAM_ARG_DEVICE;
10336 while (isspace(*tstr) && (*tstr != '\0'))
10338 device = (char *)strdup(tstr);
10342 int table_entry = 0;
10345 while (isspace(*tstr) && (*tstr != '\0'))
10347 if (isdigit(*tstr)) {
10348 task_attr = strtol(tstr, &endptr, 0);
10349 if (*endptr != '\0') {
10350 errx(1, "Invalid queue option "
10355 scsi_nv_status status;
10357 table_size = sizeof(task_attrs) /
10358 sizeof(task_attrs[0]);
10359 status = scsi_get_nv(task_attrs,
10360 table_size, tstr, &table_entry,
10361 SCSI_NV_FLAG_IG_CASE);
10362 if (status == SCSI_NV_FOUND)
10363 task_attr = task_attrs[
10364 table_entry].value;
10366 errx(1, "%s option %s",
10367 (status == SCSI_NV_AMBIGUOUS)?
10368 "ambiguous" : "invalid",
10375 timeout = strtol(optarg, NULL, 0);
10377 errx(1, "invalid timeout %d", timeout);
10378 /* Convert the timeout from seconds to ms */
10380 arglist |= CAM_ARG_TIMEOUT;
10383 arglist |= CAM_ARG_UNIT;
10384 unit = strtol(optarg, NULL, 0);
10387 arglist |= CAM_ARG_VERBOSE;
10395 * For most commands we'll want to open the passthrough device
10396 * associated with the specified device. In the case of the rescan
10397 * commands, we don't use a passthrough device at all, just the
10398 * transport layer device.
10400 if (devopen == 1) {
10401 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10402 && (((arglist & CAM_ARG_DEVICE) == 0)
10403 || ((arglist & CAM_ARG_UNIT) == 0))) {
10404 errx(1, "subcommand \"%s\" requires a valid device "
10405 "identifier", argv[1]);
10408 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10409 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10410 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10412 errx(1,"%s", cam_errbuf);
10416 * Reset optind to 2, and reset getopt, so these routines can parse
10417 * the arguments again.
10423 case CAM_CMD_DEVLIST:
10424 error = getdevlist(cam_dev);
10427 error = atahpa(cam_dev, retry_count, timeout,
10428 argc, argv, combinedopt);
10431 error = ataama(cam_dev, retry_count, timeout,
10432 argc, argv, combinedopt);
10434 case CAM_CMD_DEVTREE:
10435 error = getdevtree(argc, argv, combinedopt);
10437 case CAM_CMD_DEVTYPE:
10438 error = getdevtype(cam_dev);
10441 error = testunitready(cam_dev, task_attr, retry_count,
10444 case CAM_CMD_INQUIRY:
10445 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10446 task_attr, retry_count, timeout);
10448 case CAM_CMD_IDENTIFY:
10449 error = identify(cam_dev, retry_count, timeout);
10451 case CAM_CMD_STARTSTOP:
10452 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10453 arglist & CAM_ARG_EJECT, task_attr,
10454 retry_count, timeout);
10456 case CAM_CMD_RESCAN:
10457 error = dorescan_or_reset(argc, argv, 1);
10459 case CAM_CMD_RESET:
10460 error = dorescan_or_reset(argc, argv, 0);
10462 case CAM_CMD_READ_DEFECTS:
10463 error = readdefects(cam_dev, argc, argv, combinedopt,
10464 task_attr, retry_count, timeout);
10466 case CAM_CMD_MODE_PAGE:
10467 modepage(cam_dev, argc, argv, combinedopt,
10468 task_attr, retry_count, timeout);
10470 case CAM_CMD_SCSI_CMD:
10471 error = scsicmd(cam_dev, argc, argv, combinedopt,
10472 task_attr, retry_count, timeout);
10474 case CAM_CMD_MMCSD_CMD:
10475 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10476 retry_count, timeout);
10478 case CAM_CMD_SMP_CMD:
10479 error = smpcmd(cam_dev, argc, argv, combinedopt,
10480 retry_count, timeout);
10482 case CAM_CMD_SMP_RG:
10483 error = smpreportgeneral(cam_dev, argc, argv,
10484 combinedopt, retry_count,
10487 case CAM_CMD_SMP_PC:
10488 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10489 retry_count, timeout);
10491 case CAM_CMD_SMP_PHYLIST:
10492 error = smpphylist(cam_dev, argc, argv, combinedopt,
10493 retry_count, timeout);
10495 case CAM_CMD_SMP_MANINFO:
10496 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10497 retry_count, timeout);
10499 case CAM_CMD_DEBUG:
10500 error = camdebug(argc, argv, combinedopt);
10503 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10506 error = ratecontrol(cam_dev, task_attr, retry_count,
10507 timeout, argc, argv, combinedopt);
10509 case CAM_CMD_FORMAT:
10510 error = scsiformat(cam_dev, argc, argv,
10511 combinedopt, task_attr, retry_count,
10514 case CAM_CMD_REPORTLUNS:
10515 error = scsireportluns(cam_dev, argc, argv,
10516 combinedopt, task_attr,
10517 retry_count, timeout);
10519 case CAM_CMD_READCAP:
10520 error = scsireadcapacity(cam_dev, argc, argv,
10521 combinedopt, task_attr,
10522 retry_count, timeout);
10525 case CAM_CMD_STANDBY:
10526 case CAM_CMD_SLEEP:
10527 case CAM_CMD_POWER_MODE:
10528 error = atapm(cam_dev, argc, argv,
10529 combinedopt, retry_count, timeout);
10533 error = ataaxm(cam_dev, argc, argv,
10534 combinedopt, retry_count, timeout);
10536 case CAM_CMD_SECURITY:
10537 error = atasecurity(cam_dev, retry_count, timeout,
10538 argc, argv, combinedopt);
10540 case CAM_CMD_DOWNLOAD_FW:
10541 error = fwdownload(cam_dev, argc, argv, combinedopt,
10542 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10545 case CAM_CMD_SANITIZE:
10546 error = scsisanitize(cam_dev, argc, argv,
10547 combinedopt, task_attr,
10548 retry_count, timeout);
10550 case CAM_CMD_PERSIST:
10551 error = scsipersist(cam_dev, argc, argv, combinedopt,
10552 task_attr, retry_count, timeout,
10553 arglist & CAM_ARG_VERBOSE,
10554 arglist & CAM_ARG_ERR_RECOVER);
10556 case CAM_CMD_ATTRIB:
10557 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10558 task_attr, retry_count, timeout,
10559 arglist & CAM_ARG_VERBOSE,
10560 arglist & CAM_ARG_ERR_RECOVER);
10562 case CAM_CMD_OPCODES:
10563 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10564 task_attr, retry_count, timeout,
10565 arglist & CAM_ARG_VERBOSE);
10567 case CAM_CMD_REPROBE:
10568 error = scsireprobe(cam_dev);
10571 error = zone(cam_dev, argc, argv, combinedopt,
10572 task_attr, retry_count, timeout,
10573 arglist & CAM_ARG_VERBOSE);
10576 error = epc(cam_dev, argc, argv, combinedopt,
10577 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10579 case CAM_CMD_TIMESTAMP:
10580 error = timestamp(cam_dev, argc, argv, combinedopt,
10581 task_attr, retry_count, timeout,
10582 arglist & CAM_ARG_VERBOSE);
10584 case CAM_CMD_USAGE:
10593 if (cam_dev != NULL)
10594 cam_close_device(cam_dev);