2 * Copyright (c) 1997-2007 Kenneth D. Merry
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/ioctl.h>
33 #include <sys/stdint.h>
34 #include <sys/types.h>
36 #include <sys/endian.h>
53 #include <cam/cam_debug.h>
54 #include <cam/cam_ccb.h>
55 #include <cam/scsi/scsi_all.h>
56 #include <cam/scsi/scsi_da.h>
57 #include <cam/scsi/scsi_pass.h>
58 #include <cam/scsi/scsi_message.h>
59 #include <cam/scsi/smp_all.h>
60 #include <cam/ata/ata_all.h>
61 #include <cam/mmc/mmc_all.h>
63 #include "camcontrol.h"
65 #include "nvmecontrol_ext.h"
69 CAM_CMD_NONE = 0x00000000,
70 CAM_CMD_DEVLIST = 0x00000001,
71 CAM_CMD_TUR = 0x00000002,
72 CAM_CMD_INQUIRY = 0x00000003,
73 CAM_CMD_STARTSTOP = 0x00000004,
74 CAM_CMD_RESCAN = 0x00000005,
75 CAM_CMD_READ_DEFECTS = 0x00000006,
76 CAM_CMD_MODE_PAGE = 0x00000007,
77 CAM_CMD_SCSI_CMD = 0x00000008,
78 CAM_CMD_DEVTREE = 0x00000009,
79 CAM_CMD_USAGE = 0x0000000a,
80 CAM_CMD_DEBUG = 0x0000000b,
81 CAM_CMD_RESET = 0x0000000c,
82 CAM_CMD_FORMAT = 0x0000000d,
83 CAM_CMD_TAG = 0x0000000e,
84 CAM_CMD_RATE = 0x0000000f,
85 CAM_CMD_DETACH = 0x00000010,
86 CAM_CMD_REPORTLUNS = 0x00000011,
87 CAM_CMD_READCAP = 0x00000012,
88 CAM_CMD_IDENTIFY = 0x00000013,
89 CAM_CMD_IDLE = 0x00000014,
90 CAM_CMD_STANDBY = 0x00000015,
91 CAM_CMD_SLEEP = 0x00000016,
92 CAM_CMD_SMP_CMD = 0x00000017,
93 CAM_CMD_SMP_RG = 0x00000018,
94 CAM_CMD_SMP_PC = 0x00000019,
95 CAM_CMD_SMP_PHYLIST = 0x0000001a,
96 CAM_CMD_SMP_MANINFO = 0x0000001b,
97 CAM_CMD_DOWNLOAD_FW = 0x0000001c,
98 CAM_CMD_SECURITY = 0x0000001d,
99 CAM_CMD_HPA = 0x0000001e,
100 CAM_CMD_SANITIZE = 0x0000001f,
101 CAM_CMD_PERSIST = 0x00000020,
102 CAM_CMD_APM = 0x00000021,
103 CAM_CMD_AAM = 0x00000022,
104 CAM_CMD_ATTRIB = 0x00000023,
105 CAM_CMD_OPCODES = 0x00000024,
106 CAM_CMD_REPROBE = 0x00000025,
107 CAM_CMD_ZONE = 0x00000026,
108 CAM_CMD_EPC = 0x00000027,
109 CAM_CMD_TIMESTAMP = 0x00000028,
110 CAM_CMD_MMCSD_CMD = 0x00000029,
111 CAM_CMD_POWER_MODE = 0x0000002a,
112 CAM_CMD_DEVTYPE = 0x0000002b,
113 CAM_CMD_AMA = 0x0000002c,
117 CAM_ARG_NONE = 0x00000000,
118 CAM_ARG_VERBOSE = 0x00000001,
119 CAM_ARG_DEVICE = 0x00000002,
120 CAM_ARG_BUS = 0x00000004,
121 CAM_ARG_TARGET = 0x00000008,
122 CAM_ARG_LUN = 0x00000010,
123 CAM_ARG_EJECT = 0x00000020,
124 CAM_ARG_UNIT = 0x00000040,
125 CAM_ARG_FORMAT_BLOCK = 0x00000080,
126 CAM_ARG_FORMAT_BFI = 0x00000100,
127 CAM_ARG_FORMAT_PHYS = 0x00000200,
128 CAM_ARG_PLIST = 0x00000400,
129 CAM_ARG_GLIST = 0x00000800,
130 CAM_ARG_GET_SERIAL = 0x00001000,
131 CAM_ARG_GET_STDINQ = 0x00002000,
132 CAM_ARG_GET_XFERRATE = 0x00004000,
133 CAM_ARG_INQ_MASK = 0x00007000,
134 CAM_ARG_TIMEOUT = 0x00020000,
135 CAM_ARG_CMD_IN = 0x00040000,
136 CAM_ARG_CMD_OUT = 0x00080000,
137 CAM_ARG_ERR_RECOVER = 0x00200000,
138 CAM_ARG_RETRIES = 0x00400000,
139 CAM_ARG_START_UNIT = 0x00800000,
140 CAM_ARG_DEBUG_INFO = 0x01000000,
141 CAM_ARG_DEBUG_TRACE = 0x02000000,
142 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
143 CAM_ARG_DEBUG_CDB = 0x08000000,
144 CAM_ARG_DEBUG_XPT = 0x10000000,
145 CAM_ARG_DEBUG_PERIPH = 0x20000000,
146 CAM_ARG_DEBUG_PROBE = 0x40000000,
149 struct camcontrol_opts {
156 struct ata_res_pass16 {
157 u_int16_t reserved[5];
160 u_int8_t sector_count_exp;
161 u_int8_t sector_count;
162 u_int8_t lba_low_exp;
164 u_int8_t lba_mid_exp;
166 u_int8_t lba_high_exp;
172 struct ata_set_max_pwd
175 u_int8_t password[32];
176 u_int16_t reserved2[239];
179 static struct scsi_nv task_attrs[] = {
180 { "simple", MSG_SIMPLE_Q_TAG },
181 { "head", MSG_HEAD_OF_Q_TAG },
182 { "ordered", MSG_ORDERED_Q_TAG },
183 { "iwr", MSG_IGN_WIDE_RESIDUE },
184 { "aca", MSG_ACA_TASK }
187 static const char scsicmd_opts[] = "a:c:dfi:o:r";
188 static const char readdefect_opts[] = "f:GPqsS:X";
189 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
190 static const char smprg_opts[] = "l";
191 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
192 static const char smpphylist_opts[] = "lq";
195 static struct camcontrol_opts option_table[] = {
196 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
197 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
198 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
199 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
200 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
201 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
202 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
203 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
204 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHlNqs"},
205 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
206 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
207 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
208 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
209 {"mmcsdcmd", CAM_CMD_MMCSD_CMD, CAM_ARG_NONE, "c:a:f:Wb:l:41S:I"},
210 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
211 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
212 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
213 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
214 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
215 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
216 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
217 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
218 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
219 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
220 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
221 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
222 {"devtype", CAM_CMD_DEVTYPE, CAM_ARG_NONE, ""},
223 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
224 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "6bdelm: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 reprobe(struct cam_device *device);
305 static int dorescan_or_reset(int argc, char **argv, int rescan);
306 static int rescan_or_reset_bus(path_id_t bus, int rescan);
307 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
308 lun_id_t lun, int scan);
309 static int readdefects(struct cam_device *device, int argc, char **argv,
310 char *combinedopt, int task_attr, int retry_count,
312 static void modepage(struct cam_device *device, int argc, char **argv,
313 char *combinedopt, int task_attr, int retry_count,
315 static int scsicmd(struct cam_device *device, int argc, char **argv,
316 char *combinedopt, int task_attr, int retry_count,
318 static int smpcmd(struct cam_device *device, int argc, char **argv,
319 char *combinedopt, int retry_count, int timeout);
320 static int mmcsdcmd(struct cam_device *device, int argc, char **argv,
321 char *combinedopt, int retry_count, int timeout);
322 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
323 char *combinedopt, int retry_count, int timeout);
324 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
325 char *combinedopt, int retry_count, int timeout);
326 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
327 char *combinedopt, int retry_count, int timeout);
328 static int getdevid(struct cam_devitem *item);
329 static int buildbusdevlist(struct cam_devlist *devlist);
330 static void freebusdevlist(struct cam_devlist *devlist);
331 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
333 static int smpphylist(struct cam_device *device, int argc, char **argv,
334 char *combinedopt, int retry_count, int timeout);
335 static int tagcontrol(struct cam_device *device, int argc, char **argv,
337 static void cts_print(struct cam_device *device,
338 struct ccb_trans_settings *cts);
339 static void cpi_print(struct ccb_pathinq *cpi);
340 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
341 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
342 static int get_print_cts(struct cam_device *device, int user_settings,
343 int quiet, struct ccb_trans_settings *cts);
344 static int ratecontrol(struct cam_device *device, int task_attr,
345 int retry_count, int timeout, int argc, char **argv,
347 static int scsiformat(struct cam_device *device, int argc, char **argv,
348 char *combinedopt, int task_attr, int retry_count,
350 static int sanitize(struct cam_device *device, int argc, char **argv,
351 char *combinedopt, int task_attr, int retry_count,
353 static int scsireportluns(struct cam_device *device, int argc, char **argv,
354 char *combinedopt, int task_attr, int retry_count,
356 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
357 char *combinedopt, int task_attr, int retry_count,
359 static int atapm(struct cam_device *device, int argc, char **argv,
360 char *combinedopt, int retry_count, int timeout);
361 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
362 int argc, char **argv, char *combinedopt);
363 static int atahpa(struct cam_device *device, int retry_count, int timeout,
364 int argc, char **argv, char *combinedopt);
365 static int ataama(struct cam_device *device, int retry_count, int timeout,
366 int argc, char **argv, char *combinedopt);
367 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
368 int sa_set, int req_sa, uint8_t *buf,
370 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
372 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
373 char *combinedopt, int task_attr, int retry_count,
374 int timeout, int verbose);
377 #define min(a,b) (((a)<(b))?(a):(b))
380 #define max(a,b) (((a)>(b))?(a):(b))
384 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
385 cam_argmask *argnum, const char **subopt)
387 struct camcontrol_opts *opts;
390 for (opts = table; (opts != NULL) && (opts->optname != NULL);
392 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
393 *cmdnum = opts->cmdnum;
394 *argnum = opts->argnum;
395 *subopt = opts->subopt;
396 if (++num_matches > 1)
397 return (CC_OR_AMBIGUOUS);
402 return (CC_OR_FOUND);
404 return (CC_OR_NOT_FOUND);
408 getdevlist(struct cam_device *device)
414 ccb = cam_getccb(device);
416 ccb->ccb_h.func_code = XPT_GDEVLIST;
417 ccb->ccb_h.flags = CAM_DIR_NONE;
418 ccb->ccb_h.retry_count = 1;
420 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
421 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
422 if (cam_send_ccb(device, ccb) < 0) {
423 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)
1482 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1483 ((u_int32_t)parm->lba_size_2 << 16);
1485 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1486 ((u_int64_t)parm->lba_size48_2 << 16) |
1487 ((u_int64_t)parm->lba_size48_3 << 32) |
1488 ((u_int64_t)parm->lba_size48_4 << 48);
1491 printf("protocol ");
1492 proto = (parm->config == ATA_PROTO_CFA) ? "CFA" :
1493 (parm->config & ATA_PROTO_ATAPI) ? "ATAPI" : "ATA";
1494 if (ata_version(parm->version_major) == 0) {
1495 printf("%s", proto);
1496 } else if (ata_version(parm->version_major) <= 7) {
1497 printf("%s-%d", proto,
1498 ata_version(parm->version_major));
1499 } else if (ata_version(parm->version_major) == 8) {
1500 printf("%s8-ACS", proto);
1503 ata_version(parm->version_major) - 7, proto);
1505 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1506 if (parm->satacapabilities & ATA_SATA_GEN3)
1507 printf(" SATA 3.x\n");
1508 else if (parm->satacapabilities & ATA_SATA_GEN2)
1509 printf(" SATA 2.x\n");
1510 else if (parm->satacapabilities & ATA_SATA_GEN1)
1511 printf(" SATA 1.x\n");
1517 printf("device model %.40s\n", parm->model);
1518 printf("firmware revision %.8s\n", parm->revision);
1519 printf("serial number %.20s\n", parm->serial);
1520 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1521 printf("WWN %04x%04x%04x%04x\n",
1522 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1524 printf("additional product id %.8s\n", parm->product_id);
1525 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1526 printf("media serial number %.30s\n",
1527 parm->media_serial);
1530 printf("cylinders %d\n", parm->cylinders);
1531 printf("heads %d\n", parm->heads);
1532 printf("sectors/track %d\n", parm->sectors);
1533 printf("sector size logical %u, physical %lu, offset %lu\n",
1534 ata_logical_sector_size(parm),
1535 (unsigned long)ata_physical_sector_size(parm),
1536 (unsigned long)ata_logical_sector_offset(parm));
1538 if (parm->config == ATA_PROTO_CFA ||
1539 (parm->support.command2 & ATA_SUPPORT_CFA))
1540 printf("CFA supported\n");
1542 printf("LBA%ssupported ",
1543 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1545 printf("%d sectors\n", lbasize);
1549 printf("LBA48%ssupported ",
1550 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1552 printf("%ju sectors\n", (uintmax_t)lbasize48);
1556 printf("PIO supported PIO");
1557 switch (ata_max_pmode(parm)) {
1573 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1574 printf(" w/o IORDY");
1577 printf("DMA%ssupported ",
1578 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1579 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1580 if (parm->mwdmamodes & 0xff) {
1582 if (parm->mwdmamodes & 0x04)
1584 else if (parm->mwdmamodes & 0x02)
1586 else if (parm->mwdmamodes & 0x01)
1590 if ((parm->atavalid & ATA_FLAG_88) &&
1591 (parm->udmamodes & 0xff)) {
1593 if (parm->udmamodes & 0x40)
1595 else if (parm->udmamodes & 0x20)
1597 else if (parm->udmamodes & 0x10)
1599 else if (parm->udmamodes & 0x08)
1601 else if (parm->udmamodes & 0x04)
1603 else if (parm->udmamodes & 0x02)
1605 else if (parm->udmamodes & 0x01)
1612 if (parm->media_rotation_rate == 1) {
1613 printf("media RPM non-rotating\n");
1614 } else if (parm->media_rotation_rate >= 0x0401 &&
1615 parm->media_rotation_rate <= 0xFFFE) {
1616 printf("media RPM %d\n",
1617 parm->media_rotation_rate);
1620 printf("Zoned-Device Commands ");
1621 switch (parm->support3 & ATA_SUPPORT_ZONE_MASK) {
1622 case ATA_SUPPORT_ZONE_DEV_MANAGED:
1623 printf("device managed\n");
1625 case ATA_SUPPORT_ZONE_HOST_AWARE:
1626 printf("host aware\n");
1633 "Support Enabled Value Vendor\n");
1634 printf("read ahead %s %s\n",
1635 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1636 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1637 printf("write cache %s %s\n",
1638 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1639 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1640 printf("flush cache %s %s\n",
1641 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1642 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1643 printf("overlap %s\n",
1644 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1645 printf("Tagged Command Queuing (TCQ) %s %s",
1646 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1647 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1648 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1649 printf(" %d tags\n",
1650 ATA_QUEUE_LEN(parm->queue) + 1);
1653 printf("Native Command Queuing (NCQ) ");
1654 if (atasata(parm) && (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1655 printf("yes %d tags\n",
1656 ATA_QUEUE_LEN(parm->queue) + 1);
1657 printf("NCQ Priority Information %s\n",
1658 parm->satacapabilities & ATA_SUPPORT_NCQ_PRIO ?
1660 printf("NCQ Non-Data Command %s\n",
1661 parm->satacapabilities2 & ATA_SUPPORT_NCQ_NON_DATA ?
1663 printf("NCQ Streaming %s\n",
1664 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1666 printf("Receive & Send FPDMA Queued %s\n",
1667 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1669 printf("NCQ Autosense %s\n",
1670 parm->satasupport & ATA_SUPPORT_NCQ_AUTOSENSE ?
1675 printf("SMART %s %s\n",
1676 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1677 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1678 printf("security %s %s\n",
1679 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1680 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1681 printf("power management %s %s\n",
1682 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1683 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1684 printf("microcode download %s %s\n",
1685 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1686 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1687 printf("advanced power management %s %s",
1688 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1689 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1690 if (parm->support.command2 & ATA_SUPPORT_APM) {
1691 printf(" %d/0x%02X\n",
1692 parm->apm_value & 0xff, parm->apm_value & 0xff);
1695 printf("automatic acoustic management %s %s",
1696 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1697 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1698 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1699 printf(" %d/0x%02X %d/0x%02X\n",
1700 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1701 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1702 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1703 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1706 printf("media status notification %s %s\n",
1707 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1708 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1709 printf("power-up in Standby %s %s\n",
1710 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1711 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1712 printf("write-read-verify %s %s",
1713 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1714 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1715 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1716 printf(" %d/0x%x\n",
1717 parm->wrv_mode, parm->wrv_mode);
1720 printf("unload %s %s\n",
1721 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1722 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1723 printf("general purpose logging %s %s\n",
1724 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1725 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1726 printf("free-fall %s %s\n",
1727 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1728 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1729 printf("sense data reporting %s %s\n",
1730 parm->support2 & ATA_SUPPORT_SENSE_REPORT ? "yes" : "no",
1731 parm->enabled2 & ATA_SUPPORT_SENSE_REPORT ? "yes" : "no");
1732 printf("extended power conditions %s %s\n",
1733 parm->support2 & ATA_SUPPORT_EPC ? "yes" : "no",
1734 parm->enabled2 & ATA_SUPPORT_EPC ? "yes" : "no");
1735 printf("device statistics notification %s %s\n",
1736 parm->support2 & ATA_SUPPORT_DSN ? "yes" : "no",
1737 parm->enabled2 & ATA_SUPPORT_DSN ? "yes" : "no");
1738 printf("Data Set Management (DSM/TRIM) ");
1739 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1741 printf("DSM - max 512byte blocks ");
1742 if (parm->max_dsm_blocks == 0x00)
1743 printf("yes not specified\n");
1746 parm->max_dsm_blocks);
1748 printf("DSM - deterministic read ");
1749 if (parm->support3 & ATA_SUPPORT_DRAT) {
1750 if (parm->support3 & ATA_SUPPORT_RZAT)
1751 printf("yes zeroed\n");
1753 printf("yes any value\n");
1760 printf("encrypts all user data %s\n",
1761 parm->support3 & ATA_ENCRYPTS_ALL_USER_DATA ? "yes" : "no");
1762 printf("Sanitize ");
1763 if (parm->multi & ATA_SUPPORT_SANITIZE) {
1764 printf("yes\t\t%s%s%s\n",
1765 parm->multi & ATA_SUPPORT_BLOCK_ERASE_EXT ? "block, " : "",
1766 parm->multi & ATA_SUPPORT_OVERWRITE_EXT ? "overwrite, " : "",
1767 parm->multi & ATA_SUPPORT_CRYPTO_SCRAMBLE_EXT ? "crypto" : "");
1768 printf("Sanitize - commands allowed %s\n",
1769 parm->multi & ATA_SUPPORT_SANITIZE_ALLOWED ? "yes" : "no");
1770 printf("Sanitize - antifreeze lock %s\n",
1771 parm->multi & ATA_SUPPORT_ANTIFREEZE_LOCK_EXT ? "yes" : "no");
1778 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1780 struct ata_pass_16 *ata_pass_16;
1781 struct ata_cmd ata_cmd;
1783 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1784 ata_cmd.command = ata_pass_16->command;
1785 ata_cmd.control = ata_pass_16->control;
1786 ata_cmd.features = ata_pass_16->features;
1788 if (arglist & CAM_ARG_VERBOSE) {
1789 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1790 ata_op_string(&ata_cmd),
1791 ccb->csio.ccb_h.timeout);
1794 /* Disable freezing the device queue */
1795 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1797 if (arglist & CAM_ARG_ERR_RECOVER)
1798 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1800 if (cam_send_ccb(device, ccb) < 0) {
1801 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1802 warn("error sending ATA %s via pass_16",
1803 ata_op_string(&ata_cmd));
1806 if (arglist & CAM_ARG_VERBOSE) {
1807 cam_error_print(device, ccb, CAM_ESF_ALL,
1808 CAM_EPF_ALL, stderr);
1814 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1815 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1816 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1817 warnx("ATA %s via pass_16 failed",
1818 ata_op_string(&ata_cmd));
1820 if (arglist & CAM_ARG_VERBOSE) {
1821 cam_error_print(device, ccb, CAM_ESF_ALL,
1822 CAM_EPF_ALL, stderr);
1833 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1835 if (arglist & CAM_ARG_VERBOSE) {
1836 warnx("sending ATA %s with timeout of %u msecs",
1837 ata_op_string(&(ccb->ataio.cmd)),
1838 ccb->ataio.ccb_h.timeout);
1841 /* Disable freezing the device queue */
1842 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1844 if (arglist & CAM_ARG_ERR_RECOVER)
1845 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1847 if (cam_send_ccb(device, ccb) < 0) {
1848 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1849 warn("error sending ATA %s",
1850 ata_op_string(&(ccb->ataio.cmd)));
1853 if (arglist & CAM_ARG_VERBOSE) {
1854 cam_error_print(device, ccb, CAM_ESF_ALL,
1855 CAM_EPF_ALL, stderr);
1861 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1862 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1863 warnx("ATA %s failed: %d",
1864 ata_op_string(&(ccb->ataio.cmd)), quiet);
1867 if (arglist & CAM_ARG_VERBOSE) {
1868 cam_error_print(device, ccb, CAM_ESF_ALL,
1869 CAM_EPF_ALL, stderr);
1879 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1880 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1881 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1882 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1883 u_int16_t dxfer_len, int timeout, int quiet)
1885 if (data_ptr != NULL) {
1886 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1887 AP_FLAG_TLEN_SECT_CNT;
1888 if (flags & CAM_DIR_OUT)
1889 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1891 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1893 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1896 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1898 scsi_ata_pass_16(&ccb->csio,
1912 /*sense_len*/SSD_FULL_SIZE,
1915 return scsi_cam_pass_16_send(device, ccb, quiet);
1919 ata_try_pass_16(struct cam_device *device)
1921 struct ccb_pathinq cpi;
1923 if (get_cpi(device, &cpi) != 0) {
1924 warnx("couldn't get CPI");
1928 if (cpi.protocol == PROTO_SCSI) {
1929 /* possibly compatible with pass_16 */
1933 /* likely not compatible with pass_16 */
1938 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1939 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1940 u_int8_t command, u_int8_t features, u_int32_t lba,
1941 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1942 int timeout, int quiet)
1946 switch (ata_try_pass_16(device)) {
1950 /* Try using SCSI Passthrough */
1951 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1952 0, tag_action, command, features, lba,
1953 sector_count, data_ptr, dxfer_len,
1957 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1958 cam_fill_ataio(&ccb->ataio,
1967 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1968 return ata_cam_send(device, ccb, quiet);
1972 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1973 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1974 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1975 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1976 u_int16_t dxfer_len, int timeout, int force48bit)
1980 retval = ata_try_pass_16(device);
1987 /* Try using SCSI Passthrough */
1988 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1989 ata_flags, tag_action, command, features,
1990 lba, sector_count, data_ptr, dxfer_len,
1993 if (ata_flags & AP_FLAG_CHK_COND) {
1994 /* Decode ata_res from sense data */
1995 struct ata_res_pass16 *res_pass16;
1996 struct ata_res *res;
2000 /* sense_data is 4 byte aligned */
2001 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
2002 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
2003 ptr[i] = le16toh(ptr[i]);
2005 /* sense_data is 4 byte aligned */
2006 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
2007 &ccb->csio.sense_data;
2008 res = &ccb->ataio.res;
2009 res->flags = res_pass16->flags;
2010 res->status = res_pass16->status;
2011 res->error = res_pass16->error;
2012 res->lba_low = res_pass16->lba_low;
2013 res->lba_mid = res_pass16->lba_mid;
2014 res->lba_high = res_pass16->lba_high;
2015 res->device = res_pass16->device;
2016 res->lba_low_exp = res_pass16->lba_low_exp;
2017 res->lba_mid_exp = res_pass16->lba_mid_exp;
2018 res->lba_high_exp = res_pass16->lba_high_exp;
2019 res->sector_count = res_pass16->sector_count;
2020 res->sector_count_exp = res_pass16->sector_count_exp;
2021 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2022 if (res->status & ATA_STATUS_ERROR)
2023 ccb->ccb_h.status |= CAM_ATA_STATUS_ERROR;
2025 ccb->ccb_h.status |= CAM_REQ_CMP;
2031 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
2032 cam_fill_ataio(&ccb->ataio,
2041 if (force48bit || lba > ATA_MAX_28BIT_LBA)
2042 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
2044 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
2046 if (ata_flags & AP_FLAG_CHK_COND)
2047 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
2049 return ata_cam_send(device, ccb, 0);
2053 dump_data(uint16_t *ptr, uint32_t len)
2057 for (i = 0; i < len / 2; i++) {
2059 printf(" %3d: ", i);
2060 printf("%04hx ", ptr[i]);
2069 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
2070 int is48bit, u_int64_t *hpasize)
2072 struct ata_res *res;
2074 res = &ccb->ataio.res;
2075 if (res->status & ATA_STATUS_ERROR) {
2076 if (arglist & CAM_ARG_VERBOSE) {
2077 cam_error_print(device, ccb, CAM_ESF_ALL,
2078 CAM_EPF_ALL, stderr);
2079 printf("error = 0x%02x, sector_count = 0x%04x, "
2080 "device = 0x%02x, status = 0x%02x\n",
2081 res->error, res->sector_count,
2082 res->device, res->status);
2085 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
2086 warnx("Max address has already been set since "
2087 "last power-on or hardware reset");
2093 if (arglist & CAM_ARG_VERBOSE) {
2094 fprintf(stdout, "%s%d: Raw native max data:\n",
2095 device->device_name, device->dev_unit_num);
2096 /* res is 4 byte aligned */
2097 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
2099 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
2100 "status = 0x%02x\n", res->error, res->sector_count,
2101 res->device, res->status);
2104 if (hpasize != NULL) {
2106 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
2107 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
2108 ((res->lba_high << 16) | (res->lba_mid << 8) |
2111 *hpasize = (((res->device & 0x0f) << 24) |
2112 (res->lba_high << 16) | (res->lba_mid << 8) |
2121 ata_read_native_max(struct cam_device *device, int retry_count,
2122 u_int32_t timeout, union ccb *ccb,
2123 struct ata_params *parm, u_int64_t *hpasize)
2129 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
2130 protocol = AP_PROTO_NON_DATA;
2133 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
2134 protocol |= AP_EXTEND;
2136 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
2139 error = ata_do_cmd(device,
2142 /*flags*/CAM_DIR_NONE,
2143 /*protocol*/protocol,
2144 /*ata_flags*/AP_FLAG_CHK_COND,
2145 /*tag_action*/MSG_SIMPLE_Q_TAG,
2152 timeout ? timeout : 5000,
2158 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
2162 atahpa_set_max(struct cam_device *device, int retry_count,
2163 u_int32_t timeout, union ccb *ccb,
2164 int is48bit, u_int64_t maxsize, int persist)
2170 protocol = AP_PROTO_NON_DATA;
2173 cmd = ATA_SET_MAX_ADDRESS48;
2174 protocol |= AP_EXTEND;
2176 cmd = ATA_SET_MAX_ADDRESS;
2179 /* lba's are zero indexed so the max lba is requested max - 1 */
2183 error = ata_do_cmd(device,
2186 /*flags*/CAM_DIR_NONE,
2187 /*protocol*/protocol,
2188 /*ata_flags*/AP_FLAG_CHK_COND,
2189 /*tag_action*/MSG_SIMPLE_Q_TAG,
2191 /*features*/ATA_HPA_FEAT_MAX_ADDR,
2193 /*sector_count*/persist,
2196 timeout ? timeout : 1000,
2202 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2206 atahpa_password(struct cam_device *device, int retry_count,
2207 u_int32_t timeout, union ccb *ccb,
2208 int is48bit, struct ata_set_max_pwd *pwd)
2214 protocol = AP_PROTO_PIO_OUT;
2215 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2217 error = ata_do_cmd(device,
2220 /*flags*/CAM_DIR_OUT,
2221 /*protocol*/protocol,
2222 /*ata_flags*/AP_FLAG_CHK_COND,
2223 /*tag_action*/MSG_SIMPLE_Q_TAG,
2225 /*features*/ATA_HPA_FEAT_SET_PWD,
2228 /*data_ptr*/(u_int8_t*)pwd,
2229 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2230 timeout ? timeout : 1000,
2236 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2240 atahpa_lock(struct cam_device *device, int retry_count,
2241 u_int32_t timeout, union ccb *ccb, int is48bit)
2247 protocol = AP_PROTO_NON_DATA;
2248 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2250 error = ata_do_cmd(device,
2253 /*flags*/CAM_DIR_NONE,
2254 /*protocol*/protocol,
2255 /*ata_flags*/AP_FLAG_CHK_COND,
2256 /*tag_action*/MSG_SIMPLE_Q_TAG,
2258 /*features*/ATA_HPA_FEAT_LOCK,
2263 timeout ? timeout : 1000,
2269 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2273 atahpa_unlock(struct cam_device *device, int retry_count,
2274 u_int32_t timeout, union ccb *ccb,
2275 int is48bit, struct ata_set_max_pwd *pwd)
2281 protocol = AP_PROTO_PIO_OUT;
2282 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2284 error = ata_do_cmd(device,
2287 /*flags*/CAM_DIR_OUT,
2288 /*protocol*/protocol,
2289 /*ata_flags*/AP_FLAG_CHK_COND,
2290 /*tag_action*/MSG_SIMPLE_Q_TAG,
2292 /*features*/ATA_HPA_FEAT_UNLOCK,
2295 /*data_ptr*/(u_int8_t*)pwd,
2296 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2297 timeout ? timeout : 1000,
2303 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2307 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2308 u_int32_t timeout, union ccb *ccb, int is48bit)
2314 protocol = AP_PROTO_NON_DATA;
2315 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2317 error = ata_do_cmd(device,
2320 /*flags*/CAM_DIR_NONE,
2321 /*protocol*/protocol,
2322 /*ata_flags*/AP_FLAG_CHK_COND,
2323 /*tag_action*/MSG_SIMPLE_Q_TAG,
2325 /*features*/ATA_HPA_FEAT_FREEZE,
2330 timeout ? timeout : 1000,
2336 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2340 ata_get_native_max(struct cam_device *device, int retry_count,
2341 u_int32_t timeout, union ccb *ccb,
2342 u_int64_t *nativesize)
2346 error = ata_do_cmd(device,
2349 /*flags*/CAM_DIR_NONE,
2350 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2351 /*ata_flags*/AP_FLAG_CHK_COND,
2352 /*tag_action*/MSG_SIMPLE_Q_TAG,
2353 /*command*/ATA_AMAX_ADDR,
2354 /*features*/ATA_AMAX_ADDR_GET,
2359 timeout ? timeout : 30 * 1000,
2365 return atahpa_proc_resp(device, ccb, /*is48bit*/1, nativesize);
2369 ataama_set(struct cam_device *device, int retry_count,
2370 u_int32_t timeout, union ccb *ccb, u_int64_t maxsize)
2374 /* lba's are zero indexed so the max lba is requested max - 1 */
2378 error = ata_do_cmd(device,
2381 /*flags*/CAM_DIR_NONE,
2382 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2383 /*ata_flags*/AP_FLAG_CHK_COND,
2384 /*tag_action*/MSG_SIMPLE_Q_TAG,
2385 /*command*/ATA_AMAX_ADDR,
2386 /*features*/ATA_AMAX_ADDR_SET,
2391 timeout ? timeout : 30 * 1000,
2397 return atahpa_proc_resp(device, ccb, /*is48bit*/1, NULL);
2401 ataama_freeze(struct cam_device *device, int retry_count,
2402 u_int32_t timeout, union ccb *ccb)
2406 error = ata_do_cmd(device,
2409 /*flags*/CAM_DIR_NONE,
2410 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2411 /*ata_flags*/AP_FLAG_CHK_COND,
2412 /*tag_action*/MSG_SIMPLE_Q_TAG,
2413 /*command*/ATA_AMAX_ADDR,
2414 /*features*/ATA_AMAX_ADDR_FREEZE,
2419 timeout ? timeout : 30 * 1000,
2425 return atahpa_proc_resp(device, ccb, /*is48bit*/1, NULL);
2429 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2430 union ccb *ccb, struct ata_params** ident_bufp)
2432 struct ata_params *ident_buf;
2433 struct ccb_pathinq cpi;
2434 struct ccb_getdev cgd;
2437 u_int8_t command, retry_command;
2439 if (get_cpi(device, &cpi) != 0) {
2440 warnx("couldn't get CPI");
2444 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2445 if (cpi.protocol == PROTO_ATA) {
2446 if (get_cgd(device, &cgd) != 0) {
2447 warnx("couldn't get CGD");
2451 command = (cgd.protocol == PROTO_ATA) ?
2452 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2455 /* We don't know which for sure so try both */
2456 command = ATA_ATA_IDENTIFY;
2457 retry_command = ATA_ATAPI_IDENTIFY;
2460 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2462 warnx("can't calloc memory for identify\n");
2466 error = ata_do_28bit_cmd(device,
2468 /*retries*/retry_count,
2469 /*flags*/CAM_DIR_IN,
2470 /*protocol*/AP_PROTO_PIO_IN,
2471 /*tag_action*/MSG_SIMPLE_Q_TAG,
2476 /*data_ptr*/(u_int8_t *)ptr,
2477 /*dxfer_len*/sizeof(struct ata_params),
2478 /*timeout*/timeout ? timeout : 30 * 1000,
2482 if (retry_command == 0) {
2486 error = ata_do_28bit_cmd(device,
2488 /*retries*/retry_count,
2489 /*flags*/CAM_DIR_IN,
2490 /*protocol*/AP_PROTO_PIO_IN,
2491 /*tag_action*/MSG_SIMPLE_Q_TAG,
2492 /*command*/retry_command,
2496 /*data_ptr*/(u_int8_t *)ptr,
2497 /*dxfer_len*/sizeof(struct ata_params),
2498 /*timeout*/timeout ? timeout : 30 * 1000,
2507 ident_buf = (struct ata_params *)ptr;
2508 ata_param_fixup(ident_buf);
2511 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2516 /* check for invalid (all zero) response */
2518 warnx("Invalid identify response detected");
2523 *ident_bufp = ident_buf;
2530 ataidentify(struct cam_device *device, int retry_count, int timeout)
2533 struct ata_params *ident_buf;
2534 u_int64_t hpasize, nativesize;
2536 if ((ccb = cam_getccb(device)) == NULL) {
2537 warnx("couldn't allocate CCB");
2541 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2546 if (arglist & CAM_ARG_VERBOSE) {
2547 printf("%s%d: Raw identify data:\n",
2548 device->device_name, device->dev_unit_num);
2549 dump_data((void*)ident_buf, sizeof(struct ata_params));
2552 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2553 if (ata_read_native_max(device, retry_count, timeout, ccb,
2554 ident_buf, &hpasize) != 0) {
2561 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR) {
2562 if (ata_get_native_max(device, retry_count, timeout, ccb,
2563 &nativesize) != 0) {
2571 printf("%s%d: ", device->device_name, device->dev_unit_num);
2572 ata_print_ident(ident_buf);
2573 camxferrate(device);
2574 atacapprint(ident_buf);
2575 atahpa_print(ident_buf, hpasize, 0);
2576 ataama_print(ident_buf, nativesize, 0);
2586 nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused)
2588 struct nvme_controller_data cdata;
2590 if (nvme_get_cdata(device, &cdata))
2592 nvme_print_controller(&cdata);
2599 identify(struct cam_device *device, int retry_count, int timeout)
2602 struct ccb_pathinq cpi;
2604 if (get_cpi(device, &cpi) != 0) {
2605 warnx("couldn't get CPI");
2609 if (cpi.protocol == PROTO_NVME) {
2610 return (nvmeidentify(device, retry_count, timeout));
2613 return (ataidentify(device, retry_count, timeout));
2618 ATA_SECURITY_ACTION_PRINT,
2619 ATA_SECURITY_ACTION_FREEZE,
2620 ATA_SECURITY_ACTION_UNLOCK,
2621 ATA_SECURITY_ACTION_DISABLE,
2622 ATA_SECURITY_ACTION_ERASE,
2623 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2624 ATA_SECURITY_ACTION_SET_PASSWORD
2628 atasecurity_print_time(u_int16_t tw)
2632 printf("unspecified");
2634 printf("> 508 min");
2636 printf("%i min", 2 * tw);
2640 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2644 return 2 * 3600 * 1000; /* default: two hours */
2645 else if (timeout > 255)
2646 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2648 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2653 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2657 bzero(&cmd, sizeof(cmd));
2658 cmd.command = command;
2659 printf("Issuing %s", ata_op_string(&cmd));
2662 char pass[sizeof(pwd->password)+1];
2664 /* pwd->password may not be null terminated */
2665 pass[sizeof(pwd->password)] = '\0';
2666 strncpy(pass, pwd->password, sizeof(pwd->password));
2667 printf(" password='%s', user='%s'",
2669 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2672 if (command == ATA_SECURITY_SET_PASSWORD) {
2673 printf(", mode='%s'",
2674 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2675 "maximum" : "high");
2683 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2684 int retry_count, u_int32_t timeout, int quiet)
2688 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2690 return ata_do_28bit_cmd(device,
2693 /*flags*/CAM_DIR_NONE,
2694 /*protocol*/AP_PROTO_NON_DATA,
2695 /*tag_action*/MSG_SIMPLE_Q_TAG,
2696 /*command*/ATA_SECURITY_FREEZE_LOCK,
2707 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2708 int retry_count, u_int32_t timeout,
2709 struct ata_security_password *pwd, int quiet)
2713 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2715 return ata_do_28bit_cmd(device,
2718 /*flags*/CAM_DIR_OUT,
2719 /*protocol*/AP_PROTO_PIO_OUT,
2720 /*tag_action*/MSG_SIMPLE_Q_TAG,
2721 /*command*/ATA_SECURITY_UNLOCK,
2725 /*data_ptr*/(u_int8_t *)pwd,
2726 /*dxfer_len*/sizeof(*pwd),
2732 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2733 int retry_count, u_int32_t timeout,
2734 struct ata_security_password *pwd, int quiet)
2738 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2739 return ata_do_28bit_cmd(device,
2742 /*flags*/CAM_DIR_OUT,
2743 /*protocol*/AP_PROTO_PIO_OUT,
2744 /*tag_action*/MSG_SIMPLE_Q_TAG,
2745 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2749 /*data_ptr*/(u_int8_t *)pwd,
2750 /*dxfer_len*/sizeof(*pwd),
2757 atasecurity_erase_confirm(struct cam_device *device,
2758 struct ata_params* ident_buf)
2761 printf("\nYou are about to ERASE ALL DATA from the following"
2762 " device:\n%s%d,%s%d: ", device->device_name,
2763 device->dev_unit_num, device->given_dev_name,
2764 device->given_unit_number);
2765 ata_print_ident(ident_buf);
2769 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2771 if (fgets(str, sizeof(str), stdin) != NULL) {
2772 if (strncasecmp(str, "yes", 3) == 0) {
2774 } else if (strncasecmp(str, "no", 2) == 0) {
2777 printf("Please answer \"yes\" or "
2788 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2789 int retry_count, u_int32_t timeout,
2790 u_int32_t erase_timeout,
2791 struct ata_security_password *pwd, int quiet)
2796 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2798 error = ata_do_28bit_cmd(device,
2801 /*flags*/CAM_DIR_NONE,
2802 /*protocol*/AP_PROTO_NON_DATA,
2803 /*tag_action*/MSG_SIMPLE_Q_TAG,
2804 /*command*/ATA_SECURITY_ERASE_PREPARE,
2817 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2819 error = ata_do_28bit_cmd(device,
2822 /*flags*/CAM_DIR_OUT,
2823 /*protocol*/AP_PROTO_PIO_OUT,
2824 /*tag_action*/MSG_SIMPLE_Q_TAG,
2825 /*command*/ATA_SECURITY_ERASE_UNIT,
2829 /*data_ptr*/(u_int8_t *)pwd,
2830 /*dxfer_len*/sizeof(*pwd),
2831 /*timeout*/erase_timeout,
2834 if (error == 0 && quiet == 0)
2835 printf("\nErase Complete\n");
2841 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2842 int retry_count, u_int32_t timeout,
2843 struct ata_security_password *pwd, int quiet)
2847 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2849 return ata_do_28bit_cmd(device,
2852 /*flags*/CAM_DIR_OUT,
2853 /*protocol*/AP_PROTO_PIO_OUT,
2854 /*tag_action*/MSG_SIMPLE_Q_TAG,
2855 /*command*/ATA_SECURITY_SET_PASSWORD,
2859 /*data_ptr*/(u_int8_t *)pwd,
2860 /*dxfer_len*/sizeof(*pwd),
2866 atasecurity_print(struct ata_params *parm)
2869 printf("\nSecurity Option Value\n");
2870 if (arglist & CAM_ARG_VERBOSE) {
2871 printf("status %04x\n",
2872 parm->security_status);
2874 printf("supported %s\n",
2875 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2876 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2878 printf("enabled %s\n",
2879 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2880 printf("drive locked %s\n",
2881 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2882 printf("security config frozen %s\n",
2883 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2884 printf("count expired %s\n",
2885 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2886 printf("security level %s\n",
2887 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2888 printf("enhanced erase supported %s\n",
2889 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2890 printf("erase time ");
2891 atasecurity_print_time(parm->erase_time);
2893 printf("enhanced erase time ");
2894 atasecurity_print_time(parm->enhanced_erase_time);
2896 printf("master password rev %04x%s\n",
2897 parm->master_passwd_revision,
2898 parm->master_passwd_revision == 0x0000 ||
2899 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2903 * Validates and copies the password in optarg to the passed buffer.
2904 * If the password in optarg is the same length as the buffer then
2905 * the data will still be copied but no null termination will occur.
2908 ata_getpwd(u_int8_t *passwd, int max, char opt)
2912 len = strlen(optarg);
2914 warnx("-%c password is too long", opt);
2916 } else if (len == 0) {
2917 warnx("-%c password is missing", opt);
2919 } else if (optarg[0] == '-'){
2920 warnx("-%c password starts with '-' (generic arg?)", opt);
2922 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2923 warnx("-%c password conflicts with existing password from -%c",
2928 /* Callers pass in a buffer which does NOT need to be terminated */
2929 strncpy(passwd, optarg, max);
2936 ATA_HPA_ACTION_PRINT,
2937 ATA_HPA_ACTION_SET_MAX,
2938 ATA_HPA_ACTION_SET_PWD,
2939 ATA_HPA_ACTION_LOCK,
2940 ATA_HPA_ACTION_UNLOCK,
2941 ATA_HPA_ACTION_FREEZE_LOCK
2945 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2946 u_int64_t maxsize, int persist)
2948 printf("\nYou are about to configure HPA to limit the user accessible\n"
2949 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2950 persist ? "persistently" : "temporarily",
2951 device->device_name, device->dev_unit_num,
2952 device->given_dev_name, device->given_unit_number);
2953 ata_print_ident(ident_buf);
2957 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2959 if (NULL != fgets(str, sizeof(str), stdin)) {
2960 if (0 == strncasecmp(str, "yes", 3)) {
2962 } else if (0 == strncasecmp(str, "no", 2)) {
2965 printf("Please answer \"yes\" or "
2976 atahpa(struct cam_device *device, int retry_count, int timeout,
2977 int argc, char **argv, char *combinedopt)
2980 struct ata_params *ident_buf;
2981 struct ccb_getdev cgd;
2982 struct ata_set_max_pwd pwd;
2983 int error, confirm, quiet, c, action, actions, persist;
2984 int security, is48bit, pwdsize;
2985 u_int64_t hpasize, maxsize;
2994 memset(&pwd, 0, sizeof(pwd));
2996 /* default action is to print hpa information */
2997 action = ATA_HPA_ACTION_PRINT;
2998 pwdsize = sizeof(pwd.password);
3000 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3003 action = ATA_HPA_ACTION_SET_MAX;
3004 maxsize = strtoumax(optarg, NULL, 0);
3009 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3011 action = ATA_HPA_ACTION_SET_PWD;
3017 action = ATA_HPA_ACTION_LOCK;
3023 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3025 action = ATA_HPA_ACTION_UNLOCK;
3031 action = ATA_HPA_ACTION_FREEZE_LOCK;
3051 warnx("too many hpa actions specified");
3055 if (get_cgd(device, &cgd) != 0) {
3056 warnx("couldn't get CGD");
3060 ccb = cam_getccb(device);
3062 warnx("couldn't allocate CCB");
3066 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3073 printf("%s%d: ", device->device_name, device->dev_unit_num);
3074 ata_print_ident(ident_buf);
3075 camxferrate(device);
3078 if (action == ATA_HPA_ACTION_PRINT) {
3079 error = ata_read_native_max(device, retry_count, timeout, ccb,
3080 ident_buf, &hpasize);
3082 atahpa_print(ident_buf, hpasize, 1);
3089 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
3090 warnx("HPA is not supported by this device");
3096 if (security && !(ident_buf->support.command2 & ATA_SUPPORT_MAXSECURITY)) {
3097 warnx("HPA Security is not supported by this device");
3103 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
3106 * The ATA spec requires:
3107 * 1. Read native max addr is called directly before set max addr
3108 * 2. Read native max addr is NOT called before any other set max call
3111 case ATA_HPA_ACTION_SET_MAX:
3113 atahpa_set_confirm(device, ident_buf, maxsize,
3120 error = ata_read_native_max(device, retry_count, timeout,
3121 ccb, ident_buf, &hpasize);
3123 error = atahpa_set_max(device, retry_count, timeout,
3124 ccb, is48bit, maxsize, persist);
3125 if (error == 0 && quiet == 0) {
3126 /* redo identify to get new lba values */
3127 error = ata_do_identify(device, retry_count,
3130 atahpa_print(ident_buf, hpasize, 1);
3131 /* Hint CAM to reprobe the device. */
3137 case ATA_HPA_ACTION_SET_PWD:
3138 error = atahpa_password(device, retry_count, timeout,
3139 ccb, is48bit, &pwd);
3140 if (error == 0 && quiet == 0)
3141 printf("HPA password has been set\n");
3144 case ATA_HPA_ACTION_LOCK:
3145 error = atahpa_lock(device, retry_count, timeout,
3147 if (error == 0 && quiet == 0)
3148 printf("HPA has been locked\n");
3151 case ATA_HPA_ACTION_UNLOCK:
3152 error = atahpa_unlock(device, retry_count, timeout,
3153 ccb, is48bit, &pwd);
3154 if (error == 0 && quiet == 0)
3155 printf("HPA has been unlocked\n");
3158 case ATA_HPA_ACTION_FREEZE_LOCK:
3159 error = atahpa_freeze_lock(device, retry_count, timeout,
3161 if (error == 0 && quiet == 0)
3162 printf("HPA has been frozen\n");
3166 errx(1, "Option currently not supported");
3176 ATA_AMA_ACTION_PRINT,
3177 ATA_AMA_ACTION_SET_MAX,
3178 ATA_AMA_ACTION_FREEZE_LOCK
3182 ataama(struct cam_device *device, int retry_count, int timeout,
3183 int argc, char **argv, char *combinedopt)
3186 struct ata_params *ident_buf;
3187 struct ccb_getdev cgd;
3188 int error, quiet, c, action, actions;
3189 u_int64_t nativesize, maxsize;
3195 /* default action is to print AMA information */
3196 action = ATA_AMA_ACTION_PRINT;
3198 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3201 action = ATA_AMA_ACTION_SET_MAX;
3202 maxsize = strtoumax(optarg, NULL, 0);
3207 action = ATA_AMA_ACTION_FREEZE_LOCK;
3218 warnx("too many AMA actions specified");
3222 if (get_cgd(device, &cgd) != 0) {
3223 warnx("couldn't get CGD");
3227 ccb = cam_getccb(device);
3229 warnx("couldn't allocate CCB");
3233 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3240 printf("%s%d: ", device->device_name, device->dev_unit_num);
3241 ata_print_ident(ident_buf);
3242 camxferrate(device);
3245 if (action == ATA_AMA_ACTION_PRINT) {
3246 error = ata_get_native_max(device, retry_count, timeout, ccb,
3249 ataama_print(ident_buf, nativesize, 1);
3256 if (!(ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)) {
3257 warnx("Accessible Max Address is not supported by this device");
3264 case ATA_AMA_ACTION_SET_MAX:
3265 error = ata_get_native_max(device, retry_count, timeout, ccb,
3268 error = ataama_set(device, retry_count, timeout,
3270 if (error == 0 && quiet == 0) {
3271 /* redo identify to get new lba values */
3272 error = ata_do_identify(device, retry_count,
3273 timeout, ccb, &ident_buf);
3274 ataama_print(ident_buf, nativesize, 1);
3275 /* Hint CAM to reprobe the device. */
3281 case ATA_AMA_ACTION_FREEZE_LOCK:
3282 error = ataama_freeze(device, retry_count, timeout,
3284 if (error == 0 && quiet == 0)
3285 printf("Accessible Max Address has been frozen\n");
3289 errx(1, "Option currently not supported");
3299 atasecurity(struct cam_device *device, int retry_count, int timeout,
3300 int argc, char **argv, char *combinedopt)
3303 struct ata_params *ident_buf;
3304 int error, confirm, quiet, c, action, actions, setpwd;
3305 int security_enabled, erase_timeout, pwdsize;
3306 struct ata_security_password pwd;
3314 memset(&pwd, 0, sizeof(pwd));
3316 /* default action is to print security information */
3317 action = ATA_SECURITY_ACTION_PRINT;
3319 /* user is master by default as its safer that way */
3320 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3321 pwdsize = sizeof(pwd.password);
3323 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3326 action = ATA_SECURITY_ACTION_FREEZE;
3331 if (strcasecmp(optarg, "user") == 0) {
3332 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
3333 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
3334 } else if (strcasecmp(optarg, "master") == 0) {
3335 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3336 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
3338 warnx("-U argument '%s' is invalid (must be "
3339 "'user' or 'master')", optarg);
3345 if (strcasecmp(optarg, "high") == 0) {
3346 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3347 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3348 } else if (strcasecmp(optarg, "maximum") == 0) {
3349 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3350 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3352 warnx("-l argument '%s' is unknown (must be "
3353 "'high' or 'maximum')", optarg);
3359 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3361 action = ATA_SECURITY_ACTION_UNLOCK;
3366 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3368 action = ATA_SECURITY_ACTION_DISABLE;
3373 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3375 action = ATA_SECURITY_ACTION_ERASE;
3380 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3382 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3383 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3388 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3391 if (action == ATA_SECURITY_ACTION_PRINT)
3392 action = ATA_SECURITY_ACTION_SET_PASSWORD;
3394 * Don't increment action as this can be combined
3395 * with other actions.
3408 erase_timeout = atoi(optarg) * 1000;
3414 warnx("too many security actions specified");
3418 if ((ccb = cam_getccb(device)) == NULL) {
3419 warnx("couldn't allocate CCB");
3423 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3430 printf("%s%d: ", device->device_name, device->dev_unit_num);
3431 ata_print_ident(ident_buf);
3432 camxferrate(device);
3435 if (action == ATA_SECURITY_ACTION_PRINT) {
3436 atasecurity_print(ident_buf);
3442 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3443 warnx("Security not supported");
3449 /* default timeout 15 seconds the same as linux hdparm */
3450 timeout = timeout ? timeout : 15 * 1000;
3452 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3454 /* first set the password if requested */
3456 /* confirm we can erase before setting the password if erasing */
3458 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3459 action == ATA_SECURITY_ACTION_ERASE) &&
3460 atasecurity_erase_confirm(device, ident_buf) == 0) {
3466 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3467 pwd.revision = ident_buf->master_passwd_revision;
3468 if (pwd.revision != 0 && pwd.revision != 0xfff &&
3469 --pwd.revision == 0) {
3470 pwd.revision = 0xfffe;
3473 error = atasecurity_set_password(device, ccb, retry_count,
3474 timeout, &pwd, quiet);
3480 security_enabled = 1;
3484 case ATA_SECURITY_ACTION_FREEZE:
3485 error = atasecurity_freeze(device, ccb, retry_count,
3489 case ATA_SECURITY_ACTION_UNLOCK:
3490 if (security_enabled) {
3491 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3492 error = atasecurity_unlock(device, ccb,
3493 retry_count, timeout, &pwd, quiet);
3495 warnx("Can't unlock, drive is not locked");
3499 warnx("Can't unlock, security is disabled");
3504 case ATA_SECURITY_ACTION_DISABLE:
3505 if (security_enabled) {
3506 /* First unlock the drive if its locked */
3507 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3508 error = atasecurity_unlock(device, ccb,
3516 error = atasecurity_disable(device,
3524 warnx("Can't disable security (already disabled)");
3529 case ATA_SECURITY_ACTION_ERASE:
3530 if (security_enabled) {
3531 if (erase_timeout == 0) {
3532 erase_timeout = atasecurity_erase_timeout_msecs(
3533 ident_buf->erase_time);
3536 error = atasecurity_erase(device, ccb, retry_count,
3537 timeout, erase_timeout, &pwd, quiet);
3539 warnx("Can't secure erase (security is disabled)");
3544 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3545 if (security_enabled) {
3546 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3547 if (erase_timeout == 0) {
3549 atasecurity_erase_timeout_msecs(
3550 ident_buf->enhanced_erase_time);
3553 error = atasecurity_erase(device, ccb,
3554 retry_count, timeout,
3555 erase_timeout, &pwd,
3558 warnx("Enhanced erase is not supported");
3562 warnx("Can't secure erase (enhanced), "
3563 "(security is disabled)");
3576 * Convert periph name into a bus, target and lun.
3578 * Returns the number of parsed components, or 0.
3581 parse_btl_name(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3582 cam_argmask *arglst)
3587 bzero(&ccb, sizeof(ccb));
3588 ccb.ccb_h.func_code = XPT_GDEVLIST;
3589 if (cam_get_device(tstr, ccb.cgdl.periph_name,
3590 sizeof(ccb.cgdl.periph_name), &ccb.cgdl.unit_number) == -1) {
3591 warnx("%s", cam_errbuf);
3596 * Attempt to get the passthrough device. This ioctl will
3597 * fail if the device name is null, if the device doesn't
3598 * exist, or if the passthrough driver isn't in the kernel.
3600 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3601 warn("Unable to open %s", XPT_DEVICE);
3604 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3605 warn("Unable to find bus:target:lun for device %s%d",
3606 ccb.cgdl.periph_name, ccb.cgdl.unit_number);
3611 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3612 const struct cam_status_entry *entry;
3614 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3615 warnx("Unable to find bus:target_lun for device %s%d, "
3616 "CAM status: %s (%#x)",
3617 ccb.cgdl.periph_name, ccb.cgdl.unit_number,
3618 entry ? entry->status_text : "Unknown",
3624 * The kernel fills in the bus/target/lun. We don't
3625 * need the passthrough device name and unit number since
3626 * we aren't going to open it.
3628 *bus = ccb.ccb_h.path_id;
3629 *target = ccb.ccb_h.target_id;
3630 *lun = ccb.ccb_h.target_lun;
3631 *arglst |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3636 * Parse out a bus, or a bus, target and lun in the following
3642 * Returns the number of parsed components, or 0.
3645 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3646 cam_argmask *arglst)
3651 *bus = CAM_BUS_WILDCARD;
3652 *target = CAM_TARGET_WILDCARD;
3653 *lun = CAM_LUN_WILDCARD;
3655 while (isspace(*tstr) && (*tstr != '\0'))
3658 if (strncasecmp(tstr, "all", strlen("all")) == 0) {
3659 arglist |= CAM_ARG_BUS;
3663 if (!isdigit(*tstr))
3664 return (parse_btl_name(tstr, bus, target, lun, arglst));
3666 tmpstr = strsep(&tstr, ":");
3667 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3668 *bus = strtol(tmpstr, &end, 0);
3671 *arglst |= CAM_ARG_BUS;
3673 tmpstr = strsep(&tstr, ":");
3674 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3675 *target = strtol(tmpstr, &end, 0);
3678 *arglst |= CAM_ARG_TARGET;
3680 tmpstr = strsep(&tstr, ":");
3681 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3682 *lun = strtoll(tmpstr, &end, 0);
3685 *arglst |= CAM_ARG_LUN;
3695 dorescan_or_reset(int argc, char **argv, int rescan)
3697 static const char must[] =
3698 "you must specify \"all\", a bus, a bus:target:lun or periph to %s";
3700 path_id_t bus = CAM_BUS_WILDCARD;
3701 target_id_t target = CAM_TARGET_WILDCARD;
3702 lun_id_t lun = CAM_LUN_WILDCARD;
3706 warnx(must, rescan? "rescan" : "reset");
3710 tstr = argv[optind];
3711 while (isspace(*tstr) && (*tstr != '\0'))
3713 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3714 arglist |= CAM_ARG_BUS;
3716 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3717 if (rv != 1 && rv != 3) {
3718 warnx(must, rescan ? "rescan" : "reset");
3723 if (arglist & CAM_ARG_LUN)
3724 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3726 error = rescan_or_reset_bus(bus, rescan);
3732 rescan_or_reset_bus(path_id_t bus, int rescan)
3734 union ccb *ccb = NULL, *matchccb = NULL;
3735 int fd = -1, retval;
3740 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3741 warnx("error opening transport layer device %s", XPT_DEVICE);
3742 warn("%s", XPT_DEVICE);
3746 ccb = malloc(sizeof(*ccb));
3748 warn("failed to allocate CCB");
3752 bzero(ccb, sizeof(*ccb));
3754 if (bus != CAM_BUS_WILDCARD) {
3755 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3756 ccb->ccb_h.path_id = bus;
3757 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3758 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3759 ccb->crcn.flags = CAM_FLAG_NONE;
3761 /* run this at a low priority */
3762 ccb->ccb_h.pinfo.priority = 5;
3764 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3765 warn("CAMIOCOMMAND ioctl failed");
3770 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3771 fprintf(stdout, "%s of bus %d was successful\n",
3772 rescan ? "Re-scan" : "Reset", bus);
3774 fprintf(stdout, "%s of bus %d returned error %#x\n",
3775 rescan ? "Re-scan" : "Reset", bus,
3776 ccb->ccb_h.status & CAM_STATUS_MASK);
3785 * The right way to handle this is to modify the xpt so that it can
3786 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3787 * that isn't implemented, so instead we enumerate the buses and
3788 * send the rescan or reset to those buses in the case where the
3789 * given bus is -1 (wildcard). We don't send a rescan or reset
3790 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3791 * no-op, sending a rescan to the xpt bus would result in a status of
3794 matchccb = malloc(sizeof(*matchccb));
3795 if (matchccb == NULL) {
3796 warn("failed to allocate CCB");
3800 bzero(matchccb, sizeof(*matchccb));
3801 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3802 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3803 bufsize = sizeof(struct dev_match_result) * 20;
3804 matchccb->cdm.match_buf_len = bufsize;
3805 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3806 if (matchccb->cdm.matches == NULL) {
3807 warnx("can't malloc memory for matches");
3811 matchccb->cdm.num_matches = 0;
3813 matchccb->cdm.num_patterns = 1;
3814 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3816 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3817 matchccb->cdm.pattern_buf_len);
3818 if (matchccb->cdm.patterns == NULL) {
3819 warnx("can't malloc memory for patterns");
3823 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3824 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3829 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3830 warn("CAMIOCOMMAND ioctl failed");
3835 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3836 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3837 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3838 warnx("got CAM error %#x, CDM error %d\n",
3839 matchccb->ccb_h.status, matchccb->cdm.status);
3844 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3845 struct bus_match_result *bus_result;
3847 /* This shouldn't happen. */
3848 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3851 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3854 * We don't want to rescan or reset the xpt bus.
3857 if (bus_result->path_id == CAM_XPT_PATH_ID)
3860 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3862 ccb->ccb_h.path_id = bus_result->path_id;
3863 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3864 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3865 ccb->crcn.flags = CAM_FLAG_NONE;
3867 /* run this at a low priority */
3868 ccb->ccb_h.pinfo.priority = 5;
3870 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3871 warn("CAMIOCOMMAND ioctl failed");
3876 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3877 fprintf(stdout, "%s of bus %d was successful\n",
3878 rescan? "Re-scan" : "Reset",
3879 bus_result->path_id);
3882 * Don't bail out just yet, maybe the other
3883 * rescan or reset commands will complete
3886 fprintf(stderr, "%s of bus %d returned error "
3887 "%#x\n", rescan? "Re-scan" : "Reset",
3888 bus_result->path_id,
3889 ccb->ccb_h.status & CAM_STATUS_MASK);
3893 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3894 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3901 if (matchccb != NULL) {
3902 free(matchccb->cdm.patterns);
3903 free(matchccb->cdm.matches);
3912 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3915 struct cam_device *device;
3920 if (bus == CAM_BUS_WILDCARD) {
3921 warnx("invalid bus number %d", bus);
3925 if (target == CAM_TARGET_WILDCARD) {
3926 warnx("invalid target number %d", target);
3930 if (lun == CAM_LUN_WILDCARD) {
3931 warnx("invalid lun number %jx", (uintmax_t)lun);
3937 bzero(&ccb, sizeof(union ccb));
3940 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3941 warnx("error opening transport layer device %s\n",
3943 warn("%s", XPT_DEVICE);
3947 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3948 if (device == NULL) {
3949 warnx("%s", cam_errbuf);
3954 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3955 ccb.ccb_h.path_id = bus;
3956 ccb.ccb_h.target_id = target;
3957 ccb.ccb_h.target_lun = lun;
3958 ccb.ccb_h.timeout = 5000;
3959 ccb.crcn.flags = CAM_FLAG_NONE;
3961 /* run this at a low priority */
3962 ccb.ccb_h.pinfo.priority = 5;
3965 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3966 warn("CAMIOCOMMAND ioctl failed");
3971 if (cam_send_ccb(device, &ccb) < 0) {
3972 warn("error sending XPT_RESET_DEV CCB");
3973 cam_close_device(device);
3981 cam_close_device(device);
3984 * An error code of CAM_BDR_SENT is normal for a BDR request.
3986 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3988 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3989 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3990 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3993 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3994 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3995 ccb.ccb_h.status & CAM_STATUS_MASK);
4001 static struct scsi_nv defect_list_type_map[] = {
4002 { "block", SRDD10_BLOCK_FORMAT },
4003 { "extbfi", SRDD10_EXT_BFI_FORMAT },
4004 { "extphys", SRDD10_EXT_PHYS_FORMAT },
4005 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
4006 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
4007 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
4011 readdefects(struct cam_device *device, int argc, char **argv,
4012 char *combinedopt, int task_attr, int retry_count, int timeout)
4014 union ccb *ccb = NULL;
4015 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
4016 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
4017 size_t hdr_size = 0, entry_size = 0;
4020 u_int8_t *defect_list = NULL;
4021 u_int8_t list_format = 0;
4022 int list_type_set = 0;
4023 u_int32_t dlist_length = 0;
4024 u_int32_t returned_length = 0, valid_len = 0;
4025 u_int32_t num_returned = 0, num_valid = 0;
4026 u_int32_t max_possible_size = 0, hdr_max = 0;
4027 u_int32_t starting_offset = 0;
4028 u_int8_t returned_format, returned_type;
4030 int summary = 0, quiet = 0;
4032 int lists_specified = 0;
4033 int get_length = 1, first_pass = 1;
4036 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4040 scsi_nv_status status;
4043 status = scsi_get_nv(defect_list_type_map,
4044 sizeof(defect_list_type_map) /
4045 sizeof(defect_list_type_map[0]), optarg,
4046 &entry_num, SCSI_NV_FLAG_IG_CASE);
4048 if (status == SCSI_NV_FOUND) {
4049 list_format = defect_list_type_map[
4053 warnx("%s: %s %s option %s", __func__,
4054 (status == SCSI_NV_AMBIGUOUS) ?
4055 "ambiguous" : "invalid", "defect list type",
4058 goto defect_bailout;
4063 arglist |= CAM_ARG_GLIST;
4066 arglist |= CAM_ARG_PLIST;
4077 starting_offset = strtoul(optarg, &endptr, 0);
4078 if (*endptr != '\0') {
4080 warnx("invalid starting offset %s", optarg);
4081 goto defect_bailout;
4093 if (list_type_set == 0) {
4095 warnx("no defect list format specified");
4096 goto defect_bailout;
4099 if (arglist & CAM_ARG_PLIST) {
4100 list_format |= SRDD10_PLIST;
4104 if (arglist & CAM_ARG_GLIST) {
4105 list_format |= SRDD10_GLIST;
4110 * This implies a summary, and was the previous behavior.
4112 if (lists_specified == 0)
4115 ccb = cam_getccb(device);
4120 * We start off asking for just the header to determine how much
4121 * defect data is available. Some Hitachi drives return an error
4122 * if you ask for more data than the drive has. Once we know the
4123 * length, we retry the command with the returned length.
4125 if (use_12byte == 0)
4126 dlist_length = sizeof(*hdr10);
4128 dlist_length = sizeof(*hdr12);
4131 if (defect_list != NULL) {
4135 defect_list = malloc(dlist_length);
4136 if (defect_list == NULL) {
4137 warnx("can't malloc memory for defect list");
4139 goto defect_bailout;
4143 bzero(defect_list, dlist_length);
4146 * cam_getccb() zeros the CCB header only. So we need to zero the
4147 * payload portion of the ccb.
4149 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4151 scsi_read_defects(&ccb->csio,
4152 /*retries*/ retry_count,
4154 /*tag_action*/ task_attr,
4155 /*list_format*/ list_format,
4156 /*addr_desc_index*/ starting_offset,
4157 /*data_ptr*/ defect_list,
4158 /*dxfer_len*/ dlist_length,
4159 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
4160 /*sense_len*/ SSD_FULL_SIZE,
4161 /*timeout*/ timeout ? timeout : 5000);
4163 /* Disable freezing the device queue */
4164 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4166 if (cam_send_ccb(device, ccb) < 0) {
4167 perror("error reading defect list");
4169 if (arglist & CAM_ARG_VERBOSE) {
4170 cam_error_print(device, ccb, CAM_ESF_ALL,
4171 CAM_EPF_ALL, stderr);
4175 goto defect_bailout;
4178 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
4180 if (use_12byte == 0) {
4181 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
4182 hdr_size = sizeof(*hdr10);
4183 hdr_max = SRDDH10_MAX_LENGTH;
4185 if (valid_len >= hdr_size) {
4186 returned_length = scsi_2btoul(hdr10->length);
4187 returned_format = hdr10->format;
4189 returned_length = 0;
4190 returned_format = 0;
4193 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
4194 hdr_size = sizeof(*hdr12);
4195 hdr_max = SRDDH12_MAX_LENGTH;
4197 if (valid_len >= hdr_size) {
4198 returned_length = scsi_4btoul(hdr12->length);
4199 returned_format = hdr12->format;
4201 returned_length = 0;
4202 returned_format = 0;
4206 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
4207 switch (returned_type) {
4208 case SRDD10_BLOCK_FORMAT:
4209 entry_size = sizeof(struct scsi_defect_desc_block);
4211 case SRDD10_LONG_BLOCK_FORMAT:
4212 entry_size = sizeof(struct scsi_defect_desc_long_block);
4214 case SRDD10_EXT_PHYS_FORMAT:
4215 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4216 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
4218 case SRDD10_EXT_BFI_FORMAT:
4219 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4220 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
4223 warnx("Unknown defect format 0x%x\n", returned_type);
4225 goto defect_bailout;
4229 max_possible_size = (hdr_max / entry_size) * entry_size;
4230 num_returned = returned_length / entry_size;
4231 num_valid = min(returned_length, valid_len - hdr_size);
4232 num_valid /= entry_size;
4234 if (get_length != 0) {
4237 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
4238 CAM_SCSI_STATUS_ERROR) {
4239 struct scsi_sense_data *sense;
4240 int error_code, sense_key, asc, ascq;
4242 sense = &ccb->csio.sense_data;
4243 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4244 ccb->csio.sense_resid, &error_code, &sense_key,
4245 &asc, &ascq, /*show_errors*/ 1);
4248 * If the drive is reporting that it just doesn't
4249 * support the defect list format, go ahead and use
4250 * the length it reported. Otherwise, the length
4251 * may not be valid, so use the maximum.
4253 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4254 && (asc == 0x1c) && (ascq == 0x00)
4255 && (returned_length > 0)) {
4256 if ((use_12byte == 0)
4257 && (returned_length >= max_possible_size)) {
4262 dlist_length = returned_length + hdr_size;
4263 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4264 && (asc == 0x1f) && (ascq == 0x00)
4265 && (returned_length > 0)) {
4266 /* Partial defect list transfer */
4268 * Hitachi drives return this error
4269 * along with a partial defect list if they
4270 * have more defects than the 10 byte
4271 * command can support. Retry with the 12
4274 if (use_12byte == 0) {
4279 dlist_length = returned_length + hdr_size;
4280 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
4281 && (asc == 0x24) && (ascq == 0x00)) {
4282 /* Invalid field in CDB */
4284 * SBC-3 says that if the drive has more
4285 * defects than can be reported with the
4286 * 10 byte command, it should return this
4287 * error and no data. Retry with the 12
4290 if (use_12byte == 0) {
4295 dlist_length = returned_length + hdr_size;
4298 * If we got a SCSI error and no valid length,
4299 * just use the 10 byte maximum. The 12
4300 * byte maximum is too large.
4302 if (returned_length == 0)
4303 dlist_length = SRDD10_MAX_LENGTH;
4305 if ((use_12byte == 0)
4306 && (returned_length >=
4307 max_possible_size)) {
4312 dlist_length = returned_length +
4316 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4319 warnx("Error reading defect header");
4320 if (arglist & CAM_ARG_VERBOSE)
4321 cam_error_print(device, ccb, CAM_ESF_ALL,
4322 CAM_EPF_ALL, stderr);
4323 goto defect_bailout;
4325 if ((use_12byte == 0)
4326 && (returned_length >= max_possible_size)) {
4331 dlist_length = returned_length + hdr_size;
4334 fprintf(stdout, "%u", num_returned);
4336 fprintf(stdout, " defect%s",
4337 (num_returned != 1) ? "s" : "");
4339 fprintf(stdout, "\n");
4341 goto defect_bailout;
4345 * We always limit the list length to the 10-byte maximum
4346 * length (0xffff). The reason is that some controllers
4347 * can't handle larger I/Os, and we can transfer the entire
4348 * 10 byte list in one shot. For drives that support the 12
4349 * byte read defects command, we'll step through the list
4350 * by specifying a starting offset. For drives that don't
4351 * support the 12 byte command's starting offset, we'll
4352 * just display the first 64K.
4354 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4360 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4361 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4362 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4363 struct scsi_sense_data *sense;
4364 int error_code, sense_key, asc, ascq;
4366 sense = &ccb->csio.sense_data;
4367 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4368 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4369 &ascq, /*show_errors*/ 1);
4372 * According to the SCSI spec, if the disk doesn't support
4373 * the requested format, it will generally return a sense
4374 * key of RECOVERED ERROR, and an additional sense code
4375 * of "DEFECT LIST NOT FOUND". HGST drives also return
4376 * Primary/Grown defect list not found errors. So just
4377 * check for an ASC of 0x1c.
4379 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4381 const char *format_str;
4383 format_str = scsi_nv_to_str(defect_list_type_map,
4384 sizeof(defect_list_type_map) /
4385 sizeof(defect_list_type_map[0]),
4386 list_format & SRDD10_DLIST_FORMAT_MASK);
4387 warnx("requested defect format %s not available",
4388 format_str ? format_str : "unknown");
4390 format_str = scsi_nv_to_str(defect_list_type_map,
4391 sizeof(defect_list_type_map) /
4392 sizeof(defect_list_type_map[0]), returned_type);
4393 if (format_str != NULL) {
4394 warnx("Device returned %s format",
4398 warnx("Device returned unknown defect"
4399 " data format %#x", returned_type);
4400 goto defect_bailout;
4404 warnx("Error returned from read defect data command");
4405 if (arglist & CAM_ARG_VERBOSE)
4406 cam_error_print(device, ccb, CAM_ESF_ALL,
4407 CAM_EPF_ALL, stderr);
4408 goto defect_bailout;
4410 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4412 warnx("Error returned from read defect data command");
4413 if (arglist & CAM_ARG_VERBOSE)
4414 cam_error_print(device, ccb, CAM_ESF_ALL,
4415 CAM_EPF_ALL, stderr);
4416 goto defect_bailout;
4419 if (first_pass != 0) {
4420 fprintf(stderr, "Got %d defect", num_returned);
4422 if ((lists_specified == 0) || (num_returned == 0)) {
4423 fprintf(stderr, "s.\n");
4424 goto defect_bailout;
4425 } else if (num_returned == 1)
4426 fprintf(stderr, ":\n");
4428 fprintf(stderr, "s:\n");
4434 * XXX KDM I should probably clean up the printout format for the
4437 switch (returned_type) {
4438 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4439 case SRDD10_EXT_PHYS_FORMAT:
4441 struct scsi_defect_desc_phys_sector *dlist;
4443 dlist = (struct scsi_defect_desc_phys_sector *)
4444 (defect_list + hdr_size);
4446 for (i = 0; i < num_valid; i++) {
4449 sector = scsi_4btoul(dlist[i].sector);
4450 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4451 mads = (sector & SDD_EXT_PHYS_MADS) ?
4453 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4455 if (hex_format == 0)
4456 fprintf(stdout, "%d:%d:%d%s",
4457 scsi_3btoul(dlist[i].cylinder),
4459 scsi_4btoul(dlist[i].sector),
4460 mads ? " - " : "\n");
4462 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4463 scsi_3btoul(dlist[i].cylinder),
4465 scsi_4btoul(dlist[i].sector),
4466 mads ? " - " : "\n");
4469 if (num_valid < num_returned) {
4470 starting_offset += num_valid;
4475 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4476 case SRDD10_EXT_BFI_FORMAT:
4478 struct scsi_defect_desc_bytes_from_index *dlist;
4480 dlist = (struct scsi_defect_desc_bytes_from_index *)
4481 (defect_list + hdr_size);
4483 for (i = 0; i < num_valid; i++) {
4486 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4487 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4488 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4489 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4491 if (hex_format == 0)
4492 fprintf(stdout, "%d:%d:%d%s",
4493 scsi_3btoul(dlist[i].cylinder),
4495 scsi_4btoul(dlist[i].bytes_from_index),
4496 mads ? " - " : "\n");
4498 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4499 scsi_3btoul(dlist[i].cylinder),
4501 scsi_4btoul(dlist[i].bytes_from_index),
4502 mads ? " - " : "\n");
4506 if (num_valid < num_returned) {
4507 starting_offset += num_valid;
4512 case SRDDH10_BLOCK_FORMAT:
4514 struct scsi_defect_desc_block *dlist;
4516 dlist = (struct scsi_defect_desc_block *)
4517 (defect_list + hdr_size);
4519 for (i = 0; i < num_valid; i++) {
4520 if (hex_format == 0)
4521 fprintf(stdout, "%u\n",
4522 scsi_4btoul(dlist[i].address));
4524 fprintf(stdout, "0x%x\n",
4525 scsi_4btoul(dlist[i].address));
4528 if (num_valid < num_returned) {
4529 starting_offset += num_valid;
4535 case SRDD10_LONG_BLOCK_FORMAT:
4537 struct scsi_defect_desc_long_block *dlist;
4539 dlist = (struct scsi_defect_desc_long_block *)
4540 (defect_list + hdr_size);
4542 for (i = 0; i < num_valid; i++) {
4543 if (hex_format == 0)
4544 fprintf(stdout, "%ju\n",
4545 (uintmax_t)scsi_8btou64(
4548 fprintf(stdout, "0x%jx\n",
4549 (uintmax_t)scsi_8btou64(
4553 if (num_valid < num_returned) {
4554 starting_offset += num_valid;
4560 fprintf(stderr, "Unknown defect format 0x%x\n",
4567 if (defect_list != NULL)
4578 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4582 ccb = cam_getccb(device);
4589 mode_sense(struct cam_device *device, int *cdb_len, int dbd, int pc, int page,
4590 int subpage, int task_attr, int retry_count, int timeout, u_int8_t *data,
4594 int error_code, sense_key, asc, ascq;
4596 ccb = cam_getccb(device);
4598 errx(1, "mode_sense: couldn't allocate CCB");
4602 * MODE SENSE(6) can't handle more then 255 bytes. If there are more,
4603 * device must return error, so we should not get trucated data.
4605 if (*cdb_len == 6 && datalen > 255)
4608 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4610 scsi_mode_sense_subpage(&ccb->csio,
4611 /* retries */ retry_count,
4613 /* tag_action */ task_attr,
4617 /* subpage */ subpage,
4618 /* param_buf */ data,
4619 /* param_len */ datalen,
4620 /* minimum_cmd_size */ *cdb_len,
4621 /* sense_len */ SSD_FULL_SIZE,
4622 /* timeout */ timeout ? timeout : 5000);
4624 /* Record what CDB size the above function really set. */
4625 *cdb_len = ccb->csio.cdb_len;
4627 if (arglist & CAM_ARG_ERR_RECOVER)
4628 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4630 /* Disable freezing the device queue */
4631 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4633 if (cam_send_ccb(device, ccb) < 0)
4634 err(1, "error sending mode sense command");
4636 /* In case of ILLEGEL REQUEST try to fall back to 6-byte command. */
4637 if (*cdb_len != 6 &&
4638 ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID ||
4639 (scsi_extract_sense_ccb(ccb, &error_code, &sense_key, &asc, &ascq)
4640 && sense_key == SSD_KEY_ILLEGAL_REQUEST))) {
4645 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4646 if (arglist & CAM_ARG_VERBOSE) {
4647 cam_error_print(device, ccb, CAM_ESF_ALL,
4648 CAM_EPF_ALL, stderr);
4651 cam_close_device(device);
4652 errx(1, "mode sense command returned error");
4659 mode_select(struct cam_device *device, int cdb_len, int save_pages,
4660 int task_attr, int retry_count, int timeout, u_int8_t *data, int datalen)
4665 ccb = cam_getccb(device);
4668 errx(1, "mode_select: couldn't allocate CCB");
4670 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4672 scsi_mode_select_len(&ccb->csio,
4673 /* retries */ retry_count,
4675 /* tag_action */ task_attr,
4676 /* scsi_page_fmt */ 1,
4677 /* save_pages */ save_pages,
4678 /* param_buf */ data,
4679 /* param_len */ datalen,
4680 /* minimum_cmd_size */ cdb_len,
4681 /* sense_len */ SSD_FULL_SIZE,
4682 /* timeout */ timeout ? timeout : 5000);
4684 if (arglist & CAM_ARG_ERR_RECOVER)
4685 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4687 /* Disable freezing the device queue */
4688 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4690 if (((retval = cam_send_ccb(device, ccb)) < 0)
4691 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4692 if (arglist & CAM_ARG_VERBOSE) {
4693 cam_error_print(device, ccb, CAM_ESF_ALL,
4694 CAM_EPF_ALL, stderr);
4697 cam_close_device(device);
4700 err(1, "error sending mode select command");
4702 errx(1, "error sending mode select command");
4710 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4711 int task_attr, int retry_count, int timeout)
4714 int c, page = -1, subpage = -1, pc = 0;
4715 int binary = 0, cdb_len = 10, dbd = 0, edit = 0, list = 0;
4717 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4735 str_subpage = optarg;
4736 strsep(&str_subpage, ",");
4737 page = strtol(optarg, NULL, 0);
4739 subpage = strtol(str_subpage, NULL, 0);
4743 errx(1, "invalid mode page %d", page);
4745 errx(1, "invalid mode subpage %d", subpage);
4748 pc = strtol(optarg, NULL, 0);
4749 if ((pc < 0) || (pc > 3))
4750 errx(1, "invalid page control field %d", pc);
4757 if (page == -1 && list == 0)
4758 errx(1, "you must specify a mode page!");
4761 mode_list(device, cdb_len, dbd, pc, list > 1, task_attr,
4762 retry_count, timeout);
4764 mode_edit(device, cdb_len, dbd, pc, page, subpage, edit,
4765 binary, task_attr, retry_count, timeout);
4770 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4771 int task_attr, int retry_count, int timeout)
4774 u_int32_t flags = CAM_DIR_NONE;
4775 u_int8_t *data_ptr = NULL;
4777 u_int8_t atacmd[12];
4778 struct get_hook hook;
4779 int c, data_bytes = 0, valid_bytes;
4785 char *datastr = NULL, *tstr, *resstr = NULL;
4787 int fd_data = 0, fd_res = 0;
4790 ccb = cam_getccb(device);
4793 warnx("scsicmd: error allocating ccb");
4797 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4799 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4803 while (isspace(*tstr) && (*tstr != '\0'))
4805 hook.argc = argc - optind;
4806 hook.argv = argv + optind;
4808 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4811 * Increment optind by the number of arguments the
4812 * encoding routine processed. After each call to
4813 * getopt(3), optind points to the argument that
4814 * getopt should process _next_. In this case,
4815 * that means it points to the first command string
4816 * argument, if there is one. Once we increment
4817 * this, it should point to either the next command
4818 * line argument, or it should be past the end of
4825 while (isspace(*tstr) && (*tstr != '\0'))
4827 hook.argc = argc - optind;
4828 hook.argv = argv + optind;
4830 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4833 * Increment optind by the number of arguments the
4834 * encoding routine processed. After each call to
4835 * getopt(3), optind points to the argument that
4836 * getopt should process _next_. In this case,
4837 * that means it points to the first command string
4838 * argument, if there is one. Once we increment
4839 * this, it should point to either the next command
4840 * line argument, or it should be past the end of
4852 if (arglist & CAM_ARG_CMD_OUT) {
4853 warnx("command must either be "
4854 "read or write, not both");
4856 goto scsicmd_bailout;
4858 arglist |= CAM_ARG_CMD_IN;
4860 data_bytes = strtol(optarg, NULL, 0);
4861 if (data_bytes <= 0) {
4862 warnx("invalid number of input bytes %d",
4865 goto scsicmd_bailout;
4867 hook.argc = argc - optind;
4868 hook.argv = argv + optind;
4871 datastr = cget(&hook, NULL);
4873 * If the user supplied "-" instead of a format, he
4874 * wants the data to be written to stdout.
4876 if ((datastr != NULL)
4877 && (datastr[0] == '-'))
4880 data_ptr = (u_int8_t *)malloc(data_bytes);
4881 if (data_ptr == NULL) {
4882 warnx("can't malloc memory for data_ptr");
4884 goto scsicmd_bailout;
4888 if (arglist & CAM_ARG_CMD_IN) {
4889 warnx("command must either be "
4890 "read or write, not both");
4892 goto scsicmd_bailout;
4894 arglist |= CAM_ARG_CMD_OUT;
4895 flags = CAM_DIR_OUT;
4896 data_bytes = strtol(optarg, NULL, 0);
4897 if (data_bytes <= 0) {
4898 warnx("invalid number of output bytes %d",
4901 goto scsicmd_bailout;
4903 hook.argc = argc - optind;
4904 hook.argv = argv + optind;
4906 datastr = cget(&hook, NULL);
4907 data_ptr = (u_int8_t *)malloc(data_bytes);
4908 if (data_ptr == NULL) {
4909 warnx("can't malloc memory for data_ptr");
4911 goto scsicmd_bailout;
4913 bzero(data_ptr, data_bytes);
4915 * If the user supplied "-" instead of a format, he
4916 * wants the data to be read from stdin.
4918 if ((datastr != NULL)
4919 && (datastr[0] == '-'))
4922 buff_encode_visit(data_ptr, data_bytes, datastr,
4928 hook.argc = argc - optind;
4929 hook.argv = argv + optind;
4931 resstr = cget(&hook, NULL);
4932 if ((resstr != NULL) && (resstr[0] == '-'))
4942 * If fd_data is set, and we're writing to the device, we need to
4943 * read the data the user wants written from stdin.
4945 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4947 int amt_to_read = data_bytes;
4948 u_int8_t *buf_ptr = data_ptr;
4950 for (amt_read = 0; amt_to_read > 0;
4951 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4952 if (amt_read == -1) {
4953 warn("error reading data from stdin");
4955 goto scsicmd_bailout;
4957 amt_to_read -= amt_read;
4958 buf_ptr += amt_read;
4962 if (arglist & CAM_ARG_ERR_RECOVER)
4963 flags |= CAM_PASS_ERR_RECOVER;
4965 /* Disable freezing the device queue */
4966 flags |= CAM_DEV_QFRZDIS;
4970 * This is taken from the SCSI-3 draft spec.
4971 * (T10/1157D revision 0.3)
4972 * The top 3 bits of an opcode are the group code.
4973 * The next 5 bits are the command code.
4974 * Group 0: six byte commands
4975 * Group 1: ten byte commands
4976 * Group 2: ten byte commands
4978 * Group 4: sixteen byte commands
4979 * Group 5: twelve byte commands
4980 * Group 6: vendor specific
4981 * Group 7: vendor specific
4983 switch((cdb[0] >> 5) & 0x7) {
4994 /* computed by buff_encode_visit */
5005 * We should probably use csio_build_visit or something like that
5006 * here, but it's easier to encode arguments as you go. The
5007 * alternative would be skipping the CDB argument and then encoding
5008 * it here, since we've got the data buffer argument by now.
5010 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
5012 cam_fill_csio(&ccb->csio,
5013 /*retries*/ retry_count,
5016 /*tag_action*/ task_attr,
5017 /*data_ptr*/ data_ptr,
5018 /*dxfer_len*/ data_bytes,
5019 /*sense_len*/ SSD_FULL_SIZE,
5020 /*cdb_len*/ cdb_len,
5021 /*timeout*/ timeout ? timeout : 5000);
5024 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
5026 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5028 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5030 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5032 cam_fill_ataio(&ccb->ataio,
5033 /*retries*/ retry_count,
5037 /*data_ptr*/ data_ptr,
5038 /*dxfer_len*/ data_bytes,
5039 /*timeout*/ timeout ? timeout : 5000);
5042 if (((retval = cam_send_ccb(device, ccb)) < 0)
5043 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
5044 const char warnstr[] = "error sending command";
5051 if (arglist & CAM_ARG_VERBOSE) {
5052 cam_error_print(device, ccb, CAM_ESF_ALL,
5053 CAM_EPF_ALL, stderr);
5057 goto scsicmd_bailout;
5060 if (atacmd_len && need_res) {
5062 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
5064 fprintf(stdout, "\n");
5067 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
5068 ccb->ataio.res.status,
5069 ccb->ataio.res.error,
5070 ccb->ataio.res.lba_low,
5071 ccb->ataio.res.lba_mid,
5072 ccb->ataio.res.lba_high,
5073 ccb->ataio.res.device,
5074 ccb->ataio.res.lba_low_exp,
5075 ccb->ataio.res.lba_mid_exp,
5076 ccb->ataio.res.lba_high_exp,
5077 ccb->ataio.res.sector_count,
5078 ccb->ataio.res.sector_count_exp);
5084 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
5086 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
5087 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
5088 && (arglist & CAM_ARG_CMD_IN)
5089 && (valid_bytes > 0)) {
5091 buff_decode_visit(data_ptr, valid_bytes, datastr,
5093 fprintf(stdout, "\n");
5095 ssize_t amt_written;
5096 int amt_to_write = valid_bytes;
5097 u_int8_t *buf_ptr = data_ptr;
5099 for (amt_written = 0; (amt_to_write > 0) &&
5100 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
5101 amt_to_write -= amt_written;
5102 buf_ptr += amt_written;
5104 if (amt_written == -1) {
5105 warn("error writing data to stdout");
5107 goto scsicmd_bailout;
5108 } else if ((amt_written == 0)
5109 && (amt_to_write > 0)) {
5110 warnx("only wrote %u bytes out of %u",
5111 valid_bytes - amt_to_write, valid_bytes);
5118 if ((data_bytes > 0) && (data_ptr != NULL))
5127 camdebug(int argc, char **argv, char *combinedopt)
5130 path_id_t bus = CAM_BUS_WILDCARD;
5131 target_id_t target = CAM_TARGET_WILDCARD;
5132 lun_id_t lun = CAM_LUN_WILDCARD;
5137 bzero(&ccb, sizeof(union ccb));
5139 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5142 arglist |= CAM_ARG_DEBUG_INFO;
5143 ccb.cdbg.flags |= CAM_DEBUG_INFO;
5146 arglist |= CAM_ARG_DEBUG_PERIPH;
5147 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
5150 arglist |= CAM_ARG_DEBUG_SUBTRACE;
5151 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
5154 arglist |= CAM_ARG_DEBUG_TRACE;
5155 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
5158 arglist |= CAM_ARG_DEBUG_XPT;
5159 ccb.cdbg.flags |= CAM_DEBUG_XPT;
5162 arglist |= CAM_ARG_DEBUG_CDB;
5163 ccb.cdbg.flags |= CAM_DEBUG_CDB;
5166 arglist |= CAM_ARG_DEBUG_PROBE;
5167 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
5178 warnx("you must specify \"off\", \"all\" or a bus,");
5179 warnx("bus:target, bus:target:lun or periph");
5184 while (isspace(*tstr) && (*tstr != '\0'))
5187 if (strncmp(tstr, "off", 3) == 0) {
5188 ccb.cdbg.flags = CAM_DEBUG_NONE;
5189 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
5190 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
5191 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
5193 rv = parse_btl(tstr, &bus, &target, &lun, &arglist);
5195 warnx("you must specify \"all\", \"off\", or a bus,");
5196 warnx("bus:target, bus:target:lun or periph to debug");
5201 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
5202 warnx("error opening transport layer device %s", XPT_DEVICE);
5203 warn("%s", XPT_DEVICE);
5207 ccb.ccb_h.func_code = XPT_DEBUG;
5208 ccb.ccb_h.path_id = bus;
5209 ccb.ccb_h.target_id = target;
5210 ccb.ccb_h.target_lun = lun;
5212 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
5213 warn("CAMIOCOMMAND ioctl failed");
5216 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
5217 CAM_FUNC_NOTAVAIL) {
5218 warnx("CAM debugging not available");
5219 warnx("you need to put options CAMDEBUG in"
5220 " your kernel config file!");
5222 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
5224 warnx("XPT_DEBUG CCB failed with status %#x",
5228 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
5230 "Debugging turned off\n");
5233 "Debugging enabled for "
5235 bus, target, (uintmax_t)lun);
5245 tagcontrol(struct cam_device *device, int argc, char **argv,
5255 ccb = cam_getccb(device);
5258 warnx("tagcontrol: error allocating ccb");
5262 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5265 numtags = strtol(optarg, NULL, 0);
5267 warnx("tag count %d is < 0", numtags);
5269 goto tagcontrol_bailout;
5280 cam_path_string(device, pathstr, sizeof(pathstr));
5283 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
5284 ccb->ccb_h.func_code = XPT_REL_SIMQ;
5285 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5286 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5287 ccb->crs.openings = numtags;
5290 if (cam_send_ccb(device, ccb) < 0) {
5291 perror("error sending XPT_REL_SIMQ CCB");
5293 goto tagcontrol_bailout;
5296 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5297 warnx("XPT_REL_SIMQ CCB failed");
5298 cam_error_print(device, ccb, CAM_ESF_ALL,
5299 CAM_EPF_ALL, stderr);
5301 goto tagcontrol_bailout;
5306 fprintf(stdout, "%stagged openings now %d\n",
5307 pathstr, ccb->crs.openings);
5310 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5312 ccb->ccb_h.func_code = XPT_GDEV_STATS;
5314 if (cam_send_ccb(device, ccb) < 0) {
5315 perror("error sending XPT_GDEV_STATS CCB");
5317 goto tagcontrol_bailout;
5320 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5321 warnx("XPT_GDEV_STATS CCB failed");
5322 cam_error_print(device, ccb, CAM_ESF_ALL,
5323 CAM_EPF_ALL, stderr);
5325 goto tagcontrol_bailout;
5328 if (arglist & CAM_ARG_VERBOSE) {
5329 fprintf(stdout, "%s", pathstr);
5330 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5331 fprintf(stdout, "%s", pathstr);
5332 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5333 fprintf(stdout, "%s", pathstr);
5334 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5335 fprintf(stdout, "%s", pathstr);
5336 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5337 fprintf(stdout, "%s", pathstr);
5338 fprintf(stdout, "held %d\n", ccb->cgds.held);
5339 fprintf(stdout, "%s", pathstr);
5340 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5341 fprintf(stdout, "%s", pathstr);
5342 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5345 fprintf(stdout, "%s", pathstr);
5346 fprintf(stdout, "device openings: ");
5348 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5349 ccb->cgds.dev_active);
5359 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5363 cam_path_string(device, pathstr, sizeof(pathstr));
5365 if (cts->transport == XPORT_SPI) {
5366 struct ccb_trans_settings_spi *spi =
5367 &cts->xport_specific.spi;
5369 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5371 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5374 if (spi->sync_offset != 0) {
5377 freq = scsi_calc_syncsrate(spi->sync_period);
5378 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5379 pathstr, freq / 1000, freq % 1000);
5383 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5384 fprintf(stdout, "%soffset: %d\n", pathstr,
5388 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5389 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5390 (0x01 << spi->bus_width) * 8);
5393 if (spi->valid & CTS_SPI_VALID_DISC) {
5394 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5395 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5396 "enabled" : "disabled");
5399 if (cts->transport == XPORT_FC) {
5400 struct ccb_trans_settings_fc *fc =
5401 &cts->xport_specific.fc;
5403 if (fc->valid & CTS_FC_VALID_WWNN)
5404 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5405 (long long) fc->wwnn);
5406 if (fc->valid & CTS_FC_VALID_WWPN)
5407 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5408 (long long) fc->wwpn);
5409 if (fc->valid & CTS_FC_VALID_PORT)
5410 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5411 if (fc->valid & CTS_FC_VALID_SPEED)
5412 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5413 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5415 if (cts->transport == XPORT_SAS) {
5416 struct ccb_trans_settings_sas *sas =
5417 &cts->xport_specific.sas;
5419 if (sas->valid & CTS_SAS_VALID_SPEED)
5420 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5421 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5423 if (cts->transport == XPORT_ATA) {
5424 struct ccb_trans_settings_pata *pata =
5425 &cts->xport_specific.ata;
5427 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5428 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5429 ata_mode2string(pata->mode));
5431 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5432 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5435 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5436 fprintf(stdout, "%sPIO transaction length: %d\n",
5437 pathstr, pata->bytecount);
5440 if (cts->transport == XPORT_SATA) {
5441 struct ccb_trans_settings_sata *sata =
5442 &cts->xport_specific.sata;
5444 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5445 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5448 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5449 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5450 ata_mode2string(sata->mode));
5452 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5453 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5456 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5457 fprintf(stdout, "%sPIO transaction length: %d\n",
5458 pathstr, sata->bytecount);
5460 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5461 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5464 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5465 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5468 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5469 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5473 if (cts->protocol == PROTO_ATA) {
5474 struct ccb_trans_settings_ata *ata=
5475 &cts->proto_specific.ata;
5477 if (ata->valid & CTS_ATA_VALID_TQ) {
5478 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5479 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5480 "enabled" : "disabled");
5483 if (cts->protocol == PROTO_SCSI) {
5484 struct ccb_trans_settings_scsi *scsi=
5485 &cts->proto_specific.scsi;
5487 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5488 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5489 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5490 "enabled" : "disabled");
5494 if (cts->protocol == PROTO_NVME) {
5495 struct ccb_trans_settings_nvme *nvmex =
5496 &cts->xport_specific.nvme;
5498 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5499 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5500 NVME_MAJOR(nvmex->spec),
5501 NVME_MINOR(nvmex->spec));
5503 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5504 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5505 nvmex->lanes, nvmex->max_lanes);
5506 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5507 nvmex->speed, nvmex->max_speed);
5514 * Get a path inquiry CCB for the specified device.
5517 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5522 ccb = cam_getccb(device);
5524 warnx("get_cpi: couldn't allocate CCB");
5527 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5528 ccb->ccb_h.func_code = XPT_PATH_INQ;
5529 if (cam_send_ccb(device, ccb) < 0) {
5530 warn("get_cpi: error sending Path Inquiry CCB");
5531 if (arglist & CAM_ARG_VERBOSE)
5532 cam_error_print(device, ccb, CAM_ESF_ALL,
5533 CAM_EPF_ALL, stderr);
5535 goto get_cpi_bailout;
5537 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5538 if (arglist & CAM_ARG_VERBOSE)
5539 cam_error_print(device, ccb, CAM_ESF_ALL,
5540 CAM_EPF_ALL, stderr);
5542 goto get_cpi_bailout;
5544 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5552 * Get a get device CCB for the specified device.
5555 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5560 ccb = cam_getccb(device);
5562 warnx("get_cgd: couldn't allocate CCB");
5565 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5566 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5567 if (cam_send_ccb(device, ccb) < 0) {
5568 warn("get_cgd: error sending Path Inquiry CCB");
5569 if (arglist & CAM_ARG_VERBOSE)
5570 cam_error_print(device, ccb, CAM_ESF_ALL,
5571 CAM_EPF_ALL, stderr);
5573 goto get_cgd_bailout;
5575 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5576 if (arglist & CAM_ARG_VERBOSE)
5577 cam_error_print(device, ccb, CAM_ESF_ALL,
5578 CAM_EPF_ALL, stderr);
5580 goto get_cgd_bailout;
5582 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5590 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5594 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5595 int timeout, int verbosemode)
5597 union ccb *ccb = NULL;
5598 struct scsi_vpd_supported_page_list sup_pages;
5602 ccb = cam_getccb(dev);
5604 warn("Unable to allocate CCB");
5609 /* cam_getccb cleans up the header, caller has to zero the payload */
5610 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5612 bzero(&sup_pages, sizeof(sup_pages));
5614 scsi_inquiry(&ccb->csio,
5615 /*retries*/ retry_count,
5617 /* tag_action */ MSG_SIMPLE_Q_TAG,
5618 /* inq_buf */ (u_int8_t *)&sup_pages,
5619 /* inq_len */ sizeof(sup_pages),
5621 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5622 /* sense_len */ SSD_FULL_SIZE,
5623 /* timeout */ timeout ? timeout : 5000);
5625 /* Disable freezing the device queue */
5626 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5628 if (retry_count != 0)
5629 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5631 if (cam_send_ccb(dev, ccb) < 0) {
5638 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5639 if (verbosemode != 0)
5640 cam_error_print(dev, ccb, CAM_ESF_ALL,
5641 CAM_EPF_ALL, stderr);
5646 for (i = 0; i < sup_pages.length; i++) {
5647 if (sup_pages.list[i] == page_id) {
5660 * devtype is filled in with the type of device.
5661 * Returns 0 for success, non-zero for failure.
5664 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5665 int verbosemode, camcontrol_devtype *devtype)
5667 struct ccb_getdev cgd;
5670 retval = get_cgd(dev, &cgd);
5674 switch (cgd.protocol) {
5680 *devtype = CC_DT_ATA;
5682 break; /*NOTREACHED*/
5684 *devtype = CC_DT_NVME;
5686 break; /*NOTREACHED*/
5688 *devtype = CC_DT_MMCSD;
5690 break; /*NOTREACHED*/
5692 *devtype = CC_DT_UNKNOWN;
5694 break; /*NOTREACHED*/
5697 if (retry_count == -1) {
5699 * For a retry count of -1, used only the cached data to avoid
5700 * I/O to the drive. Sending the identify command to the drive
5701 * can cause issues for SATL attachaed drives since identify is
5702 * not an NCQ command.
5704 if (cgd.ident_data.config != 0)
5705 *devtype = CC_DT_SATL;
5707 *devtype = CC_DT_SCSI;
5710 * Check for the ATA Information VPD page (0x89). If this is an
5711 * ATA device behind a SCSI to ATA translation layer (SATL),
5712 * this VPD page should be present.
5714 * If that VPD page isn't present, or we get an error back from
5715 * the INQUIRY command, we'll just treat it as a normal SCSI
5718 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5719 timeout, verbosemode);
5721 *devtype = CC_DT_SATL;
5723 *devtype = CC_DT_SCSI;
5732 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5733 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5734 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5735 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5736 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5737 int is48bit, camcontrol_devtype devtype)
5741 if (devtype == CC_DT_ATA) {
5742 cam_fill_ataio(&ccb->ataio,
5743 /*retries*/ retry_count,
5746 /*tag_action*/ tag_action,
5747 /*data_ptr*/ data_ptr,
5748 /*dxfer_len*/ dxfer_len,
5749 /*timeout*/ timeout);
5750 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5751 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5754 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5757 if (auxiliary != 0) {
5758 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5759 ccb->ataio.aux = auxiliary;
5762 if (ata_flags & AP_FLAG_CHK_COND)
5763 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5765 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5766 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5767 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5768 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5770 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5771 protocol |= AP_EXTEND;
5773 retval = scsi_ata_pass(&ccb->csio,
5774 /*retries*/ retry_count,
5777 /*tag_action*/ tag_action,
5778 /*protocol*/ protocol,
5779 /*ata_flags*/ ata_flags,
5780 /*features*/ features,
5781 /*sector_count*/ sector_count,
5783 /*command*/ command,
5786 /*auxiliary*/ auxiliary,
5788 /*data_ptr*/ data_ptr,
5789 /*dxfer_len*/ dxfer_len,
5790 /*cdb_storage*/ cdb_storage,
5791 /*cdb_storage_len*/ cdb_storage_len,
5792 /*minimum_cmd_size*/ 0,
5793 /*sense_len*/ sense_len,
5794 /*timeout*/ timeout);
5801 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5802 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5806 switch (ccb->ccb_h.func_code) {
5809 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5812 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5813 * or 16 byte, and need to see what
5815 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5816 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5818 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5819 if ((opcode != ATA_PASS_12)
5820 && (opcode != ATA_PASS_16)) {
5822 warnx("%s: unsupported opcode %02x", __func__, opcode);
5826 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5828 /* Note: the _ccb() variant returns 0 for an error */
5835 switch (error_code) {
5836 case SSD_DESC_CURRENT_ERROR:
5837 case SSD_DESC_DEFERRED_ERROR: {
5838 struct scsi_sense_data_desc *sense;
5839 struct scsi_sense_ata_ret_desc *desc;
5842 sense = (struct scsi_sense_data_desc *)
5843 &ccb->csio.sense_data;
5845 desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len -
5846 ccb->csio.sense_resid, SSD_DESC_ATA);
5847 if (desc_ptr == NULL) {
5848 cam_error_print(dev, ccb, CAM_ESF_ALL,
5849 CAM_EPF_ALL, stderr);
5853 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5855 *error = desc->error;
5856 *count = (desc->count_15_8 << 8) |
5858 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5859 ((uint64_t)desc->lba_39_32 << 32) |
5860 ((uint64_t)desc->lba_31_24 << 24) |
5861 (desc->lba_23_16 << 16) |
5862 (desc->lba_15_8 << 8) |
5864 *device = desc->device;
5865 *status = desc->status;
5868 * If the extend bit isn't set, the result is for a
5869 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5870 * command without the extend bit set. This means
5871 * that the device is supposed to return 28-bit
5872 * status. The count field is only 8 bits, and the
5873 * LBA field is only 8 bits.
5875 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5881 case SSD_CURRENT_ERROR:
5882 case SSD_DEFERRED_ERROR: {
5884 struct scsi_sense_data_fixed *sense;
5887 * XXX KDM need to support fixed sense data.
5889 warnx("%s: Fixed sense data not supported yet",
5893 break; /*NOTREACHED*/
5904 struct ata_res *res;
5907 * In this case, we have an ATA command, and we need to
5908 * fill in the requested values from the result register
5911 res = &ccb->ataio.res;
5912 *error = res->error;
5913 *status = res->status;
5914 *device = res->device;
5915 *count = res->sector_count;
5916 *lba = (res->lba_high << 16) |
5917 (res->lba_mid << 8) |
5919 if (res->flags & CAM_ATAIO_48BIT) {
5920 *count |= (res->sector_count_exp << 8);
5921 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5922 ((uint64_t)res->lba_mid_exp << 32) |
5923 ((uint64_t)res->lba_high_exp << 40);
5925 *lba |= (res->device & 0xf) << 24;
5938 cpi_print(struct ccb_pathinq *cpi)
5940 char adapter_str[1024];
5943 snprintf(adapter_str, sizeof(adapter_str),
5944 "%s%d:", cpi->dev_name, cpi->unit_number);
5946 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5949 for (i = 1; i < UINT8_MAX; i = i << 1) {
5952 if ((i & cpi->hba_inquiry) == 0)
5955 fprintf(stdout, "%s supports ", adapter_str);
5959 str = "MDP message";
5962 str = "32 bit wide SCSI";
5965 str = "16 bit wide SCSI";
5968 str = "SDTR message";
5971 str = "linked CDBs";
5974 str = "tag queue messages";
5977 str = "soft reset alternative";
5980 str = "SATA Port Multiplier";
5983 str = "unknown PI bit set";
5986 fprintf(stdout, "%s\n", str);
5989 for (i = 1; i < UINT32_MAX; i = i << 1) {
5992 if ((i & cpi->hba_misc) == 0)
5995 fprintf(stdout, "%s ", adapter_str);
5999 str = "can understand ata_ext requests";
6002 str = "64bit extended LUNs supported";
6005 str = "bus scans from high ID to low ID";
6008 str = "removable devices not included in scan";
6010 case PIM_NOINITIATOR:
6011 str = "initiator role not supported";
6013 case PIM_NOBUSRESET:
6014 str = "user has disabled initial BUS RESET or"
6015 " controller is in target/mixed mode";
6018 str = "do not send 6-byte commands";
6021 str = "scan bus sequentially";
6024 str = "unmapped I/O supported";
6027 str = "does its own scanning";
6030 str = "unknown PIM bit set";
6033 fprintf(stdout, "%s\n", str);
6036 for (i = 1; i < UINT16_MAX; i = i << 1) {
6039 if ((i & cpi->target_sprt) == 0)
6042 fprintf(stdout, "%s supports ", adapter_str);
6045 str = "target mode processor mode";
6048 str = "target mode phase cog. mode";
6050 case PIT_DISCONNECT:
6051 str = "disconnects in target mode";
6054 str = "terminate I/O message in target mode";
6057 str = "group 6 commands in target mode";
6060 str = "group 7 commands in target mode";
6063 str = "unknown PIT bit set";
6067 fprintf(stdout, "%s\n", str);
6069 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
6071 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
6073 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
6075 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
6076 adapter_str, cpi->hpath_id);
6077 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
6079 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
6080 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
6081 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
6082 adapter_str, cpi->hba_vendor);
6083 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
6084 adapter_str, cpi->hba_device);
6085 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
6086 adapter_str, cpi->hba_subvendor);
6087 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
6088 adapter_str, cpi->hba_subdevice);
6089 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
6090 fprintf(stdout, "%s base transfer speed: ", adapter_str);
6091 if (cpi->base_transfer_speed > 1000)
6092 fprintf(stdout, "%d.%03dMB/sec\n",
6093 cpi->base_transfer_speed / 1000,
6094 cpi->base_transfer_speed % 1000);
6096 fprintf(stdout, "%dKB/sec\n",
6097 (cpi->base_transfer_speed % 1000) * 1000);
6098 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
6099 adapter_str, cpi->maxio);
6103 get_print_cts(struct cam_device *device, int user_settings, int quiet,
6104 struct ccb_trans_settings *cts)
6110 ccb = cam_getccb(device);
6113 warnx("get_print_cts: error allocating ccb");
6117 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
6119 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
6121 if (user_settings == 0)
6122 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
6124 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
6126 if (cam_send_ccb(device, ccb) < 0) {
6127 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
6128 if (arglist & CAM_ARG_VERBOSE)
6129 cam_error_print(device, ccb, CAM_ESF_ALL,
6130 CAM_EPF_ALL, stderr);
6132 goto get_print_cts_bailout;
6135 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6136 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
6137 if (arglist & CAM_ARG_VERBOSE)
6138 cam_error_print(device, ccb, CAM_ESF_ALL,
6139 CAM_EPF_ALL, stderr);
6141 goto get_print_cts_bailout;
6145 cts_print(device, &ccb->cts);
6148 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
6150 get_print_cts_bailout:
6158 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
6159 int timeout, int argc, char **argv, char *combinedopt)
6163 int user_settings = 0;
6165 int disc_enable = -1, tag_enable = -1;
6168 double syncrate = -1;
6171 int change_settings = 0, send_tur = 0;
6172 struct ccb_pathinq cpi;
6174 ccb = cam_getccb(device);
6176 warnx("ratecontrol: error allocating ccb");
6179 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6188 if (strncasecmp(optarg, "enable", 6) == 0)
6190 else if (strncasecmp(optarg, "disable", 7) == 0)
6193 warnx("-D argument \"%s\" is unknown", optarg);
6195 goto ratecontrol_bailout;
6197 change_settings = 1;
6200 mode = ata_string2mode(optarg);
6202 warnx("unknown mode '%s'", optarg);
6204 goto ratecontrol_bailout;
6206 change_settings = 1;
6209 offset = strtol(optarg, NULL, 0);
6211 warnx("offset value %d is < 0", offset);
6213 goto ratecontrol_bailout;
6215 change_settings = 1;
6221 syncrate = atof(optarg);
6223 warnx("sync rate %f is < 0", syncrate);
6225 goto ratecontrol_bailout;
6227 change_settings = 1;
6230 if (strncasecmp(optarg, "enable", 6) == 0)
6232 else if (strncasecmp(optarg, "disable", 7) == 0)
6235 warnx("-T argument \"%s\" is unknown", optarg);
6237 goto ratecontrol_bailout;
6239 change_settings = 1;
6245 bus_width = strtol(optarg, NULL, 0);
6246 if (bus_width < 0) {
6247 warnx("bus width %d is < 0", bus_width);
6249 goto ratecontrol_bailout;
6251 change_settings = 1;
6257 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
6259 * Grab path inquiry information, so we can determine whether
6260 * or not the initiator is capable of the things that the user
6263 ccb->ccb_h.func_code = XPT_PATH_INQ;
6264 if (cam_send_ccb(device, ccb) < 0) {
6265 perror("error sending XPT_PATH_INQ CCB");
6266 if (arglist & CAM_ARG_VERBOSE) {
6267 cam_error_print(device, ccb, CAM_ESF_ALL,
6268 CAM_EPF_ALL, stderr);
6271 goto ratecontrol_bailout;
6273 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6274 warnx("XPT_PATH_INQ CCB failed");
6275 if (arglist & CAM_ARG_VERBOSE) {
6276 cam_error_print(device, ccb, CAM_ESF_ALL,
6277 CAM_EPF_ALL, stderr);
6280 goto ratecontrol_bailout;
6282 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
6283 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
6285 fprintf(stdout, "%s parameters:\n",
6286 user_settings ? "User" : "Current");
6288 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
6290 goto ratecontrol_bailout;
6292 if (arglist & CAM_ARG_VERBOSE)
6295 if (change_settings) {
6296 int didsettings = 0;
6297 struct ccb_trans_settings_spi *spi = NULL;
6298 struct ccb_trans_settings_pata *pata = NULL;
6299 struct ccb_trans_settings_sata *sata = NULL;
6300 struct ccb_trans_settings_ata *ata = NULL;
6301 struct ccb_trans_settings_scsi *scsi = NULL;
6303 if (ccb->cts.transport == XPORT_SPI)
6304 spi = &ccb->cts.xport_specific.spi;
6305 if (ccb->cts.transport == XPORT_ATA)
6306 pata = &ccb->cts.xport_specific.ata;
6307 if (ccb->cts.transport == XPORT_SATA)
6308 sata = &ccb->cts.xport_specific.sata;
6309 if (ccb->cts.protocol == PROTO_ATA)
6310 ata = &ccb->cts.proto_specific.ata;
6311 if (ccb->cts.protocol == PROTO_SCSI)
6312 scsi = &ccb->cts.proto_specific.scsi;
6313 ccb->cts.xport_specific.valid = 0;
6314 ccb->cts.proto_specific.valid = 0;
6315 if (spi && disc_enable != -1) {
6316 spi->valid |= CTS_SPI_VALID_DISC;
6317 if (disc_enable == 0)
6318 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6320 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6323 if (tag_enable != -1) {
6324 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6325 warnx("HBA does not support tagged queueing, "
6326 "so you cannot modify tag settings");
6328 goto ratecontrol_bailout;
6331 ata->valid |= CTS_SCSI_VALID_TQ;
6332 if (tag_enable == 0)
6333 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6335 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6338 scsi->valid |= CTS_SCSI_VALID_TQ;
6339 if (tag_enable == 0)
6340 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6342 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6346 if (spi && offset != -1) {
6347 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6348 warnx("HBA is not capable of changing offset");
6350 goto ratecontrol_bailout;
6352 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6353 spi->sync_offset = offset;
6356 if (spi && syncrate != -1) {
6357 int prelim_sync_period;
6359 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6360 warnx("HBA is not capable of changing "
6363 goto ratecontrol_bailout;
6365 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6367 * The sync rate the user gives us is in MHz.
6368 * We need to translate it into KHz for this
6373 * Next, we calculate a "preliminary" sync period
6374 * in tenths of a nanosecond.
6377 prelim_sync_period = 0;
6379 prelim_sync_period = 10000000 / syncrate;
6381 scsi_calc_syncparam(prelim_sync_period);
6384 if (sata && syncrate != -1) {
6385 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6386 warnx("HBA is not capable of changing "
6389 goto ratecontrol_bailout;
6391 if (!user_settings) {
6392 warnx("You can modify only user rate "
6393 "settings for SATA");
6395 goto ratecontrol_bailout;
6397 sata->revision = ata_speed2revision(syncrate * 100);
6398 if (sata->revision < 0) {
6399 warnx("Invalid rate %f", syncrate);
6401 goto ratecontrol_bailout;
6403 sata->valid |= CTS_SATA_VALID_REVISION;
6406 if ((pata || sata) && mode != -1) {
6407 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6408 warnx("HBA is not capable of changing "
6411 goto ratecontrol_bailout;
6413 if (!user_settings) {
6414 warnx("You can modify only user mode "
6415 "settings for ATA/SATA");
6417 goto ratecontrol_bailout;
6421 pata->valid |= CTS_ATA_VALID_MODE;
6424 sata->valid |= CTS_SATA_VALID_MODE;
6429 * The bus_width argument goes like this:
6433 * Therefore, if you shift the number of bits given on the
6434 * command line right by 4, you should get the correct
6437 if (spi && bus_width != -1) {
6439 * We might as well validate things here with a
6440 * decipherable error message, rather than what
6441 * will probably be an indecipherable error message
6442 * by the time it gets back to us.
6444 if ((bus_width == 16)
6445 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6446 warnx("HBA does not support 16 bit bus width");
6448 goto ratecontrol_bailout;
6449 } else if ((bus_width == 32)
6450 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6451 warnx("HBA does not support 32 bit bus width");
6453 goto ratecontrol_bailout;
6454 } else if ((bus_width != 8)
6455 && (bus_width != 16)
6456 && (bus_width != 32)) {
6457 warnx("Invalid bus width %d", bus_width);
6459 goto ratecontrol_bailout;
6461 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6462 spi->bus_width = bus_width >> 4;
6465 if (didsettings == 0) {
6466 goto ratecontrol_bailout;
6468 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6469 if (cam_send_ccb(device, ccb) < 0) {
6470 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
6471 if (arglist & CAM_ARG_VERBOSE) {
6472 cam_error_print(device, ccb, CAM_ESF_ALL,
6473 CAM_EPF_ALL, stderr);
6476 goto ratecontrol_bailout;
6478 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6479 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6480 if (arglist & CAM_ARG_VERBOSE) {
6481 cam_error_print(device, ccb, CAM_ESF_ALL,
6482 CAM_EPF_ALL, stderr);
6485 goto ratecontrol_bailout;
6489 retval = testunitready(device, task_attr, retry_count, timeout,
6490 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6492 * If the TUR didn't succeed, just bail.
6496 fprintf(stderr, "Test Unit Ready failed\n");
6497 goto ratecontrol_bailout;
6500 if ((change_settings || send_tur) && !quiet &&
6501 (ccb->cts.transport == XPORT_ATA ||
6502 ccb->cts.transport == XPORT_SATA || send_tur)) {
6503 fprintf(stdout, "New parameters:\n");
6504 retval = get_print_cts(device, user_settings, 0, NULL);
6507 ratecontrol_bailout:
6513 scsiformat(struct cam_device *device, int argc, char **argv,
6514 char *combinedopt, int task_attr, int retry_count, int timeout)
6518 int ycount = 0, quiet = 0;
6519 int error = 0, retval = 0;
6520 int use_timeout = 10800 * 1000;
6522 struct format_defect_list_header fh;
6523 u_int8_t *data_ptr = NULL;
6524 u_int32_t dxfer_len = 0;
6526 int num_warnings = 0;
6529 ccb = cam_getccb(device);
6532 warnx("scsiformat: error allocating ccb");
6536 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6538 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6559 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6560 "following device:\n");
6562 error = scsidoinquiry(device, argc, argv, combinedopt,
6563 task_attr, retry_count, timeout);
6566 warnx("scsiformat: error sending inquiry");
6567 goto scsiformat_bailout;
6572 if (!get_confirmation()) {
6574 goto scsiformat_bailout;
6579 use_timeout = timeout;
6582 fprintf(stdout, "Current format timeout is %d seconds\n",
6583 use_timeout / 1000);
6587 * If the user hasn't disabled questions and didn't specify a
6588 * timeout on the command line, ask them if they want the current
6592 && (timeout == 0)) {
6594 int new_timeout = 0;
6596 fprintf(stdout, "Enter new timeout in seconds or press\n"
6597 "return to keep the current timeout [%d] ",
6598 use_timeout / 1000);
6600 if (fgets(str, sizeof(str), stdin) != NULL) {
6602 new_timeout = atoi(str);
6605 if (new_timeout != 0) {
6606 use_timeout = new_timeout * 1000;
6607 fprintf(stdout, "Using new timeout value %d\n",
6608 use_timeout / 1000);
6613 * Keep this outside the if block below to silence any unused
6614 * variable warnings.
6616 bzero(&fh, sizeof(fh));
6619 * If we're in immediate mode, we've got to include the format
6622 if (immediate != 0) {
6623 fh.byte2 = FU_DLH_IMMED;
6624 data_ptr = (u_int8_t *)&fh;
6625 dxfer_len = sizeof(fh);
6626 byte2 = FU_FMT_DATA;
6627 } else if (quiet == 0) {
6628 fprintf(stdout, "Formatting...");
6632 scsi_format_unit(&ccb->csio,
6633 /* retries */ retry_count,
6635 /* tag_action */ task_attr,
6638 /* data_ptr */ data_ptr,
6639 /* dxfer_len */ dxfer_len,
6640 /* sense_len */ SSD_FULL_SIZE,
6641 /* timeout */ use_timeout);
6643 /* Disable freezing the device queue */
6644 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6646 if (arglist & CAM_ARG_ERR_RECOVER)
6647 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6649 if (((retval = cam_send_ccb(device, ccb)) < 0)
6650 || ((immediate == 0)
6651 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6652 const char errstr[] = "error sending format command";
6659 if (arglist & CAM_ARG_VERBOSE) {
6660 cam_error_print(device, ccb, CAM_ESF_ALL,
6661 CAM_EPF_ALL, stderr);
6664 goto scsiformat_bailout;
6668 * If we ran in non-immediate mode, we already checked for errors
6669 * above and printed out any necessary information. If we're in
6670 * immediate mode, we need to loop through and get status
6671 * information periodically.
6673 if (immediate == 0) {
6675 fprintf(stdout, "Format Complete\n");
6677 goto scsiformat_bailout;
6684 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6687 * There's really no need to do error recovery or
6688 * retries here, since we're just going to sit in a
6689 * loop and wait for the device to finish formatting.
6691 scsi_test_unit_ready(&ccb->csio,
6694 /* tag_action */ task_attr,
6695 /* sense_len */ SSD_FULL_SIZE,
6696 /* timeout */ 5000);
6698 /* Disable freezing the device queue */
6699 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6701 retval = cam_send_ccb(device, ccb);
6704 * If we get an error from the ioctl, bail out. SCSI
6705 * errors are expected.
6708 warn("error sending CAMIOCOMMAND ioctl");
6709 if (arglist & CAM_ARG_VERBOSE) {
6710 cam_error_print(device, ccb, CAM_ESF_ALL,
6711 CAM_EPF_ALL, stderr);
6714 goto scsiformat_bailout;
6717 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6719 if ((status != CAM_REQ_CMP)
6720 && (status == CAM_SCSI_STATUS_ERROR)
6721 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6722 struct scsi_sense_data *sense;
6723 int error_code, sense_key, asc, ascq;
6725 sense = &ccb->csio.sense_data;
6726 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6727 ccb->csio.sense_resid, &error_code, &sense_key,
6728 &asc, &ascq, /*show_errors*/ 1);
6731 * According to the SCSI-2 and SCSI-3 specs, a
6732 * drive that is in the middle of a format should
6733 * return NOT READY with an ASC of "logical unit
6734 * not ready, format in progress". The sense key
6735 * specific bytes will then be a progress indicator.
6737 if ((sense_key == SSD_KEY_NOT_READY)
6738 && (asc == 0x04) && (ascq == 0x04)) {
6741 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6742 ccb->csio.sense_resid, sks) == 0)
6745 u_int64_t percentage;
6747 val = scsi_2btoul(&sks[1]);
6748 percentage = 10000ull * val;
6751 "\rFormatting: %ju.%02u %% "
6753 (uintmax_t)(percentage /
6755 (unsigned)((percentage /
6759 } else if ((quiet == 0)
6760 && (++num_warnings <= 1)) {
6761 warnx("Unexpected SCSI Sense Key "
6762 "Specific value returned "
6764 scsi_sense_print(device, &ccb->csio,
6766 warnx("Unable to print status "
6767 "information, but format will "
6769 warnx("will exit when format is "
6774 warnx("Unexpected SCSI error during format");
6775 cam_error_print(device, ccb, CAM_ESF_ALL,
6776 CAM_EPF_ALL, stderr);
6778 goto scsiformat_bailout;
6781 } else if (status != CAM_REQ_CMP) {
6782 warnx("Unexpected CAM status %#x", status);
6783 if (arglist & CAM_ARG_VERBOSE)
6784 cam_error_print(device, ccb, CAM_ESF_ALL,
6785 CAM_EPF_ALL, stderr);
6787 goto scsiformat_bailout;
6790 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6793 fprintf(stdout, "\nFormat Complete\n");
6803 sanitize_wait_ata(struct cam_device *device, union ccb *ccb, int quiet)
6805 struct ata_res *res;
6811 retval = ata_do_cmd(device,
6814 /*flags*/CAM_DIR_NONE,
6815 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
6816 /*ata_flags*/AP_FLAG_CHK_COND,
6817 /*tag_action*/MSG_SIMPLE_Q_TAG,
6818 /*command*/ATA_SANITIZE,
6819 /*features*/0x00, /* SANITIZE STATUS EXT */
6827 warn("error sending CAMIOCOMMAND ioctl");
6828 if (arglist & CAM_ARG_VERBOSE) {
6829 cam_error_print(device, ccb, CAM_ESF_ALL,
6830 CAM_EPF_ALL, stderr);
6835 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6836 if (status == CAM_REQ_CMP) {
6837 res = &ccb->ataio.res;
6838 if (res->sector_count_exp & 0x40) {
6840 val = (res->lba_mid << 8) + res->lba_low;
6843 "Sanitizing: %u.%02u%% (%d/%d)\r",
6844 (perc / (0x10000 * 100)),
6845 ((perc / 0x10000) % 100),
6850 } else if ((res->sector_count_exp & 0x80) == 0) {
6851 warnx("Sanitize complete with an error. ");
6856 } else if (status != CAM_REQ_CMP && status != CAM_REQUEUE_REQ) {
6857 warnx("Unexpected CAM status %#x", status);
6858 if (arglist & CAM_ARG_VERBOSE)
6859 cam_error_print(device, ccb, CAM_ESF_ALL,
6860 CAM_EPF_ALL, stderr);
6868 sanitize_wait_scsi(struct cam_device *device, union ccb *ccb, int task_attr, int quiet)
6870 int warnings = 0, retval;
6875 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6878 * There's really no need to do error recovery or
6879 * retries here, since we're just going to sit in a
6880 * loop and wait for the device to finish sanitizing.
6882 scsi_test_unit_ready(&ccb->csio,
6885 /* tag_action */ task_attr,
6886 /* sense_len */ SSD_FULL_SIZE,
6887 /* timeout */ 5000);
6889 /* Disable freezing the device queue */
6890 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6892 retval = cam_send_ccb(device, ccb);
6895 * If we get an error from the ioctl, bail out. SCSI
6896 * errors are expected.
6899 warn("error sending CAMIOCOMMAND ioctl");
6900 if (arglist & CAM_ARG_VERBOSE) {
6901 cam_error_print(device, ccb, CAM_ESF_ALL,
6902 CAM_EPF_ALL, stderr);
6907 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6908 if ((status == CAM_SCSI_STATUS_ERROR) &&
6909 ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6910 struct scsi_sense_data *sense;
6911 int error_code, sense_key, asc, ascq;
6913 sense = &ccb->csio.sense_data;
6914 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6915 ccb->csio.sense_resid, &error_code, &sense_key,
6916 &asc, &ascq, /*show_errors*/ 1);
6919 * According to the SCSI-3 spec, a drive that is in the
6920 * middle of a sanitize should return NOT READY with an
6921 * ASC of "logical unit not ready, sanitize in
6922 * progress". The sense key specific bytes will then
6923 * be a progress indicator.
6925 if ((sense_key == SSD_KEY_NOT_READY)
6926 && (asc == 0x04) && (ascq == 0x1b)) {
6929 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6930 ccb->csio.sense_resid, sks) == 0)
6932 val = scsi_2btoul(&sks[1]);
6935 "Sanitizing: %u.%02u%% (%d/%d)\r",
6936 (perc / (0x10000 * 100)),
6937 ((perc / 0x10000) % 100),
6940 } else if ((quiet == 0) && (++warnings <= 1)) {
6941 warnx("Unexpected SCSI Sense Key "
6942 "Specific value returned "
6943 "during sanitize:");
6944 scsi_sense_print(device, &ccb->csio,
6946 warnx("Unable to print status "
6947 "information, but sanitze will "
6949 warnx("will exit when sanitize is "
6954 warnx("Unexpected SCSI error during sanitize");
6955 cam_error_print(device, ccb, CAM_ESF_ALL,
6956 CAM_EPF_ALL, stderr);
6960 } else if (status != CAM_REQ_CMP && status != CAM_REQUEUE_REQ) {
6961 warnx("Unexpected CAM status %#x", status);
6962 if (arglist & CAM_ARG_VERBOSE)
6963 cam_error_print(device, ccb, CAM_ESF_ALL,
6964 CAM_EPF_ALL, stderr);
6967 } while ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6972 sanitize(struct cam_device *device, int argc, char **argv,
6973 char *combinedopt, int task_attr, int retry_count, int timeout)
6976 u_int8_t action = 0;
6978 int ycount = 0, quiet = 0;
6986 const char *pattern = NULL;
6987 u_int8_t *data_ptr = NULL;
6988 u_int32_t dxfer_len = 0;
6990 uint16_t feature, count;
6993 camcontrol_devtype dt;
6996 * Get the device type, request no I/O be done to do this.
6998 error = get_device_type(device, -1, 0, 0, &dt);
6999 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
7000 warnx("sanitize: can't get device type");
7004 ccb = cam_getccb(device);
7007 warnx("sanitize: error allocating ccb");
7011 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7013 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7016 if (strcasecmp(optarg, "overwrite") == 0)
7017 action = SSZ_SERVICE_ACTION_OVERWRITE;
7018 else if (strcasecmp(optarg, "block") == 0)
7019 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
7020 else if (strcasecmp(optarg, "crypto") == 0)
7021 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
7022 else if (strcasecmp(optarg, "exitfailure") == 0)
7023 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
7025 warnx("invalid service operation \"%s\"",
7028 goto sanitize_bailout;
7032 passes = strtol(optarg, NULL, 0);
7033 if (passes < 1 || passes > 31) {
7034 warnx("invalid passes value %d", passes);
7036 goto sanitize_bailout;
7055 /* ATA supports only immediate commands. */
7056 if (dt == CC_DT_SCSI)
7069 warnx("an action is required");
7071 goto sanitize_bailout;
7072 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
7073 struct scsi_sanitize_parameter_list *pl;
7077 if (pattern == NULL) {
7078 warnx("overwrite action requires -P argument");
7080 goto sanitize_bailout;
7082 fd = open(pattern, O_RDONLY);
7084 warn("cannot open pattern file %s", pattern);
7086 goto sanitize_bailout;
7088 if (fstat(fd, &sb) < 0) {
7089 warn("cannot stat pattern file %s", pattern);
7091 goto sanitize_bailout;
7094 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
7095 warnx("pattern file size exceeds maximum value %d",
7096 SSZPL_MAX_PATTERN_LENGTH);
7098 goto sanitize_bailout;
7100 dxfer_len = sizeof(*pl) + sz;
7101 data_ptr = calloc(1, dxfer_len);
7102 if (data_ptr == NULL) {
7103 warnx("cannot allocate parameter list buffer");
7105 goto sanitize_bailout;
7108 amt = read(fd, data_ptr + sizeof(*pl), sz);
7110 warn("cannot read pattern file");
7112 goto sanitize_bailout;
7113 } else if (amt != sz) {
7114 warnx("short pattern file read");
7116 goto sanitize_bailout;
7119 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
7125 pl->byte1 |= SSZPL_INVERT;
7126 scsi_ulto2b(sz, pl->length);
7132 else if (invert != 0)
7134 else if (pattern != NULL)
7139 warnx("%s argument only valid with overwrite "
7142 goto sanitize_bailout;
7147 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
7148 "following device:\n");
7150 if (dt == CC_DT_SCSI) {
7151 error = scsidoinquiry(device, argc, argv, combinedopt,
7152 task_attr, retry_count, timeout);
7153 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7154 struct ata_params *ident_buf;
7155 error = ata_do_identify(device, retry_count, timeout,
7158 printf("%s%d: ", device->device_name,
7159 device->dev_unit_num);
7160 ata_print_ident(ident_buf);
7167 warnx("sanitize: error sending inquiry");
7168 goto sanitize_bailout;
7173 if (!get_confirmation()) {
7175 goto sanitize_bailout;
7180 use_timeout = timeout;
7182 use_timeout = (immediate ? 10 : 10800) * 1000;
7184 if (immediate == 0 && quiet == 0) {
7185 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
7186 use_timeout / 1000);
7190 * If the user hasn't disabled questions and didn't specify a
7191 * timeout on the command line, ask them if they want the current
7194 if (immediate == 0 && ycount == 0 && timeout == 0) {
7196 int new_timeout = 0;
7198 fprintf(stdout, "Enter new timeout in seconds or press\n"
7199 "return to keep the current timeout [%d] ",
7200 use_timeout / 1000);
7202 if (fgets(str, sizeof(str), stdin) != NULL) {
7204 new_timeout = atoi(str);
7207 if (new_timeout != 0) {
7208 use_timeout = new_timeout * 1000;
7209 fprintf(stdout, "Using new timeout value %d\n",
7210 use_timeout / 1000);
7214 if (dt == CC_DT_SCSI) {
7217 byte2 |= SSZ_UNRESTRICTED_EXIT;
7220 scsi_sanitize(&ccb->csio,
7221 /* retries */ retry_count,
7223 /* tag_action */ task_attr,
7226 /* data_ptr */ data_ptr,
7227 /* dxfer_len */ dxfer_len,
7228 /* sense_len */ SSD_FULL_SIZE,
7229 /* timeout */ use_timeout);
7231 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7232 if (arglist & CAM_ARG_ERR_RECOVER)
7233 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7234 if (cam_send_ccb(device, ccb) < 0) {
7235 warn("error sending sanitize command");
7237 goto sanitize_bailout;
7239 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7240 if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
7241 feature = 0x14; /* OVERWRITE EXT */
7242 lba = 0x4F5700000000 | scsi_4btoul(data_ptr + 4);
7243 count = (passes == 0) ? 1 : (passes >= 16) ? 0 : passes;
7245 count |= 0x80; /* INVERT PATTERN */
7247 count |= 0x10; /* FAILURE MODE */
7248 } else if (action == SSZ_SERVICE_ACTION_BLOCK_ERASE) {
7249 feature = 0x12; /* BLOCK ERASE EXT */
7250 lba = 0x0000426B4572;
7253 count |= 0x10; /* FAILURE MODE */
7254 } else if (action == SSZ_SERVICE_ACTION_CRYPTO_ERASE) {
7255 feature = 0x11; /* CRYPTO SCRAMBLE EXT */
7256 lba = 0x000043727970;
7259 count |= 0x10; /* FAILURE MODE */
7260 } else if (action == SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE) {
7261 feature = 0x00; /* SANITIZE STATUS EXT */
7263 count = 1; /* CLEAR SANITIZE OPERATION FAILED */
7266 goto sanitize_bailout;
7269 error = ata_do_cmd(device,
7272 /*flags*/CAM_DIR_NONE,
7273 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
7274 /*ata_flags*/AP_FLAG_CHK_COND,
7275 /*tag_action*/MSG_SIMPLE_Q_TAG,
7276 /*command*/ATA_SANITIZE,
7277 /*features*/feature,
7279 /*sector_count*/count,
7282 /*timeout*/ use_timeout,
7286 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7287 struct scsi_sense_data *sense;
7288 int error_code, sense_key, asc, ascq;
7290 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
7291 CAM_SCSI_STATUS_ERROR) {
7292 sense = &ccb->csio.sense_data;
7293 scsi_extract_sense_len(sense, ccb->csio.sense_len -
7294 ccb->csio.sense_resid, &error_code, &sense_key,
7295 &asc, &ascq, /*show_errors*/ 1);
7297 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
7298 asc == 0x20 && ascq == 0x00)
7299 warnx("sanitize is not supported by "
7302 warnx("error sanitizing this device");
7304 warnx("error sanitizing this device");
7306 if (arglist & CAM_ARG_VERBOSE) {
7307 cam_error_print(device, ccb, CAM_ESF_ALL,
7308 CAM_EPF_ALL, stderr);
7311 goto sanitize_bailout;
7315 * If we ran in non-immediate mode, we already checked for errors
7316 * above and printed out any necessary information. If we're in
7317 * immediate mode, we need to loop through and get status
7318 * information periodically.
7320 if (immediate == 0) {
7322 fprintf(stdout, "Sanitize Complete\n");
7324 goto sanitize_bailout;
7328 if (dt == CC_DT_SCSI) {
7329 error = sanitize_wait_scsi(device, ccb, task_attr, quiet);
7330 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7331 error = sanitize_wait_ata(device, ccb, quiet);
7334 if (error == 0 && quiet == 0)
7335 fprintf(stdout, "Sanitize Complete \n");
7340 if (data_ptr != NULL)
7348 scsireportluns(struct cam_device *device, int argc, char **argv,
7349 char *combinedopt, int task_attr, int retry_count, int timeout)
7352 int c, countonly, lunsonly;
7353 struct scsi_report_luns_data *lundata;
7355 uint8_t report_type;
7356 uint32_t list_len, i, j;
7361 report_type = RPL_REPORT_DEFAULT;
7362 ccb = cam_getccb(device);
7365 warnx("%s: error allocating ccb", __func__);
7369 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7374 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7383 if (strcasecmp(optarg, "default") == 0)
7384 report_type = RPL_REPORT_DEFAULT;
7385 else if (strcasecmp(optarg, "wellknown") == 0)
7386 report_type = RPL_REPORT_WELLKNOWN;
7387 else if (strcasecmp(optarg, "all") == 0)
7388 report_type = RPL_REPORT_ALL;
7390 warnx("%s: invalid report type \"%s\"",
7401 if ((countonly != 0)
7402 && (lunsonly != 0)) {
7403 warnx("%s: you can only specify one of -c or -l", __func__);
7408 * According to SPC-4, the allocation length must be at least 16
7409 * bytes -- enough for the header and one LUN.
7411 alloc_len = sizeof(*lundata) + 8;
7415 lundata = malloc(alloc_len);
7417 if (lundata == NULL) {
7418 warn("%s: error mallocing %d bytes", __func__, alloc_len);
7423 scsi_report_luns(&ccb->csio,
7424 /*retries*/ retry_count,
7426 /*tag_action*/ task_attr,
7427 /*select_report*/ report_type,
7428 /*rpl_buf*/ lundata,
7429 /*alloc_len*/ alloc_len,
7430 /*sense_len*/ SSD_FULL_SIZE,
7431 /*timeout*/ timeout ? timeout : 5000);
7433 /* Disable freezing the device queue */
7434 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7436 if (arglist & CAM_ARG_ERR_RECOVER)
7437 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7439 if (cam_send_ccb(device, ccb) < 0) {
7440 warn("error sending REPORT LUNS command");
7442 if (arglist & CAM_ARG_VERBOSE)
7443 cam_error_print(device, ccb, CAM_ESF_ALL,
7444 CAM_EPF_ALL, stderr);
7450 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7451 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7457 list_len = scsi_4btoul(lundata->length);
7460 * If we need to list the LUNs, and our allocation
7461 * length was too short, reallocate and retry.
7463 if ((countonly == 0)
7464 && (list_len > (alloc_len - sizeof(*lundata)))) {
7465 alloc_len = list_len + sizeof(*lundata);
7471 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7472 ((list_len / 8) > 1) ? "s" : "");
7477 for (i = 0; i < (list_len / 8); i++) {
7481 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7483 fprintf(stdout, ",");
7484 switch (lundata->luns[i].lundata[j] &
7485 RPL_LUNDATA_ATYP_MASK) {
7486 case RPL_LUNDATA_ATYP_PERIPH:
7487 if ((lundata->luns[i].lundata[j] &
7488 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7489 fprintf(stdout, "%d:",
7490 lundata->luns[i].lundata[j] &
7491 RPL_LUNDATA_PERIPH_BUS_MASK);
7493 && ((lundata->luns[i].lundata[j+2] &
7494 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7497 fprintf(stdout, "%d",
7498 lundata->luns[i].lundata[j+1]);
7500 case RPL_LUNDATA_ATYP_FLAT: {
7502 tmplun[0] = lundata->luns[i].lundata[j] &
7503 RPL_LUNDATA_FLAT_LUN_MASK;
7504 tmplun[1] = lundata->luns[i].lundata[j+1];
7506 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7510 case RPL_LUNDATA_ATYP_LUN:
7511 fprintf(stdout, "%d:%d:%d",
7512 (lundata->luns[i].lundata[j+1] &
7513 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7514 lundata->luns[i].lundata[j] &
7515 RPL_LUNDATA_LUN_TARG_MASK,
7516 lundata->luns[i].lundata[j+1] &
7517 RPL_LUNDATA_LUN_LUN_MASK);
7519 case RPL_LUNDATA_ATYP_EXTLUN: {
7520 int field_len_code, eam_code;
7522 eam_code = lundata->luns[i].lundata[j] &
7523 RPL_LUNDATA_EXT_EAM_MASK;
7524 field_len_code = (lundata->luns[i].lundata[j] &
7525 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7527 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7528 && (field_len_code == 0x00)) {
7529 fprintf(stdout, "%d",
7530 lundata->luns[i].lundata[j+1]);
7531 } else if ((eam_code ==
7532 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7533 && (field_len_code == 0x03)) {
7537 * This format takes up all 8 bytes.
7538 * If we aren't starting at offset 0,
7542 fprintf(stdout, "Invalid "
7545 "specified format", j);
7549 bzero(tmp_lun, sizeof(tmp_lun));
7550 bcopy(&lundata->luns[i].lundata[j+1],
7551 &tmp_lun[1], sizeof(tmp_lun) - 1);
7552 fprintf(stdout, "%#jx",
7553 (intmax_t)scsi_8btou64(tmp_lun));
7556 fprintf(stderr, "Unknown Extended LUN"
7557 "Address method %#x, length "
7558 "code %#x", eam_code,
7565 fprintf(stderr, "Unknown LUN address method "
7566 "%#x\n", lundata->luns[i].lundata[0] &
7567 RPL_LUNDATA_ATYP_MASK);
7571 * For the flat addressing method, there are no
7572 * other levels after it.
7577 fprintf(stdout, "\n");
7590 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7591 char *combinedopt, int task_attr, int retry_count, int timeout)
7594 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7595 struct scsi_read_capacity_data rcap;
7596 struct scsi_read_capacity_data_long rcaplong;
7611 ccb = cam_getccb(device);
7614 warnx("%s: error allocating ccb", __func__);
7618 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7620 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7650 if ((blocksizeonly != 0)
7651 && (numblocks != 0)) {
7652 warnx("%s: you can only specify one of -b or -N", __func__);
7657 if ((blocksizeonly != 0)
7658 && (sizeonly != 0)) {
7659 warnx("%s: you can only specify one of -b or -s", __func__);
7666 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7672 && (blocksizeonly != 0)) {
7673 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7681 scsi_read_capacity(&ccb->csio,
7682 /*retries*/ retry_count,
7684 /*tag_action*/ task_attr,
7687 /*timeout*/ timeout ? timeout : 5000);
7689 /* Disable freezing the device queue */
7690 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7692 if (arglist & CAM_ARG_ERR_RECOVER)
7693 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7695 if (cam_send_ccb(device, ccb) < 0) {
7696 warn("error sending READ CAPACITY command");
7698 if (arglist & CAM_ARG_VERBOSE)
7699 cam_error_print(device, ccb, CAM_ESF_ALL,
7700 CAM_EPF_ALL, stderr);
7706 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7707 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7712 maxsector = scsi_4btoul(rcap.addr);
7713 block_len = scsi_4btoul(rcap.length);
7716 * A last block of 2^32-1 means that the true capacity is over 2TB,
7717 * and we need to issue the long READ CAPACITY to get the real
7718 * capacity. Otherwise, we're all set.
7720 if (maxsector != 0xffffffff)
7724 scsi_read_capacity_16(&ccb->csio,
7725 /*retries*/ retry_count,
7727 /*tag_action*/ task_attr,
7731 /*rcap_buf*/ (uint8_t *)&rcaplong,
7732 /*rcap_buf_len*/ sizeof(rcaplong),
7733 /*sense_len*/ SSD_FULL_SIZE,
7734 /*timeout*/ timeout ? timeout : 5000);
7736 /* Disable freezing the device queue */
7737 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7739 if (arglist & CAM_ARG_ERR_RECOVER)
7740 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7742 if (cam_send_ccb(device, ccb) < 0) {
7743 warn("error sending READ CAPACITY (16) command");
7745 if (arglist & CAM_ARG_VERBOSE)
7746 cam_error_print(device, ccb, CAM_ESF_ALL,
7747 CAM_EPF_ALL, stderr);
7753 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7754 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7759 maxsector = scsi_8btou64(rcaplong.addr);
7760 block_len = scsi_4btoul(rcaplong.length);
7763 if (blocksizeonly == 0) {
7765 * Humanize implies !quiet, and also implies numblocks.
7767 if (humanize != 0) {
7772 tmpbytes = (maxsector + 1) * block_len;
7773 ret = humanize_number(tmpstr, sizeof(tmpstr),
7774 tmpbytes, "", HN_AUTOSCALE,
7777 HN_DIVISOR_1000 : 0));
7779 warnx("%s: humanize_number failed!", __func__);
7783 fprintf(stdout, "Device Size: %s%s", tmpstr,
7784 (sizeonly == 0) ? ", " : "\n");
7785 } else if (numblocks != 0) {
7786 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7787 "Blocks: " : "", (uintmax_t)maxsector + 1,
7788 (sizeonly == 0) ? ", " : "\n");
7790 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7791 "Last Block: " : "", (uintmax_t)maxsector,
7792 (sizeonly == 0) ? ", " : "\n");
7796 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7797 "Block Length: " : "", block_len, (quiet == 0) ?
7806 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7807 int retry_count, int timeout)
7811 uint8_t *smp_request = NULL, *smp_response = NULL;
7812 int request_size = 0, response_size = 0;
7813 int fd_request = 0, fd_response = 0;
7814 char *datastr = NULL;
7815 struct get_hook hook;
7820 * Note that at the moment we don't support sending SMP CCBs to
7821 * devices that aren't probed by CAM.
7823 ccb = cam_getccb(device);
7825 warnx("%s: error allocating CCB", __func__);
7829 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7831 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7834 arglist |= CAM_ARG_CMD_IN;
7835 response_size = strtol(optarg, NULL, 0);
7836 if (response_size <= 0) {
7837 warnx("invalid number of response bytes %d",
7840 goto smpcmd_bailout;
7842 hook.argc = argc - optind;
7843 hook.argv = argv + optind;
7846 datastr = cget(&hook, NULL);
7848 * If the user supplied "-" instead of a format, he
7849 * wants the data to be written to stdout.
7851 if ((datastr != NULL)
7852 && (datastr[0] == '-'))
7855 smp_response = (u_int8_t *)malloc(response_size);
7856 if (smp_response == NULL) {
7857 warn("can't malloc memory for SMP response");
7859 goto smpcmd_bailout;
7863 arglist |= CAM_ARG_CMD_OUT;
7864 request_size = strtol(optarg, NULL, 0);
7865 if (request_size <= 0) {
7866 warnx("invalid number of request bytes %d",
7869 goto smpcmd_bailout;
7871 hook.argc = argc - optind;
7872 hook.argv = argv + optind;
7874 datastr = cget(&hook, NULL);
7875 smp_request = (u_int8_t *)malloc(request_size);
7876 if (smp_request == NULL) {
7877 warn("can't malloc memory for SMP request");
7879 goto smpcmd_bailout;
7881 bzero(smp_request, request_size);
7883 * If the user supplied "-" instead of a format, he
7884 * wants the data to be read from stdin.
7886 if ((datastr != NULL)
7887 && (datastr[0] == '-'))
7890 buff_encode_visit(smp_request, request_size,
7901 * If fd_data is set, and we're writing to the device, we need to
7902 * read the data the user wants written from stdin.
7904 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7906 int amt_to_read = request_size;
7907 u_int8_t *buf_ptr = smp_request;
7909 for (amt_read = 0; amt_to_read > 0;
7910 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7911 if (amt_read == -1) {
7912 warn("error reading data from stdin");
7914 goto smpcmd_bailout;
7916 amt_to_read -= amt_read;
7917 buf_ptr += amt_read;
7921 if (((arglist & CAM_ARG_CMD_IN) == 0)
7922 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7923 warnx("%s: need both the request (-r) and response (-R) "
7924 "arguments", __func__);
7926 goto smpcmd_bailout;
7929 flags |= CAM_DEV_QFRZDIS;
7931 cam_fill_smpio(&ccb->smpio,
7932 /*retries*/ retry_count,
7935 /*smp_request*/ smp_request,
7936 /*smp_request_len*/ request_size,
7937 /*smp_response*/ smp_response,
7938 /*smp_response_len*/ response_size,
7939 /*timeout*/ timeout ? timeout : 5000);
7941 ccb->smpio.flags = SMP_FLAG_NONE;
7943 if (((retval = cam_send_ccb(device, ccb)) < 0)
7944 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7945 const char warnstr[] = "error sending command";
7952 if (arglist & CAM_ARG_VERBOSE) {
7953 cam_error_print(device, ccb, CAM_ESF_ALL,
7954 CAM_EPF_ALL, stderr);
7958 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7959 && (response_size > 0)) {
7960 if (fd_response == 0) {
7961 buff_decode_visit(smp_response, response_size,
7962 datastr, arg_put, NULL);
7963 fprintf(stdout, "\n");
7965 ssize_t amt_written;
7966 int amt_to_write = response_size;
7967 u_int8_t *buf_ptr = smp_response;
7969 for (amt_written = 0; (amt_to_write > 0) &&
7970 (amt_written = write(STDOUT_FILENO, buf_ptr,
7971 amt_to_write)) > 0;){
7972 amt_to_write -= amt_written;
7973 buf_ptr += amt_written;
7975 if (amt_written == -1) {
7976 warn("error writing data to stdout");
7978 goto smpcmd_bailout;
7979 } else if ((amt_written == 0)
7980 && (amt_to_write > 0)) {
7981 warnx("only wrote %u bytes out of %u",
7982 response_size - amt_to_write,
7991 if (smp_request != NULL)
7994 if (smp_response != NULL)
8001 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
8002 int retry_count, int timeout)
8006 int32_t mmc_opcode = 0, mmc_arg = 0;
8007 int32_t mmc_flags = -1;
8010 int is_bw_4 = 0, is_bw_1 = 0;
8011 int is_highspeed = 0, is_stdspeed = 0;
8012 int is_info_request = 0;
8014 uint8_t mmc_data_byte = 0;
8016 /* For IO_RW_EXTENDED command */
8017 uint8_t *mmc_data = NULL;
8018 struct mmc_data mmc_d;
8019 int mmc_data_len = 0;
8022 * Note that at the moment we don't support sending SMP CCBs to
8023 * devices that aren't probed by CAM.
8025 ccb = cam_getccb(device);
8027 warnx("%s: error allocating CCB", __func__);
8031 bzero(&(&ccb->ccb_h)[1],
8032 sizeof(union ccb) - sizeof(struct ccb_hdr));
8034 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8043 if (!strcmp(optarg, "high"))
8049 is_info_request = 1;
8052 mmc_opcode = strtol(optarg, NULL, 0);
8053 if (mmc_opcode < 0) {
8054 warnx("invalid MMC opcode %d",
8057 goto mmccmd_bailout;
8061 mmc_arg = strtol(optarg, NULL, 0);
8063 warnx("invalid MMC arg %d",
8066 goto mmccmd_bailout;
8070 mmc_flags = strtol(optarg, NULL, 0);
8071 if (mmc_flags < 0) {
8072 warnx("invalid MMC flags %d",
8075 goto mmccmd_bailout;
8079 mmc_data_len = strtol(optarg, NULL, 0);
8080 if (mmc_data_len <= 0) {
8081 warnx("invalid MMC data len %d",
8084 goto mmccmd_bailout;
8091 mmc_data_byte = strtol(optarg, NULL, 0);
8097 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
8099 /* If flags are left default, supply the right flags */
8101 switch (mmc_opcode) {
8102 case MMC_GO_IDLE_STATE:
8103 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
8105 case IO_SEND_OP_COND:
8106 mmc_flags = MMC_RSP_R4;
8108 case SD_SEND_RELATIVE_ADDR:
8109 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
8111 case MMC_SELECT_CARD:
8112 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
8113 mmc_arg = mmc_arg << 16;
8115 case SD_IO_RW_DIRECT:
8116 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
8117 mmc_arg = SD_IO_RW_ADR(mmc_arg);
8119 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
8121 case SD_IO_RW_EXTENDED:
8122 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
8123 mmc_arg = SD_IO_RW_ADR(mmc_arg);
8124 int len_arg = mmc_data_len;
8125 if (mmc_data_len == 512)
8129 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
8131 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
8134 mmc_flags = MMC_RSP_R1;
8138 // Switch bus width instead of sending IO command
8139 if (is_bw_4 || is_bw_1) {
8140 struct ccb_trans_settings_mmc *cts;
8141 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
8142 ccb->ccb_h.flags = 0;
8143 cts = &ccb->cts.proto_specific.mmc;
8144 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
8145 cts->ios_valid = MMC_BW;
8146 if (((retval = cam_send_ccb(device, ccb)) < 0)
8147 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8148 warn("Error sending command");
8150 printf("Parameters set OK\n");
8156 // Switch bus speed instead of sending IO command
8157 if (is_stdspeed || is_highspeed) {
8158 struct ccb_trans_settings_mmc *cts;
8159 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
8160 ccb->ccb_h.flags = 0;
8161 cts = &ccb->cts.proto_specific.mmc;
8162 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
8163 cts->ios_valid = MMC_BT;
8164 if (((retval = cam_send_ccb(device, ccb)) < 0)
8165 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8166 warn("Error sending command");
8168 printf("Speed set OK (HS: %d)\n", is_highspeed);
8174 // Get information about controller and its settings
8175 if (is_info_request) {
8176 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
8177 ccb->ccb_h.flags = 0;
8178 struct ccb_trans_settings_mmc *cts;
8179 cts = &ccb->cts.proto_specific.mmc;
8180 if (((retval = cam_send_ccb(device, ccb)) < 0)
8181 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8182 warn("Error sending command");
8185 printf("Host controller information\n");
8186 printf("Host OCR: 0x%x\n", cts->host_ocr);
8187 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
8188 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
8189 printf("Supported bus width: ");
8190 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
8192 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
8194 printf("\nCurrent settings:\n");
8195 printf("Bus width: ");
8196 switch (cts->ios.bus_width) {
8207 printf("Freq: %d.%03d MHz%s\n",
8208 cts->ios.clock / 1000000,
8209 (cts->ios.clock / 1000) % 1000,
8210 cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : "");
8214 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
8216 if (mmc_data_len > 0) {
8217 flags |= CAM_DIR_IN;
8218 mmc_data = malloc(mmc_data_len);
8219 memset(mmc_data, 0, mmc_data_len);
8220 memset(&mmc_d, 0, sizeof(mmc_d));
8221 mmc_d.len = mmc_data_len;
8222 mmc_d.data = mmc_data;
8223 mmc_d.flags = MMC_DATA_READ;
8224 } else flags |= CAM_DIR_NONE;
8226 cam_fill_mmcio(&ccb->mmcio,
8227 /*retries*/ retry_count,
8230 /*mmc_opcode*/ mmc_opcode,
8231 /*mmc_arg*/ mmc_arg,
8232 /*mmc_flags*/ mmc_flags,
8233 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
8234 /*timeout*/ timeout ? timeout : 5000);
8236 if (((retval = cam_send_ccb(device, ccb)) < 0)
8237 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8238 const char warnstr[] = "error sending command";
8245 if (arglist & CAM_ARG_VERBOSE) {
8246 cam_error_print(device, ccb, CAM_ESF_ALL,
8247 CAM_EPF_ALL, stderr);
8251 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
8252 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
8253 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
8254 ccb->mmcio.cmd.resp[1],
8255 ccb->mmcio.cmd.resp[2],
8256 ccb->mmcio.cmd.resp[3]);
8258 switch (mmc_opcode) {
8259 case SD_IO_RW_DIRECT:
8260 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
8261 SD_R5_DATA(ccb->mmcio.cmd.resp),
8262 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
8264 case SD_IO_RW_EXTENDED:
8265 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
8266 hexdump(mmc_data, mmc_data_len, NULL, 0);
8268 case SD_SEND_RELATIVE_ADDR:
8269 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
8272 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
8279 if (mmc_data_len > 0 && mmc_data != NULL)
8286 smpreportgeneral(struct cam_device *device, int argc, char **argv,
8287 char *combinedopt, int retry_count, int timeout)
8290 struct smp_report_general_request *request = NULL;
8291 struct smp_report_general_response *response = NULL;
8292 struct sbuf *sb = NULL;
8294 int c, long_response = 0;
8298 * Note that at the moment we don't support sending SMP CCBs to
8299 * devices that aren't probed by CAM.
8301 ccb = cam_getccb(device);
8303 warnx("%s: error allocating CCB", __func__);
8307 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8309 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8318 request = malloc(sizeof(*request));
8319 if (request == NULL) {
8320 warn("%s: unable to allocate %zd bytes", __func__,
8326 response = malloc(sizeof(*response));
8327 if (response == NULL) {
8328 warn("%s: unable to allocate %zd bytes", __func__,
8335 smp_report_general(&ccb->smpio,
8339 /*request_len*/ sizeof(*request),
8340 (uint8_t *)response,
8341 /*response_len*/ sizeof(*response),
8342 /*long_response*/ long_response,
8345 if (((retval = cam_send_ccb(device, ccb)) < 0)
8346 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8347 const char warnstr[] = "error sending command";
8354 if (arglist & CAM_ARG_VERBOSE) {
8355 cam_error_print(device, ccb, CAM_ESF_ALL,
8356 CAM_EPF_ALL, stderr);
8363 * If the device supports the long response bit, try again and see
8364 * if we can get all of the data.
8366 if ((response->long_response & SMP_RG_LONG_RESPONSE)
8367 && (long_response == 0)) {
8368 ccb->ccb_h.status = CAM_REQ_INPROG;
8369 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8375 * XXX KDM detect and decode SMP errors here.
8377 sb = sbuf_new_auto();
8379 warnx("%s: error allocating sbuf", __func__);
8383 smp_report_general_sbuf(response, sizeof(*response), sb);
8385 if (sbuf_finish(sb) != 0) {
8386 warnx("%s: sbuf_finish", __func__);
8390 printf("%s", sbuf_data(sb));
8396 if (request != NULL)
8399 if (response != NULL)
8408 static struct camcontrol_opts phy_ops[] = {
8409 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
8410 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
8411 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
8412 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
8413 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
8414 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
8415 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
8416 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
8417 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
8422 smpphycontrol(struct cam_device *device, int argc, char **argv,
8423 char *combinedopt, int retry_count, int timeout)
8426 struct smp_phy_control_request *request = NULL;
8427 struct smp_phy_control_response *response = NULL;
8428 int long_response = 0;
8431 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
8433 uint64_t attached_dev_name = 0;
8434 int dev_name_set = 0;
8435 uint32_t min_plr = 0, max_plr = 0;
8436 uint32_t pp_timeout_val = 0;
8437 int slumber_partial = 0;
8438 int set_pp_timeout_val = 0;
8442 * Note that at the moment we don't support sending SMP CCBs to
8443 * devices that aren't probed by CAM.
8445 ccb = cam_getccb(device);
8447 warnx("%s: error allocating CCB", __func__);
8451 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8453 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8461 if (strcasecmp(optarg, "enable") == 0)
8463 else if (strcasecmp(optarg, "disable") == 0)
8466 warnx("%s: Invalid argument %s", __func__,
8473 slumber_partial |= enable <<
8474 SMP_PC_SAS_SLUMBER_SHIFT;
8477 slumber_partial |= enable <<
8478 SMP_PC_SAS_PARTIAL_SHIFT;
8481 slumber_partial |= enable <<
8482 SMP_PC_SATA_SLUMBER_SHIFT;
8485 slumber_partial |= enable <<
8486 SMP_PC_SATA_PARTIAL_SHIFT;
8489 warnx("%s: programmer error", __func__);
8492 break; /*NOTREACHED*/
8497 attached_dev_name = (uintmax_t)strtoumax(optarg,
8506 * We don't do extensive checking here, so this
8507 * will continue to work when new speeds come out.
8509 min_plr = strtoul(optarg, NULL, 0);
8511 || (min_plr > 0xf)) {
8512 warnx("%s: invalid link rate %x",
8520 * We don't do extensive checking here, so this
8521 * will continue to work when new speeds come out.
8523 max_plr = strtoul(optarg, NULL, 0);
8525 || (max_plr > 0xf)) {
8526 warnx("%s: invalid link rate %x",
8533 camcontrol_optret optreturn;
8534 cam_argmask argnums;
8537 if (phy_op_set != 0) {
8538 warnx("%s: only one phy operation argument "
8539 "(-o) allowed", __func__);
8547 * Allow the user to specify the phy operation
8548 * numerically, as well as with a name. This will
8549 * future-proof it a bit, so options that are added
8550 * in future specs can be used.
8552 if (isdigit(optarg[0])) {
8553 phy_operation = strtoul(optarg, NULL, 0);
8554 if ((phy_operation == 0)
8555 || (phy_operation > 0xff)) {
8556 warnx("%s: invalid phy operation %#x",
8557 __func__, phy_operation);
8563 optreturn = getoption(phy_ops, optarg, &phy_operation,
8566 if (optreturn == CC_OR_AMBIGUOUS) {
8567 warnx("%s: ambiguous option %s", __func__,
8572 } else if (optreturn == CC_OR_NOT_FOUND) {
8573 warnx("%s: option %s not found", __func__,
8585 pp_timeout_val = strtoul(optarg, NULL, 0);
8586 if (pp_timeout_val > 15) {
8587 warnx("%s: invalid partial pathway timeout "
8588 "value %u, need a value less than 16",
8589 __func__, pp_timeout_val);
8593 set_pp_timeout_val = 1;
8601 warnx("%s: a PHY (-p phy) argument is required",__func__);
8606 if (((dev_name_set != 0)
8607 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8608 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8609 && (dev_name_set == 0))) {
8610 warnx("%s: -d name and -o setdevname arguments both "
8611 "required to set device name", __func__);
8616 request = malloc(sizeof(*request));
8617 if (request == NULL) {
8618 warn("%s: unable to allocate %zd bytes", __func__,
8624 response = malloc(sizeof(*response));
8625 if (response == NULL) {
8626 warn("%s: unable to allocate %zd bytes", __func__,
8632 smp_phy_control(&ccb->smpio,
8637 (uint8_t *)response,
8640 /*expected_exp_change_count*/ 0,
8643 (set_pp_timeout_val != 0) ? 1 : 0,
8651 if (((retval = cam_send_ccb(device, ccb)) < 0)
8652 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8653 const char warnstr[] = "error sending command";
8660 if (arglist & CAM_ARG_VERBOSE) {
8662 * Use CAM_EPF_NORMAL so we only get one line of
8663 * SMP command decoding.
8665 cam_error_print(device, ccb, CAM_ESF_ALL,
8666 CAM_EPF_NORMAL, stderr);
8672 /* XXX KDM print out something here for success? */
8677 if (request != NULL)
8680 if (response != NULL)
8687 smpmaninfo(struct cam_device *device, int argc, char **argv,
8688 char *combinedopt, int retry_count, int timeout)
8691 struct smp_report_manuf_info_request request;
8692 struct smp_report_manuf_info_response response;
8693 struct sbuf *sb = NULL;
8694 int long_response = 0;
8699 * Note that at the moment we don't support sending SMP CCBs to
8700 * devices that aren't probed by CAM.
8702 ccb = cam_getccb(device);
8704 warnx("%s: error allocating CCB", __func__);
8708 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8710 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8719 bzero(&request, sizeof(request));
8720 bzero(&response, sizeof(response));
8722 smp_report_manuf_info(&ccb->smpio,
8727 (uint8_t *)&response,
8732 if (((retval = cam_send_ccb(device, ccb)) < 0)
8733 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8734 const char warnstr[] = "error sending command";
8741 if (arglist & CAM_ARG_VERBOSE) {
8742 cam_error_print(device, ccb, CAM_ESF_ALL,
8743 CAM_EPF_ALL, stderr);
8749 sb = sbuf_new_auto();
8751 warnx("%s: error allocating sbuf", __func__);
8755 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8757 if (sbuf_finish(sb) != 0) {
8758 warnx("%s: sbuf_finish", __func__);
8762 printf("%s", sbuf_data(sb));
8776 getdevid(struct cam_devitem *item)
8779 union ccb *ccb = NULL;
8781 struct cam_device *dev;
8783 dev = cam_open_btl(item->dev_match.path_id,
8784 item->dev_match.target_id,
8785 item->dev_match.target_lun, O_RDWR, NULL);
8788 warnx("%s", cam_errbuf);
8793 item->device_id_len = 0;
8795 ccb = cam_getccb(dev);
8797 warnx("%s: error allocating CCB", __func__);
8802 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8805 * On the first try, we just probe for the size of the data, and
8806 * then allocate that much memory and try again.
8809 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8810 ccb->ccb_h.flags = CAM_DIR_IN;
8811 ccb->cdai.flags = CDAI_FLAG_NONE;
8812 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8813 ccb->cdai.bufsiz = item->device_id_len;
8814 if (item->device_id_len != 0)
8815 ccb->cdai.buf = (uint8_t *)item->device_id;
8817 if (cam_send_ccb(dev, ccb) < 0) {
8818 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8823 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8824 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8829 if (item->device_id_len == 0) {
8831 * This is our first time through. Allocate the buffer,
8832 * and then go back to get the data.
8834 if (ccb->cdai.provsiz == 0) {
8835 warnx("%s: invalid .provsiz field returned with "
8836 "XPT_GDEV_ADVINFO CCB", __func__);
8840 item->device_id_len = ccb->cdai.provsiz;
8841 item->device_id = malloc(item->device_id_len);
8842 if (item->device_id == NULL) {
8843 warn("%s: unable to allocate %d bytes", __func__,
8844 item->device_id_len);
8848 ccb->ccb_h.status = CAM_REQ_INPROG;
8854 cam_close_device(dev);
8863 * XXX KDM merge this code with getdevtree()?
8866 buildbusdevlist(struct cam_devlist *devlist)
8869 int bufsize, fd = -1;
8870 struct dev_match_pattern *patterns;
8871 struct cam_devitem *item = NULL;
8872 int skip_device = 0;
8875 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8876 warn("couldn't open %s", XPT_DEVICE);
8880 bzero(&ccb, sizeof(union ccb));
8882 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8883 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8884 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8886 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8887 bufsize = sizeof(struct dev_match_result) * 100;
8888 ccb.cdm.match_buf_len = bufsize;
8889 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8890 if (ccb.cdm.matches == NULL) {
8891 warnx("can't malloc memory for matches");
8895 ccb.cdm.num_matches = 0;
8896 ccb.cdm.num_patterns = 2;
8897 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8898 ccb.cdm.num_patterns;
8900 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8901 if (patterns == NULL) {
8902 warnx("can't malloc memory for patterns");
8907 ccb.cdm.patterns = patterns;
8908 bzero(patterns, ccb.cdm.pattern_buf_len);
8910 patterns[0].type = DEV_MATCH_DEVICE;
8911 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8912 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8913 patterns[1].type = DEV_MATCH_PERIPH;
8914 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8915 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8918 * We do the ioctl multiple times if necessary, in case there are
8919 * more than 100 nodes in the EDT.
8924 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8925 warn("error sending CAMIOCOMMAND ioctl");
8930 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8931 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8932 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8933 warnx("got CAM error %#x, CDM error %d\n",
8934 ccb.ccb_h.status, ccb.cdm.status);
8939 for (i = 0; i < ccb.cdm.num_matches; i++) {
8940 switch (ccb.cdm.matches[i].type) {
8941 case DEV_MATCH_DEVICE: {
8942 struct device_match_result *dev_result;
8945 &ccb.cdm.matches[i].result.device_result;
8947 if (dev_result->flags &
8948 DEV_RESULT_UNCONFIGURED) {
8954 item = malloc(sizeof(*item));
8956 warn("%s: unable to allocate %zd bytes",
8957 __func__, sizeof(*item));
8961 bzero(item, sizeof(*item));
8962 bcopy(dev_result, &item->dev_match,
8963 sizeof(*dev_result));
8964 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8967 if (getdevid(item) != 0) {
8973 case DEV_MATCH_PERIPH: {
8974 struct periph_match_result *periph_result;
8977 &ccb.cdm.matches[i].result.periph_result;
8979 if (skip_device != 0)
8981 item->num_periphs++;
8982 item->periph_matches = realloc(
8983 item->periph_matches,
8985 sizeof(struct periph_match_result));
8986 if (item->periph_matches == NULL) {
8987 warn("%s: error allocating periph "
8992 bcopy(periph_result, &item->periph_matches[
8993 item->num_periphs - 1],
8994 sizeof(*periph_result));
8998 fprintf(stderr, "%s: unexpected match "
8999 "type %d\n", __func__,
9000 ccb.cdm.matches[i].type);
9003 break; /*NOTREACHED*/
9006 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
9007 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
9015 free(ccb.cdm.matches);
9018 freebusdevlist(devlist);
9024 freebusdevlist(struct cam_devlist *devlist)
9026 struct cam_devitem *item, *item2;
9028 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
9029 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
9031 free(item->device_id);
9032 free(item->periph_matches);
9037 static struct cam_devitem *
9038 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
9040 struct cam_devitem *item;
9042 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
9043 struct scsi_vpd_id_descriptor *idd;
9046 * XXX KDM look for LUN IDs as well?
9048 idd = scsi_get_devid(item->device_id,
9049 item->device_id_len,
9050 scsi_devid_is_sas_target);
9054 if (scsi_8btou64(idd->identifier) == sasaddr)
9062 smpphylist(struct cam_device *device, int argc, char **argv,
9063 char *combinedopt, int retry_count, int timeout)
9065 struct smp_report_general_request *rgrequest = NULL;
9066 struct smp_report_general_response *rgresponse = NULL;
9067 struct smp_discover_request *disrequest = NULL;
9068 struct smp_discover_response *disresponse = NULL;
9069 struct cam_devlist devlist;
9071 int long_response = 0;
9078 * Note that at the moment we don't support sending SMP CCBs to
9079 * devices that aren't probed by CAM.
9081 ccb = cam_getccb(device);
9083 warnx("%s: error allocating CCB", __func__);
9087 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
9088 STAILQ_INIT(&devlist.dev_queue);
9090 rgrequest = malloc(sizeof(*rgrequest));
9091 if (rgrequest == NULL) {
9092 warn("%s: unable to allocate %zd bytes", __func__,
9093 sizeof(*rgrequest));
9098 rgresponse = malloc(sizeof(*rgresponse));
9099 if (rgresponse == NULL) {
9100 warn("%s: unable to allocate %zd bytes", __func__,
9101 sizeof(*rgresponse));
9106 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9119 smp_report_general(&ccb->smpio,
9123 /*request_len*/ sizeof(*rgrequest),
9124 (uint8_t *)rgresponse,
9125 /*response_len*/ sizeof(*rgresponse),
9126 /*long_response*/ long_response,
9129 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9131 if (((retval = cam_send_ccb(device, ccb)) < 0)
9132 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
9133 const char warnstr[] = "error sending command";
9140 if (arglist & CAM_ARG_VERBOSE) {
9141 cam_error_print(device, ccb, CAM_ESF_ALL,
9142 CAM_EPF_ALL, stderr);
9148 num_phys = rgresponse->num_phys;
9150 if (num_phys == 0) {
9152 fprintf(stdout, "%s: No Phys reported\n", __func__);
9157 devlist.path_id = device->path_id;
9159 retval = buildbusdevlist(&devlist);
9164 fprintf(stdout, "%d PHYs:\n", num_phys);
9165 fprintf(stdout, "PHY Attached SAS Address\n");
9168 disrequest = malloc(sizeof(*disrequest));
9169 if (disrequest == NULL) {
9170 warn("%s: unable to allocate %zd bytes", __func__,
9171 sizeof(*disrequest));
9176 disresponse = malloc(sizeof(*disresponse));
9177 if (disresponse == NULL) {
9178 warn("%s: unable to allocate %zd bytes", __func__,
9179 sizeof(*disresponse));
9184 for (i = 0; i < num_phys; i++) {
9185 struct cam_devitem *item;
9186 struct device_match_result *dev_match;
9187 char vendor[16], product[48], revision[16];
9191 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
9193 ccb->ccb_h.status = CAM_REQ_INPROG;
9194 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9196 smp_discover(&ccb->smpio,
9200 sizeof(*disrequest),
9201 (uint8_t *)disresponse,
9202 sizeof(*disresponse),
9204 /*ignore_zone_group*/ 0,
9208 if (((retval = cam_send_ccb(device, ccb)) < 0)
9209 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
9210 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
9211 const char warnstr[] = "error sending command";
9218 if (arglist & CAM_ARG_VERBOSE) {
9219 cam_error_print(device, ccb, CAM_ESF_ALL,
9220 CAM_EPF_ALL, stderr);
9226 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
9228 fprintf(stdout, "%3d <vacant>\n", i);
9232 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
9235 item = findsasdevice(&devlist,
9236 scsi_8btou64(disresponse->attached_sas_address));
9240 || (item != NULL)) {
9241 fprintf(stdout, "%3d 0x%016jx", i,
9242 (uintmax_t)scsi_8btou64(
9243 disresponse->attached_sas_address));
9245 fprintf(stdout, "\n");
9248 } else if (quiet != 0)
9251 dev_match = &item->dev_match;
9253 if (dev_match->protocol == PROTO_SCSI) {
9254 cam_strvis(vendor, dev_match->inq_data.vendor,
9255 sizeof(dev_match->inq_data.vendor),
9257 cam_strvis(product, dev_match->inq_data.product,
9258 sizeof(dev_match->inq_data.product),
9260 cam_strvis(revision, dev_match->inq_data.revision,
9261 sizeof(dev_match->inq_data.revision),
9263 sprintf(tmpstr, "<%s %s %s>", vendor, product,
9265 } else if ((dev_match->protocol == PROTO_ATA)
9266 || (dev_match->protocol == PROTO_SATAPM)) {
9267 cam_strvis(product, dev_match->ident_data.model,
9268 sizeof(dev_match->ident_data.model),
9270 cam_strvis(revision, dev_match->ident_data.revision,
9271 sizeof(dev_match->ident_data.revision),
9273 sprintf(tmpstr, "<%s %s>", product, revision);
9275 sprintf(tmpstr, "<>");
9277 fprintf(stdout, " %-33s ", tmpstr);
9280 * If we have 0 periphs, that's a bug...
9282 if (item->num_periphs == 0) {
9283 fprintf(stdout, "\n");
9287 fprintf(stdout, "(");
9288 for (j = 0; j < item->num_periphs; j++) {
9290 fprintf(stdout, ",");
9292 fprintf(stdout, "%s%d",
9293 item->periph_matches[j].periph_name,
9294 item->periph_matches[j].unit_number);
9297 fprintf(stdout, ")\n");
9311 freebusdevlist(&devlist);
9317 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
9319 struct ata_res *res;
9321 res = &ccb->ataio.res;
9322 if (res->status & ATA_STATUS_ERROR) {
9323 if (arglist & CAM_ARG_VERBOSE) {
9324 cam_error_print(device, ccb, CAM_ESF_ALL,
9325 CAM_EPF_ALL, stderr);
9326 printf("error = 0x%02x, sector_count = 0x%04x, "
9327 "device = 0x%02x, status = 0x%02x\n",
9328 res->error, res->sector_count,
9329 res->device, res->status);
9335 if (arglist & CAM_ARG_VERBOSE) {
9336 fprintf(stdout, "%s%d: Raw native check power data:\n",
9337 device->device_name, device->dev_unit_num);
9338 /* res is 4 byte aligned */
9339 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
9341 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
9342 "status = 0x%02x\n", res->error, res->sector_count,
9343 res->device, res->status);
9346 printf("%s%d: ", device->device_name, device->dev_unit_num);
9347 switch (res->sector_count) {
9349 printf("Standby mode\n");
9352 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
9355 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
9358 printf("Idle mode\n");
9361 printf("Active or Idle mode\n");
9364 printf("Unknown mode 0x%02x\n", res->sector_count);
9372 atapm(struct cam_device *device, int argc, char **argv,
9373 char *combinedopt, int retry_count, int timeout)
9379 u_int8_t ata_flags = 0;
9382 ccb = cam_getccb(device);
9385 warnx("%s: error allocating ccb", __func__);
9389 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9398 if (strcmp(argv[1], "idle") == 0) {
9400 cmd = ATA_IDLE_IMMEDIATE;
9403 } else if (strcmp(argv[1], "standby") == 0) {
9405 cmd = ATA_STANDBY_IMMEDIATE;
9407 cmd = ATA_STANDBY_CMD;
9408 } else if (strcmp(argv[1], "powermode") == 0) {
9409 cmd = ATA_CHECK_POWER_MODE;
9410 ata_flags = AP_FLAG_CHK_COND;
9419 else if (t <= (240 * 5))
9421 else if (t <= (252 * 5))
9422 /* special encoding for 21 minutes */
9424 else if (t <= (11 * 30 * 60))
9425 sc = (t - 1) / (30 * 60) + 241;
9429 retval = ata_do_cmd(device,
9431 /*retries*/retry_count,
9432 /*flags*/CAM_DIR_NONE,
9433 /*protocol*/AP_PROTO_NON_DATA,
9434 /*ata_flags*/ata_flags,
9435 /*tag_action*/MSG_SIMPLE_Q_TAG,
9442 /*timeout*/timeout ? timeout : 30 * 1000,
9447 if (retval || cmd != ATA_CHECK_POWER_MODE)
9450 return (atapm_proc_resp(device, ccb));
9454 ataaxm(struct cam_device *device, int argc, char **argv,
9455 char *combinedopt, int retry_count, int timeout)
9463 ccb = cam_getccb(device);
9466 warnx("%s: error allocating ccb", __func__);
9470 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9480 if (strcmp(argv[1], "apm") == 0) {
9496 retval = ata_do_28bit_cmd(device,
9498 /*retries*/retry_count,
9499 /*flags*/CAM_DIR_NONE,
9500 /*protocol*/AP_PROTO_NON_DATA,
9501 /*tag_action*/MSG_SIMPLE_Q_TAG,
9502 /*command*/ATA_SETFEATURES,
9508 /*timeout*/timeout ? timeout : 30 * 1000,
9516 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9517 int show_sa_errors, int sa_set, int service_action,
9518 int timeout_desc, int task_attr, int retry_count, int timeout,
9519 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9521 union ccb *ccb = NULL;
9522 uint8_t *buf = NULL;
9523 uint32_t alloc_len = 0, num_opcodes;
9524 uint32_t valid_len = 0;
9525 uint32_t avail_len = 0;
9526 struct scsi_report_supported_opcodes_all *all_hdr;
9527 struct scsi_report_supported_opcodes_one *one;
9532 * Make it clear that we haven't yet allocated or filled anything.
9537 ccb = cam_getccb(device);
9539 warnx("couldn't allocate CCB");
9544 /* cam_getccb cleans up the header, caller has to zero the payload */
9545 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9547 if (opcode_set != 0) {
9548 options |= RSO_OPTIONS_OC;
9550 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9553 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9554 sizeof(struct scsi_report_supported_opcodes_descr));
9557 if (timeout_desc != 0) {
9558 options |= RSO_RCTD;
9559 alloc_len += num_opcodes *
9560 sizeof(struct scsi_report_supported_opcodes_timeout);
9564 options |= RSO_OPTIONS_OC_SA;
9565 if (show_sa_errors != 0)
9566 options &= ~RSO_OPTIONS_OC;
9575 buf = malloc(alloc_len);
9577 warn("Unable to allocate %u bytes", alloc_len);
9581 bzero(buf, alloc_len);
9583 scsi_report_supported_opcodes(&ccb->csio,
9584 /*retries*/ retry_count,
9586 /*tag_action*/ task_attr,
9587 /*options*/ options,
9588 /*req_opcode*/ opcode,
9589 /*req_service_action*/ service_action,
9591 /*dxfer_len*/ alloc_len,
9592 /*sense_len*/ SSD_FULL_SIZE,
9593 /*timeout*/ timeout ? timeout : 10000);
9595 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9597 if (retry_count != 0)
9598 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9600 if (cam_send_ccb(device, ccb) < 0) {
9601 perror("error sending REPORT SUPPORTED OPERATION CODES");
9606 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9607 if (verbosemode != 0)
9608 cam_error_print(device, ccb, CAM_ESF_ALL,
9609 CAM_EPF_ALL, stderr);
9614 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9616 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9617 && (valid_len >= sizeof(*all_hdr))) {
9618 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9619 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9620 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9621 && (valid_len >= sizeof(*one))) {
9622 uint32_t cdb_length;
9624 one = (struct scsi_report_supported_opcodes_one *)buf;
9625 cdb_length = scsi_2btoul(one->cdb_length);
9626 avail_len = sizeof(*one) + cdb_length;
9627 if (one->support & RSO_ONE_CTDP) {
9628 struct scsi_report_supported_opcodes_timeout *td;
9630 td = (struct scsi_report_supported_opcodes_timeout *)
9632 if (valid_len >= (avail_len + sizeof(td->length))) {
9633 avail_len += scsi_2btoul(td->length) +
9636 avail_len += sizeof(*td);
9642 * avail_len could be zero if we didn't get enough data back from
9643 * thet target to determine
9645 if ((avail_len != 0)
9646 && (avail_len > valid_len)) {
9647 alloc_len = avail_len;
9651 *fill_len = valid_len;
9663 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9664 int req_sa, uint8_t *buf, uint32_t valid_len)
9666 struct scsi_report_supported_opcodes_one *one;
9667 struct scsi_report_supported_opcodes_timeout *td;
9668 uint32_t cdb_len = 0, td_len = 0;
9669 const char *op_desc = NULL;
9673 one = (struct scsi_report_supported_opcodes_one *)buf;
9676 * If we don't have the full single opcode descriptor, no point in
9679 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9681 warnx("Only %u bytes returned, not enough to verify support",
9687 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9689 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9692 printf(", SA 0x%x", req_sa);
9695 switch (one->support & RSO_ONE_SUP_MASK) {
9696 case RSO_ONE_SUP_UNAVAIL:
9697 printf("No command support information currently available\n");
9699 case RSO_ONE_SUP_NOT_SUP:
9700 printf("Command not supported\n");
9703 break; /*NOTREACHED*/
9704 case RSO_ONE_SUP_AVAIL:
9705 printf("Command is supported, complies with a SCSI standard\n");
9707 case RSO_ONE_SUP_VENDOR:
9708 printf("Command is supported, vendor-specific "
9709 "implementation\n");
9712 printf("Unknown command support flags 0x%#x\n",
9713 one->support & RSO_ONE_SUP_MASK);
9718 * If we don't have the CDB length, it isn't exactly an error, the
9719 * command probably isn't supported.
9721 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9725 cdb_len = scsi_2btoul(one->cdb_length);
9728 * If our valid data doesn't include the full reported length,
9729 * return. The caller should have detected this and adjusted his
9730 * allocation length to get all of the available data.
9732 if (valid_len < sizeof(*one) + cdb_len) {
9738 * If all we have is the opcode, there is no point in printing out
9746 printf("CDB usage bitmap:");
9747 for (i = 0; i < cdb_len; i++) {
9748 printf(" %02x", one->cdb_usage[i]);
9753 * If we don't have a timeout descriptor, we're done.
9755 if ((one->support & RSO_ONE_CTDP) == 0)
9759 * If we don't have enough valid length to include the timeout
9760 * descriptor length, we're done.
9762 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9765 td = (struct scsi_report_supported_opcodes_timeout *)
9766 &buf[sizeof(*one) + cdb_len];
9767 td_len = scsi_2btoul(td->length);
9768 td_len += sizeof(td->length);
9771 * If we don't have the full timeout descriptor, we're done.
9773 if (td_len < sizeof(*td))
9777 * If we don't have enough valid length to contain the full timeout
9778 * descriptor, we're done.
9780 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9783 printf("Timeout information:\n");
9784 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9785 printf("Nominal timeout: %u seconds\n",
9786 scsi_4btoul(td->nominal_time));
9787 printf("Recommended timeout: %u seconds\n",
9788 scsi_4btoul(td->recommended_time));
9795 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9798 struct scsi_report_supported_opcodes_all *hdr;
9799 struct scsi_report_supported_opcodes_descr *desc;
9800 uint32_t avail_len = 0, used_len = 0;
9804 if (valid_len < sizeof(*hdr)) {
9805 warnx("%s: not enough returned data (%u bytes) opcode list",
9806 __func__, valid_len);
9810 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9811 avail_len = scsi_4btoul(hdr->length);
9812 avail_len += sizeof(hdr->length);
9814 * Take the lesser of the amount of data the drive claims is
9815 * available, and the amount of data the HBA says was returned.
9817 avail_len = MIN(avail_len, valid_len);
9819 used_len = sizeof(hdr->length);
9821 printf("%-6s %4s %8s ",
9822 "Opcode", "SA", "CDB len" );
9825 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9826 printf(" Description\n");
9828 while ((avail_len - used_len) > sizeof(*desc)) {
9829 struct scsi_report_supported_opcodes_timeout *td;
9831 const char *op_desc = NULL;
9833 cur_ptr = &buf[used_len];
9834 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9836 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9837 if (op_desc == NULL)
9838 op_desc = "UNKNOWN";
9840 printf("0x%02x %#4x %8u ", desc->opcode,
9841 scsi_2btoul(desc->service_action),
9842 scsi_2btoul(desc->cdb_length));
9844 used_len += sizeof(*desc);
9846 if ((desc->flags & RSO_CTDP) == 0) {
9847 printf(" %s\n", op_desc);
9852 * If we don't have enough space to fit a timeout
9853 * descriptor, then we're done.
9855 if (avail_len - used_len < sizeof(*td)) {
9856 used_len = avail_len;
9857 printf(" %s\n", op_desc);
9860 cur_ptr = &buf[used_len];
9861 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9862 td_len = scsi_2btoul(td->length);
9863 td_len += sizeof(td->length);
9867 * If the given timeout descriptor length is less than what
9868 * we understand, skip it.
9870 if (td_len < sizeof(*td)) {
9871 printf(" %s\n", op_desc);
9875 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9876 scsi_4btoul(td->nominal_time),
9877 scsi_4btoul(td->recommended_time), op_desc);
9884 scsiopcodes(struct cam_device *device, int argc, char **argv,
9885 char *combinedopt, int task_attr, int retry_count, int timeout,
9889 uint32_t opcode = 0, service_action = 0;
9890 int td_set = 0, opcode_set = 0, sa_set = 0;
9891 int show_sa_errors = 1;
9892 uint32_t valid_len = 0;
9893 uint8_t *buf = NULL;
9897 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9903 opcode = strtoul(optarg, &endptr, 0);
9904 if (*endptr != '\0') {
9905 warnx("Invalid opcode \"%s\", must be a number",
9910 if (opcode > 0xff) {
9911 warnx("Invalid opcode 0x%#x, must be between"
9912 "0 and 0xff inclusive", opcode);
9919 service_action = strtoul(optarg, &endptr, 0);
9920 if (*endptr != '\0') {
9921 warnx("Invalid service action \"%s\", must "
9922 "be a number", optarg);
9926 if (service_action > 0xffff) {
9927 warnx("Invalid service action 0x%#x, must "
9928 "be between 0 and 0xffff inclusive",
9943 && (opcode_set == 0)) {
9944 warnx("You must specify an opcode with -o if a service "
9949 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9950 sa_set, service_action, td_set, task_attr,
9951 retry_count, timeout, verbosemode, &valid_len,
9956 if ((opcode_set != 0)
9958 retval = scsiprintoneopcode(device, opcode, sa_set,
9959 service_action, buf, valid_len);
9961 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9972 reprobe(struct cam_device *device)
9977 ccb = cam_getccb(device);
9980 warnx("%s: error allocating ccb", __func__);
9984 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
9986 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9988 if (cam_send_ccb(device, ccb) < 0) {
9989 warn("error sending XPT_REPROBE_LUN CCB");
9994 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9995 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
10007 usage(int printlong)
10010 fprintf(printlong ? stdout : stderr,
10011 "usage: camcontrol <command> [device id][generic args][command args]\n"
10012 " camcontrol devlist [-b] [-v]\n"
10013 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
10014 " camcontrol tur [dev_id][generic args]\n"
10015 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
10016 " camcontrol identify [dev_id][generic args] [-v]\n"
10017 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
10018 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
10019 " [-q] [-s] [-l]\n"
10020 " camcontrol start [dev_id][generic args]\n"
10021 " camcontrol stop [dev_id][generic args]\n"
10022 " camcontrol load [dev_id][generic args]\n"
10023 " camcontrol eject [dev_id][generic args]\n"
10024 " camcontrol reprobe [dev_id][generic args]\n"
10025 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
10026 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
10027 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
10028 " [-q][-s][-S offset][-X]\n"
10029 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
10030 " [-P pagectl][-e | -b][-d]\n"
10031 " camcontrol cmd [dev_id][generic args]\n"
10032 " <-a cmd [args] | -c cmd [args]>\n"
10033 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
10034 " camcontrol smpcmd [dev_id][generic args]\n"
10035 " <-r len fmt [args]> <-R len fmt [args]>\n"
10036 " camcontrol smprg [dev_id][generic args][-l]\n"
10037 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
10038 " [-o operation][-d name][-m rate][-M rate]\n"
10039 " [-T pp_timeout][-a enable|disable]\n"
10040 " [-A enable|disable][-s enable|disable]\n"
10041 " [-S enable|disable]\n"
10042 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
10043 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
10044 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
10045 " <all|dev_id|bus[:target[:lun]]|off>\n"
10046 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
10047 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
10048 " [-D <enable|disable>][-M mode][-O offset]\n"
10049 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
10050 " [-U][-W bus_width]\n"
10051 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
10052 " camcontrol sanitize [dev_id][generic args]\n"
10053 " [-a overwrite|block|crypto|exitfailure]\n"
10054 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
10056 " camcontrol idle [dev_id][generic args][-t time]\n"
10057 " camcontrol standby [dev_id][generic args][-t time]\n"
10058 " camcontrol sleep [dev_id][generic args]\n"
10059 " camcontrol powermode [dev_id][generic args]\n"
10060 " camcontrol apm [dev_id][generic args][-l level]\n"
10061 " camcontrol aam [dev_id][generic args][-l level]\n"
10062 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
10064 " camcontrol security [dev_id][generic args]\n"
10065 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
10066 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
10067 " [-U <user|master>] [-y]\n"
10068 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
10069 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
10070 " camcontrol ama [dev_id][generic args] [-f] [-q] [-s max_sectors]\n"
10071 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
10072 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
10073 " [-s scope][-S][-T type][-U]\n"
10074 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
10075 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
10076 " [-p part][-s start][-T type][-V vol]\n"
10077 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
10079 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
10080 " [-o rep_opts] [-P print_opts]\n"
10081 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
10082 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
10083 " [-S power_src] [-T timer]\n"
10084 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
10085 " <-s <-f format -T time | -U >>\n"
10086 " camcontrol devtype [dev_id]\n"
10088 " camcontrol help\n");
10092 "Specify one of the following options:\n"
10093 "devlist list all CAM devices\n"
10094 "periphlist list all CAM peripheral drivers attached to a device\n"
10095 "tur send a test unit ready to the named device\n"
10096 "inquiry send a SCSI inquiry command to the named device\n"
10097 "identify send a ATA identify command to the named device\n"
10098 "reportluns send a SCSI report luns command to the device\n"
10099 "readcap send a SCSI read capacity command to the device\n"
10100 "start send a Start Unit command to the device\n"
10101 "stop send a Stop Unit command to the device\n"
10102 "load send a Start Unit command to the device with the load bit set\n"
10103 "eject send a Stop Unit command to the device with the eject bit set\n"
10104 "reprobe update capacity information of the given device\n"
10105 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
10106 "reset reset all buses, the given bus, bus:target:lun or device\n"
10107 "defects read the defect list of the specified device\n"
10108 "modepage display or edit (-e) the given mode page\n"
10109 "cmd send the given SCSI command, may need -i or -o as well\n"
10110 "smpcmd send the given SMP command, requires -o and -i\n"
10111 "smprg send the SMP Report General command\n"
10112 "smppc send the SMP PHY Control command, requires -p\n"
10113 "smpphylist display phys attached to a SAS expander\n"
10114 "smpmaninfo send the SMP Report Manufacturer Info command\n"
10115 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
10116 "tags report or set the number of transaction slots for a device\n"
10117 "negotiate report or set device negotiation parameters\n"
10118 "format send the SCSI FORMAT UNIT command to the named device\n"
10119 "sanitize send the SCSI SANITIZE command to the named device\n"
10120 "idle send the ATA IDLE command to the named device\n"
10121 "standby send the ATA STANDBY command to the named device\n"
10122 "sleep send the ATA SLEEP command to the named device\n"
10123 "powermode send the ATA CHECK POWER MODE command to the named device\n"
10124 "fwdownload program firmware of the named device with the given image\n"
10125 "security report or send ATA security commands to the named device\n"
10126 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
10127 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
10128 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
10129 "zone manage Zoned Block (Shingled) devices\n"
10130 "epc send ATA Extended Power Conditions commands\n"
10131 "timestamp report or set the device's timestamp\n"
10132 "devtype report the type of device\n"
10133 "help this message\n"
10134 "Device Identifiers:\n"
10135 "bus:target specify the bus and target, lun defaults to 0\n"
10136 "bus:target:lun specify the bus, target and lun\n"
10137 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
10138 "Generic arguments:\n"
10139 "-v be verbose, print out sense information\n"
10140 "-t timeout command timeout in seconds, overrides default timeout\n"
10141 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
10142 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
10143 "-E have the kernel attempt to perform SCSI error recovery\n"
10144 "-C count specify the SCSI command retry count (needs -E to work)\n"
10145 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
10146 "modepage arguments:\n"
10147 "-l list all available mode pages\n"
10148 "-m page specify the mode page to view or edit\n"
10149 "-e edit the specified mode page\n"
10150 "-b force view to binary mode\n"
10151 "-d disable block descriptors for mode sense\n"
10152 "-P pgctl page control field 0-3\n"
10153 "defects arguments:\n"
10154 "-f format specify defect list format (block, bfi or phys)\n"
10155 "-G get the grown defect list\n"
10156 "-P get the permanent defect list\n"
10157 "inquiry arguments:\n"
10158 "-D get the standard inquiry data\n"
10159 "-S get the serial number\n"
10160 "-R get the transfer rate, etc.\n"
10161 "reportluns arguments:\n"
10162 "-c only report a count of available LUNs\n"
10163 "-l only print out luns, and not a count\n"
10164 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
10165 "readcap arguments\n"
10166 "-b only report the blocksize\n"
10167 "-h human readable device size, base 2\n"
10168 "-H human readable device size, base 10\n"
10169 "-N print the number of blocks instead of last block\n"
10170 "-q quiet, print numbers only\n"
10171 "-s only report the last block/device size\n"
10173 "-c cdb [args] specify the SCSI CDB\n"
10174 "-i len fmt specify input data and input data format\n"
10175 "-o len fmt [args] specify output data and output data fmt\n"
10176 "smpcmd arguments:\n"
10177 "-r len fmt [args] specify the SMP command to be sent\n"
10178 "-R len fmt [args] specify SMP response format\n"
10179 "smprg arguments:\n"
10180 "-l specify the long response format\n"
10181 "smppc arguments:\n"
10182 "-p phy specify the PHY to operate on\n"
10183 "-l specify the long request/response format\n"
10184 "-o operation specify the phy control operation\n"
10185 "-d name set the attached device name\n"
10186 "-m rate set the minimum physical link rate\n"
10187 "-M rate set the maximum physical link rate\n"
10188 "-T pp_timeout set the partial pathway timeout value\n"
10189 "-a enable|disable enable or disable SATA slumber\n"
10190 "-A enable|disable enable or disable SATA partial phy power\n"
10191 "-s enable|disable enable or disable SAS slumber\n"
10192 "-S enable|disable enable or disable SAS partial phy power\n"
10193 "smpphylist arguments:\n"
10194 "-l specify the long response format\n"
10195 "-q only print phys with attached devices\n"
10196 "smpmaninfo arguments:\n"
10197 "-l specify the long response format\n"
10198 "debug arguments:\n"
10199 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
10200 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
10201 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
10202 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
10203 "tags arguments:\n"
10204 "-N tags specify the number of tags to use for this device\n"
10205 "-q be quiet, don't report the number of tags\n"
10206 "-v report a number of tag-related parameters\n"
10207 "negotiate arguments:\n"
10208 "-a send a test unit ready after negotiation\n"
10209 "-c report/set current negotiation settings\n"
10210 "-D <arg> \"enable\" or \"disable\" disconnection\n"
10211 "-M mode set ATA mode\n"
10212 "-O offset set command delay offset\n"
10213 "-q be quiet, don't report anything\n"
10214 "-R syncrate synchronization rate in MHz\n"
10215 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
10216 "-U report/set user negotiation settings\n"
10217 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
10218 "-v also print a Path Inquiry CCB for the controller\n"
10219 "format arguments:\n"
10220 "-q be quiet, don't print status messages\n"
10221 "-r run in report only mode\n"
10222 "-w don't send immediate format command\n"
10223 "-y don't ask any questions\n"
10224 "sanitize arguments:\n"
10225 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
10226 "-c passes overwrite passes to perform (1 to 31)\n"
10227 "-I invert overwrite pattern after each pass\n"
10228 "-P pattern path to overwrite pattern file\n"
10229 "-q be quiet, don't print status messages\n"
10230 "-r run in report only mode\n"
10231 "-U run operation in unrestricted completion exit mode\n"
10232 "-w don't send immediate sanitize command\n"
10233 "-y don't ask any questions\n"
10234 "idle/standby arguments:\n"
10235 "-t <arg> number of seconds before respective state.\n"
10236 "fwdownload arguments:\n"
10237 "-f fw_image path to firmware image file\n"
10238 "-q don't print informational messages, only errors\n"
10239 "-s run in simulation mode\n"
10240 "-v print info for every firmware segment sent to device\n"
10241 "-y don't ask any questions\n"
10242 "security arguments:\n"
10243 "-d pwd disable security using the given password for the selected\n"
10245 "-e pwd erase the device using the given pwd for the selected user\n"
10246 "-f freeze the security configuration of the specified device\n"
10247 "-h pwd enhanced erase the device using the given pwd for the\n"
10249 "-k pwd unlock the device using the given pwd for the selected\n"
10251 "-l <high|maximum> specifies which security level to set: high or maximum\n"
10252 "-q be quiet, do not print any status messages\n"
10253 "-s pwd password the device (enable security) using the given\n"
10254 " pwd for the selected user\n"
10255 "-T timeout overrides the timeout (seconds) used for erase operation\n"
10256 "-U <user|master> specifies which user to set: user or master\n"
10257 "-y don't ask any questions\n"
10259 "-f freeze the HPA configuration of the device\n"
10260 "-l lock the HPA configuration of the device\n"
10261 "-P make the HPA max sectors persist\n"
10262 "-p pwd Set the HPA configuration password required for unlock\n"
10264 "-q be quiet, do not print any status messages\n"
10265 "-s sectors configures the maximum user accessible sectors of the\n"
10267 "-U pwd unlock the HPA configuration of the device\n"
10268 "-y don't ask any questions\n"
10270 "-f freeze the AMA configuration of the device\n"
10271 "-q be quiet, do not print any status messages\n"
10272 "-s sectors configures the maximum user accessible sectors of the\n"
10274 "persist arguments:\n"
10275 "-i action specify read_keys, read_reservation, report_cap, or\n"
10276 " read_full_status\n"
10277 "-o action specify register, register_ignore, reserve, release,\n"
10278 " clear, preempt, preempt_abort, register_move, replace_lost\n"
10279 "-a set the All Target Ports (ALL_TG_PT) bit\n"
10280 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
10281 "-k key specify the Reservation Key\n"
10282 "-K sa_key specify the Service Action Reservation Key\n"
10283 "-p set the Activate Persist Through Power Loss bit\n"
10284 "-R rtp specify the Relative Target Port\n"
10285 "-s scope specify the scope: lun, extent, element or a number\n"
10286 "-S specify Transport ID for register, requires -I\n"
10287 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
10288 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
10289 "-U unregister the current initiator for register_move\n"
10290 "attrib arguments:\n"
10291 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
10293 "-w attr specify an attribute to write, one -w argument per attr\n"
10294 "-a attr_num only display this attribute number\n"
10295 "-c get cached attributes\n"
10296 "-e elem_addr request attributes for the given element in a changer\n"
10297 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
10298 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
10299 " field_none, field_desc, field_num, field_size, field_rw\n"
10300 "-p partition request attributes for the given partition\n"
10301 "-s start_attr request attributes starting at the given number\n"
10302 "-T elem_type specify the element type (used with -e)\n"
10303 "-V logical_vol specify the logical volume ID\n"
10304 "opcodes arguments:\n"
10305 "-o opcode specify the individual opcode to list\n"
10306 "-s service_action specify the service action for the opcode\n"
10307 "-N do not return SCSI error for unsupported SA\n"
10308 "-T request nominal and recommended timeout values\n"
10309 "zone arguments:\n"
10310 "-c cmd required: rz, open, close, finish, or rwp\n"
10311 "-a apply the action to all zones\n"
10312 "-l LBA specify the zone starting LBA\n"
10313 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
10314 " closed, full, ro, offline, reset, nonseq, nonwp\n"
10315 "-P print_opt report zones printing: normal, summary, script\n"
10317 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
10318 " source, status, list\n"
10319 "-d disable power mode (timer, state)\n"
10320 "-D delayed entry (goto)\n"
10321 "-e enable power mode (timer, state)\n"
10322 "-H hold power mode (goto)\n"
10323 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
10325 "-P only display power mode (status)\n"
10326 "-r rst_src restore settings from: default, saved (restore)\n"
10327 "-s save mode (timer, state, restore)\n"
10328 "-S power_src set power source: battery, nonbattery (source)\n"
10329 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
10330 "timestamp arguments:\n"
10331 "-r report the timestamp of the device\n"
10332 "-f format report the timestamp of the device with the given\n"
10333 " strftime(3) format string\n"
10334 "-m report the timestamp of the device as milliseconds since\n"
10335 " January 1st, 1970\n"
10336 "-U report the time with UTC instead of the local time zone\n"
10337 "-s set the timestamp of the device\n"
10338 "-f format the format of the time string passed into strptime(3)\n"
10339 "-T time the time value passed into strptime(3)\n"
10340 "-U set the timestamp of the device to UTC time\n"
10345 main(int argc, char **argv)
10348 char *device = NULL;
10350 struct cam_device *cam_dev = NULL;
10351 int timeout = 0, retry_count = 1;
10352 camcontrol_optret optreturn;
10354 const char *mainopt = "C:En:Q:t:u:v";
10355 const char *subopt = NULL;
10356 char combinedopt[256];
10357 int error = 0, optstart = 2;
10358 int task_attr = MSG_SIMPLE_Q_TAG;
10361 target_id_t target;
10364 cmdlist = CAM_CMD_NONE;
10365 arglist = CAM_ARG_NONE;
10373 * Get the base option.
10375 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
10377 if (optreturn == CC_OR_AMBIGUOUS) {
10378 warnx("ambiguous option %s", argv[1]);
10381 } else if (optreturn == CC_OR_NOT_FOUND) {
10382 warnx("option %s not found", argv[1]);
10388 * Ahh, getopt(3) is a pain.
10390 * This is a gross hack. There really aren't many other good
10391 * options (excuse the pun) for parsing options in a situation like
10392 * this. getopt is kinda braindead, so you end up having to run
10393 * through the options twice, and give each invocation of getopt
10394 * the option string for the other invocation.
10396 * You would think that you could just have two groups of options.
10397 * The first group would get parsed by the first invocation of
10398 * getopt, and the second group would get parsed by the second
10399 * invocation of getopt. It doesn't quite work out that way. When
10400 * the first invocation of getopt finishes, it leaves optind pointing
10401 * to the argument _after_ the first argument in the second group.
10402 * So when the second invocation of getopt comes around, it doesn't
10403 * recognize the first argument it gets and then bails out.
10405 * A nice alternative would be to have a flag for getopt that says
10406 * "just keep parsing arguments even when you encounter an unknown
10407 * argument", but there isn't one. So there's no real clean way to
10408 * easily parse two sets of arguments without having one invocation
10409 * of getopt know about the other.
10411 * Without this hack, the first invocation of getopt would work as
10412 * long as the generic arguments are first, but the second invocation
10413 * (in the subfunction) would fail in one of two ways. In the case
10414 * where you don't set optreset, it would fail because optind may be
10415 * pointing to the argument after the one it should be pointing at.
10416 * In the case where you do set optreset, and reset optind, it would
10417 * fail because getopt would run into the first set of options, which
10418 * it doesn't understand.
10420 * All of this would "sort of" work if you could somehow figure out
10421 * whether optind had been incremented one option too far. The
10422 * mechanics of that, however, are more daunting than just giving
10423 * both invocations all of the expect options for either invocation.
10425 * Needless to say, I wouldn't mind if someone invented a better
10426 * (non-GPL!) command line parsing interface than getopt. I
10427 * wouldn't mind if someone added more knobs to getopt to make it
10428 * work better. Who knows, I may talk myself into doing it someday,
10429 * if the standards weenies let me. As it is, it just leads to
10430 * hackery like this and causes people to avoid it in some cases.
10432 * KDM, September 8th, 1998
10434 if (subopt != NULL)
10435 sprintf(combinedopt, "%s%s", mainopt, subopt);
10437 sprintf(combinedopt, "%s", mainopt);
10440 * For these options we do not parse optional device arguments and
10441 * we do not open a passthrough device.
10443 if ((cmdlist == CAM_CMD_RESCAN)
10444 || (cmdlist == CAM_CMD_RESET)
10445 || (cmdlist == CAM_CMD_DEVTREE)
10446 || (cmdlist == CAM_CMD_USAGE)
10447 || (cmdlist == CAM_CMD_DEBUG))
10451 && (argc > 2 && argv[2][0] != '-')) {
10455 if (isdigit(argv[2][0])) {
10456 /* device specified as bus:target[:lun] */
10457 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10459 errx(1, "numeric device specification must "
10460 "be either bus:target, or "
10462 /* default to 0 if lun was not specified */
10463 if ((arglist & CAM_ARG_LUN) == 0) {
10465 arglist |= CAM_ARG_LUN;
10469 if (cam_get_device(argv[2], name, sizeof name, &unit)
10471 errx(1, "%s", cam_errbuf);
10472 device = strdup(name);
10473 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10478 * Start getopt processing at argv[2/3], since we've already
10479 * accepted argv[1..2] as the command name, and as a possible
10485 * Now we run through the argument list looking for generic
10486 * options, and ignoring options that possibly belong to
10489 while ((c = getopt(argc, argv, combinedopt))!= -1){
10492 retry_count = strtol(optarg, NULL, 0);
10493 if (retry_count < 0)
10494 errx(1, "retry count %d is < 0",
10496 arglist |= CAM_ARG_RETRIES;
10499 arglist |= CAM_ARG_ERR_RECOVER;
10502 arglist |= CAM_ARG_DEVICE;
10504 while (isspace(*tstr) && (*tstr != '\0'))
10506 device = (char *)strdup(tstr);
10510 int table_entry = 0;
10513 while (isspace(*tstr) && (*tstr != '\0'))
10515 if (isdigit(*tstr)) {
10516 task_attr = strtol(tstr, &endptr, 0);
10517 if (*endptr != '\0') {
10518 errx(1, "Invalid queue option "
10523 scsi_nv_status status;
10525 table_size = sizeof(task_attrs) /
10526 sizeof(task_attrs[0]);
10527 status = scsi_get_nv(task_attrs,
10528 table_size, tstr, &table_entry,
10529 SCSI_NV_FLAG_IG_CASE);
10530 if (status == SCSI_NV_FOUND)
10531 task_attr = task_attrs[
10532 table_entry].value;
10534 errx(1, "%s option %s",
10535 (status == SCSI_NV_AMBIGUOUS)?
10536 "ambiguous" : "invalid",
10543 timeout = strtol(optarg, NULL, 0);
10545 errx(1, "invalid timeout %d", timeout);
10546 /* Convert the timeout from seconds to ms */
10548 arglist |= CAM_ARG_TIMEOUT;
10551 arglist |= CAM_ARG_UNIT;
10552 unit = strtol(optarg, NULL, 0);
10555 arglist |= CAM_ARG_VERBOSE;
10563 * For most commands we'll want to open the passthrough device
10564 * associated with the specified device. In the case of the rescan
10565 * commands, we don't use a passthrough device at all, just the
10566 * transport layer device.
10568 if (devopen == 1) {
10569 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10570 && (((arglist & CAM_ARG_DEVICE) == 0)
10571 || ((arglist & CAM_ARG_UNIT) == 0))) {
10572 errx(1, "subcommand \"%s\" requires a valid device "
10573 "identifier", argv[1]);
10576 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10577 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10578 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10580 errx(1,"%s", cam_errbuf);
10584 * Reset optind to 2, and reset getopt, so these routines can parse
10585 * the arguments again.
10591 case CAM_CMD_DEVLIST:
10592 error = getdevlist(cam_dev);
10595 error = atahpa(cam_dev, retry_count, timeout,
10596 argc, argv, combinedopt);
10599 error = ataama(cam_dev, retry_count, timeout,
10600 argc, argv, combinedopt);
10602 case CAM_CMD_DEVTREE:
10603 error = getdevtree(argc, argv, combinedopt);
10605 case CAM_CMD_DEVTYPE:
10606 error = getdevtype(cam_dev);
10609 error = testunitready(cam_dev, task_attr, retry_count,
10612 case CAM_CMD_INQUIRY:
10613 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10614 task_attr, retry_count, timeout);
10616 case CAM_CMD_IDENTIFY:
10617 error = identify(cam_dev, retry_count, timeout);
10619 case CAM_CMD_STARTSTOP:
10620 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10621 arglist & CAM_ARG_EJECT, task_attr,
10622 retry_count, timeout);
10624 case CAM_CMD_RESCAN:
10625 error = dorescan_or_reset(argc, argv, 1);
10627 case CAM_CMD_RESET:
10628 error = dorescan_or_reset(argc, argv, 0);
10630 case CAM_CMD_READ_DEFECTS:
10631 error = readdefects(cam_dev, argc, argv, combinedopt,
10632 task_attr, retry_count, timeout);
10634 case CAM_CMD_MODE_PAGE:
10635 modepage(cam_dev, argc, argv, combinedopt,
10636 task_attr, retry_count, timeout);
10638 case CAM_CMD_SCSI_CMD:
10639 error = scsicmd(cam_dev, argc, argv, combinedopt,
10640 task_attr, retry_count, timeout);
10642 case CAM_CMD_MMCSD_CMD:
10643 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10644 retry_count, timeout);
10646 case CAM_CMD_SMP_CMD:
10647 error = smpcmd(cam_dev, argc, argv, combinedopt,
10648 retry_count, timeout);
10650 case CAM_CMD_SMP_RG:
10651 error = smpreportgeneral(cam_dev, argc, argv,
10652 combinedopt, retry_count,
10655 case CAM_CMD_SMP_PC:
10656 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10657 retry_count, timeout);
10659 case CAM_CMD_SMP_PHYLIST:
10660 error = smpphylist(cam_dev, argc, argv, combinedopt,
10661 retry_count, timeout);
10663 case CAM_CMD_SMP_MANINFO:
10664 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10665 retry_count, timeout);
10667 case CAM_CMD_DEBUG:
10668 error = camdebug(argc, argv, combinedopt);
10671 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10674 error = ratecontrol(cam_dev, task_attr, retry_count,
10675 timeout, argc, argv, combinedopt);
10677 case CAM_CMD_FORMAT:
10678 error = scsiformat(cam_dev, argc, argv,
10679 combinedopt, task_attr, retry_count,
10682 case CAM_CMD_REPORTLUNS:
10683 error = scsireportluns(cam_dev, argc, argv,
10684 combinedopt, task_attr,
10685 retry_count, timeout);
10687 case CAM_CMD_READCAP:
10688 error = scsireadcapacity(cam_dev, argc, argv,
10689 combinedopt, task_attr,
10690 retry_count, timeout);
10693 case CAM_CMD_STANDBY:
10694 case CAM_CMD_SLEEP:
10695 case CAM_CMD_POWER_MODE:
10696 error = atapm(cam_dev, argc, argv,
10697 combinedopt, retry_count, timeout);
10701 error = ataaxm(cam_dev, argc, argv,
10702 combinedopt, retry_count, timeout);
10704 case CAM_CMD_SECURITY:
10705 error = atasecurity(cam_dev, retry_count, timeout,
10706 argc, argv, combinedopt);
10708 case CAM_CMD_DOWNLOAD_FW:
10709 error = fwdownload(cam_dev, argc, argv, combinedopt,
10710 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10713 case CAM_CMD_SANITIZE:
10714 error = sanitize(cam_dev, argc, argv, combinedopt, task_attr,
10715 retry_count, timeout);
10717 case CAM_CMD_PERSIST:
10718 error = scsipersist(cam_dev, argc, argv, combinedopt,
10719 task_attr, retry_count, timeout,
10720 arglist & CAM_ARG_VERBOSE,
10721 arglist & CAM_ARG_ERR_RECOVER);
10723 case CAM_CMD_ATTRIB:
10724 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10725 task_attr, retry_count, timeout,
10726 arglist & CAM_ARG_VERBOSE,
10727 arglist & CAM_ARG_ERR_RECOVER);
10729 case CAM_CMD_OPCODES:
10730 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10731 task_attr, retry_count, timeout,
10732 arglist & CAM_ARG_VERBOSE);
10734 case CAM_CMD_REPROBE:
10735 error = reprobe(cam_dev);
10738 error = zone(cam_dev, argc, argv, combinedopt,
10739 task_attr, retry_count, timeout,
10740 arglist & CAM_ARG_VERBOSE);
10743 error = epc(cam_dev, argc, argv, combinedopt,
10744 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10746 case CAM_CMD_TIMESTAMP:
10747 error = timestamp(cam_dev, argc, argv, combinedopt,
10748 task_attr, retry_count, timeout,
10749 arglist & CAM_ARG_VERBOSE);
10751 case CAM_CMD_USAGE:
10760 if (cam_dev != NULL)
10761 cam_close_device(cam_dev);