2 * Copyright (c) 1997-2007 Kenneth D. Merry
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/ioctl.h>
33 #include <sys/stdint.h>
34 #include <sys/types.h>
36 #include <sys/endian.h>
53 #include <cam/cam_debug.h>
54 #include <cam/cam_ccb.h>
55 #include <cam/scsi/scsi_all.h>
56 #include <cam/scsi/scsi_da.h>
57 #include <cam/scsi/scsi_pass.h>
58 #include <cam/scsi/scsi_message.h>
59 #include <cam/scsi/smp_all.h>
60 #include <cam/ata/ata_all.h>
61 #include <cam/mmc/mmc_all.h>
63 #include "camcontrol.h"
65 #include "nvmecontrol_ext.h"
69 CAM_CMD_NONE = 0x00000000,
70 CAM_CMD_DEVLIST = 0x00000001,
71 CAM_CMD_TUR = 0x00000002,
72 CAM_CMD_INQUIRY = 0x00000003,
73 CAM_CMD_STARTSTOP = 0x00000004,
74 CAM_CMD_RESCAN = 0x00000005,
75 CAM_CMD_READ_DEFECTS = 0x00000006,
76 CAM_CMD_MODE_PAGE = 0x00000007,
77 CAM_CMD_SCSI_CMD = 0x00000008,
78 CAM_CMD_DEVTREE = 0x00000009,
79 CAM_CMD_USAGE = 0x0000000a,
80 CAM_CMD_DEBUG = 0x0000000b,
81 CAM_CMD_RESET = 0x0000000c,
82 CAM_CMD_FORMAT = 0x0000000d,
83 CAM_CMD_TAG = 0x0000000e,
84 CAM_CMD_RATE = 0x0000000f,
85 CAM_CMD_DETACH = 0x00000010,
86 CAM_CMD_REPORTLUNS = 0x00000011,
87 CAM_CMD_READCAP = 0x00000012,
88 CAM_CMD_IDENTIFY = 0x00000013,
89 CAM_CMD_IDLE = 0x00000014,
90 CAM_CMD_STANDBY = 0x00000015,
91 CAM_CMD_SLEEP = 0x00000016,
92 CAM_CMD_SMP_CMD = 0x00000017,
93 CAM_CMD_SMP_RG = 0x00000018,
94 CAM_CMD_SMP_PC = 0x00000019,
95 CAM_CMD_SMP_PHYLIST = 0x0000001a,
96 CAM_CMD_SMP_MANINFO = 0x0000001b,
97 CAM_CMD_DOWNLOAD_FW = 0x0000001c,
98 CAM_CMD_SECURITY = 0x0000001d,
99 CAM_CMD_HPA = 0x0000001e,
100 CAM_CMD_SANITIZE = 0x0000001f,
101 CAM_CMD_PERSIST = 0x00000020,
102 CAM_CMD_APM = 0x00000021,
103 CAM_CMD_AAM = 0x00000022,
104 CAM_CMD_ATTRIB = 0x00000023,
105 CAM_CMD_OPCODES = 0x00000024,
106 CAM_CMD_REPROBE = 0x00000025,
107 CAM_CMD_ZONE = 0x00000026,
108 CAM_CMD_EPC = 0x00000027,
109 CAM_CMD_TIMESTAMP = 0x00000028,
110 CAM_CMD_MMCSD_CMD = 0x00000029,
111 CAM_CMD_POWER_MODE = 0x0000002a,
112 CAM_CMD_DEVTYPE = 0x0000002b,
113 CAM_CMD_AMA = 0x0000002c,
117 CAM_ARG_NONE = 0x00000000,
118 CAM_ARG_VERBOSE = 0x00000001,
119 CAM_ARG_DEVICE = 0x00000002,
120 CAM_ARG_BUS = 0x00000004,
121 CAM_ARG_TARGET = 0x00000008,
122 CAM_ARG_LUN = 0x00000010,
123 CAM_ARG_EJECT = 0x00000020,
124 CAM_ARG_UNIT = 0x00000040,
125 CAM_ARG_FORMAT_BLOCK = 0x00000080,
126 CAM_ARG_FORMAT_BFI = 0x00000100,
127 CAM_ARG_FORMAT_PHYS = 0x00000200,
128 CAM_ARG_PLIST = 0x00000400,
129 CAM_ARG_GLIST = 0x00000800,
130 CAM_ARG_GET_SERIAL = 0x00001000,
131 CAM_ARG_GET_STDINQ = 0x00002000,
132 CAM_ARG_GET_XFERRATE = 0x00004000,
133 CAM_ARG_INQ_MASK = 0x00007000,
134 CAM_ARG_TIMEOUT = 0x00020000,
135 CAM_ARG_CMD_IN = 0x00040000,
136 CAM_ARG_CMD_OUT = 0x00080000,
137 CAM_ARG_ERR_RECOVER = 0x00200000,
138 CAM_ARG_RETRIES = 0x00400000,
139 CAM_ARG_START_UNIT = 0x00800000,
140 CAM_ARG_DEBUG_INFO = 0x01000000,
141 CAM_ARG_DEBUG_TRACE = 0x02000000,
142 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
143 CAM_ARG_DEBUG_CDB = 0x08000000,
144 CAM_ARG_DEBUG_XPT = 0x10000000,
145 CAM_ARG_DEBUG_PERIPH = 0x20000000,
146 CAM_ARG_DEBUG_PROBE = 0x40000000,
149 struct camcontrol_opts {
156 struct ata_res_pass16 {
157 u_int16_t reserved[5];
160 u_int8_t sector_count_exp;
161 u_int8_t sector_count;
162 u_int8_t lba_low_exp;
164 u_int8_t lba_mid_exp;
166 u_int8_t lba_high_exp;
172 struct ata_set_max_pwd
175 u_int8_t password[32];
176 u_int16_t reserved2[239];
179 static struct scsi_nv task_attrs[] = {
180 { "simple", MSG_SIMPLE_Q_TAG },
181 { "head", MSG_HEAD_OF_Q_TAG },
182 { "ordered", MSG_ORDERED_Q_TAG },
183 { "iwr", MSG_IGN_WIDE_RESIDUE },
184 { "aca", MSG_ACA_TASK }
187 static const char scsicmd_opts[] = "a:c:dfi:o:r";
188 static const char readdefect_opts[] = "f:GPqsS:X";
189 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
190 static const char smprg_opts[] = "l";
191 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
192 static const char smpphylist_opts[] = "lq";
195 static struct camcontrol_opts option_table[] = {
196 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
197 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
198 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
199 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
200 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
201 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
202 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
203 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
204 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHlNqs"},
205 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
206 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
207 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
208 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
209 {"mmcsdcmd", CAM_CMD_MMCSD_CMD, CAM_ARG_NONE, "c:a:f:Wb:l:41S:I"},
210 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
211 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
212 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
213 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
214 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
215 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
216 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
217 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
218 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
219 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
220 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
221 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
222 {"devtype", CAM_CMD_DEVTYPE, CAM_ARG_NONE, ""},
223 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
224 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "6bdelm:DLP:"},
225 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
226 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
227 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
228 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
229 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
230 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
231 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
232 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
233 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
234 {"powermode", CAM_CMD_POWER_MODE, CAM_ARG_NONE, ""},
235 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
236 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
237 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
238 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
239 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
240 {"ama", CAM_CMD_AMA, CAM_ARG_NONE, "fqs:"},
241 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
242 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
243 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
244 {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
245 {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
246 {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
247 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
248 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
249 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
254 struct device_match_result dev_match;
256 struct periph_match_result *periph_matches;
257 struct scsi_vpd_device_id *device_id;
259 STAILQ_ENTRY(cam_devitem) links;
263 STAILQ_HEAD(, cam_devitem) dev_queue;
267 static cam_cmdmask cmdlist;
268 static cam_argmask arglist;
270 static const char *devtype_names[] = {
280 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
281 uint32_t *cmdnum, cam_argmask *argnum,
282 const char **subopt);
283 static int getdevlist(struct cam_device *device);
284 static int getdevtree(int argc, char **argv, char *combinedopt);
285 static int getdevtype(struct cam_device *device);
286 static int print_dev_scsi(struct device_match_result *dev_result, char *tmpstr);
287 static int print_dev_ata(struct device_match_result *dev_result, char *tmpstr);
288 static int print_dev_semb(struct device_match_result *dev_result, char *tmpstr);
289 static int print_dev_mmcsd(struct device_match_result *dev_result,
292 static int print_dev_nvme(struct device_match_result *dev_result, char *tmpstr);
294 static int testunitready(struct cam_device *device, int task_attr,
295 int retry_count, int timeout, int quiet);
296 static int scsistart(struct cam_device *device, int startstop, int loadeject,
297 int task_attr, int retry_count, int timeout);
298 static int scsiinquiry(struct cam_device *device, int task_attr,
299 int retry_count, int timeout);
300 static int scsiserial(struct cam_device *device, int task_attr,
301 int retry_count, int timeout);
302 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
303 lun_id_t *lun, cam_argmask *arglst);
304 static int reprobe(struct cam_device *device);
305 static int dorescan_or_reset(int argc, char **argv, int rescan);
306 static int rescan_or_reset_bus(path_id_t bus, int rescan);
307 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
308 lun_id_t lun, int scan);
309 static int readdefects(struct cam_device *device, int argc, char **argv,
310 char *combinedopt, int task_attr, int retry_count,
312 static void modepage(struct cam_device *device, int argc, char **argv,
313 char *combinedopt, int task_attr, int retry_count,
315 static int scsicmd(struct cam_device *device, int argc, char **argv,
316 char *combinedopt, int task_attr, int retry_count,
318 static int smpcmd(struct cam_device *device, int argc, char **argv,
319 char *combinedopt, int retry_count, int timeout);
320 static int mmcsdcmd(struct cam_device *device, int argc, char **argv,
321 char *combinedopt, int retry_count, int timeout);
322 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
323 char *combinedopt, int retry_count, int timeout);
324 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
325 char *combinedopt, int retry_count, int timeout);
326 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
327 char *combinedopt, int retry_count, int timeout);
328 static int getdevid(struct cam_devitem *item);
329 static int buildbusdevlist(struct cam_devlist *devlist);
330 static void freebusdevlist(struct cam_devlist *devlist);
331 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
333 static int smpphylist(struct cam_device *device, int argc, char **argv,
334 char *combinedopt, int retry_count, int timeout);
335 static int tagcontrol(struct cam_device *device, int argc, char **argv,
337 static void cts_print(struct cam_device *device,
338 struct ccb_trans_settings *cts);
339 static void cpi_print(struct ccb_pathinq *cpi);
340 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
341 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
342 static int get_print_cts(struct cam_device *device, int user_settings,
343 int quiet, struct ccb_trans_settings *cts);
344 static int ratecontrol(struct cam_device *device, int task_attr,
345 int retry_count, int timeout, int argc, char **argv,
347 static int scsiformat(struct cam_device *device, int argc, char **argv,
348 char *combinedopt, int task_attr, int retry_count,
350 static int sanitize(struct cam_device *device, int argc, char **argv,
351 char *combinedopt, int task_attr, int retry_count,
353 static int scsireportluns(struct cam_device *device, int argc, char **argv,
354 char *combinedopt, int task_attr, int retry_count,
356 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
357 char *combinedopt, int task_attr, int retry_count,
359 static int atapm(struct cam_device *device, int argc, char **argv,
360 char *combinedopt, int retry_count, int timeout);
361 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
362 int argc, char **argv, char *combinedopt);
363 static int atahpa(struct cam_device *device, int retry_count, int timeout,
364 int argc, char **argv, char *combinedopt);
365 static int ataama(struct cam_device *device, int retry_count, int timeout,
366 int argc, char **argv, char *combinedopt);
367 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
368 int sa_set, int req_sa, uint8_t *buf,
370 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
372 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
373 char *combinedopt, int task_attr, int retry_count,
374 int timeout, int verbose);
377 #define min(a,b) (((a)<(b))?(a):(b))
380 #define max(a,b) (((a)>(b))?(a):(b))
384 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
385 cam_argmask *argnum, const char **subopt)
387 struct camcontrol_opts *opts;
390 for (opts = table; (opts != NULL) && (opts->optname != NULL);
392 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
393 *cmdnum = opts->cmdnum;
394 *argnum = opts->argnum;
395 *subopt = opts->subopt;
396 if (++num_matches > 1)
397 return (CC_OR_AMBIGUOUS);
402 return (CC_OR_FOUND);
404 return (CC_OR_NOT_FOUND);
408 getdevlist(struct cam_device *device)
414 ccb = cam_getccb(device);
416 ccb->ccb_h.func_code = XPT_GDEVLIST;
417 ccb->ccb_h.flags = CAM_DIR_NONE;
418 ccb->ccb_h.retry_count = 1;
420 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
421 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
422 if (cam_send_ccb(device, ccb) < 0) {
423 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 llbaa, int pc,
4590 int page, int subpage, int task_attr, int retry_count, int timeout,
4591 u_int8_t *data, int datalen)
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);
4623 if (llbaa && ccb->csio.cdb_len == 10) {
4624 struct scsi_mode_sense_10 *cdb =
4625 (struct scsi_mode_sense_10 *)ccb->csio.cdb_io.cdb_bytes;
4626 cdb->byte2 |= SMS10_LLBAA;
4629 /* Record what CDB size the above function really set. */
4630 *cdb_len = ccb->csio.cdb_len;
4632 if (arglist & CAM_ARG_ERR_RECOVER)
4633 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4635 /* Disable freezing the device queue */
4636 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4638 if (cam_send_ccb(device, ccb) < 0)
4639 err(1, "error sending mode sense command");
4641 /* In case of ILLEGEL REQUEST try to fall back to 6-byte command. */
4642 if (*cdb_len != 6 &&
4643 ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID ||
4644 (scsi_extract_sense_ccb(ccb, &error_code, &sense_key, &asc, &ascq)
4645 && sense_key == SSD_KEY_ILLEGAL_REQUEST))) {
4650 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4651 if (arglist & CAM_ARG_VERBOSE) {
4652 cam_error_print(device, ccb, CAM_ESF_ALL,
4653 CAM_EPF_ALL, stderr);
4656 cam_close_device(device);
4657 errx(1, "mode sense command returned error");
4664 mode_select(struct cam_device *device, int cdb_len, int save_pages,
4665 int task_attr, int retry_count, int timeout, u_int8_t *data, int datalen)
4670 ccb = cam_getccb(device);
4673 errx(1, "mode_select: couldn't allocate CCB");
4675 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4677 scsi_mode_select_len(&ccb->csio,
4678 /* retries */ retry_count,
4680 /* tag_action */ task_attr,
4681 /* scsi_page_fmt */ 1,
4682 /* save_pages */ save_pages,
4683 /* param_buf */ data,
4684 /* param_len */ datalen,
4685 /* minimum_cmd_size */ cdb_len,
4686 /* sense_len */ SSD_FULL_SIZE,
4687 /* timeout */ timeout ? timeout : 5000);
4689 if (arglist & CAM_ARG_ERR_RECOVER)
4690 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4692 /* Disable freezing the device queue */
4693 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4695 if (((retval = cam_send_ccb(device, ccb)) < 0)
4696 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4697 if (arglist & CAM_ARG_VERBOSE) {
4698 cam_error_print(device, ccb, CAM_ESF_ALL,
4699 CAM_EPF_ALL, stderr);
4702 cam_close_device(device);
4705 err(1, "error sending mode select command");
4707 errx(1, "error sending mode select command");
4715 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4716 int task_attr, int retry_count, int timeout)
4719 int c, page = -1, subpage = -1, pc = 0, llbaa = 0;
4720 int binary = 0, cdb_len = 10, dbd = 0, desc = 0, edit = 0, list = 0;
4722 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4740 str_subpage = optarg;
4741 strsep(&str_subpage, ",");
4742 page = strtol(optarg, NULL, 0);
4744 subpage = strtol(str_subpage, NULL, 0);
4748 errx(1, "invalid mode page %d", page);
4750 errx(1, "invalid mode subpage %d", subpage);
4759 pc = strtol(optarg, NULL, 0);
4760 if ((pc < 0) || (pc > 3))
4761 errx(1, "invalid page control field %d", pc);
4768 if (page == -1 && desc == 0 && list == 0)
4769 errx(1, "you must specify a mode page!");
4772 errx(1, "-d and -D are incompatible!");
4774 if (llbaa && cdb_len != 10)
4775 errx(1, "LLBAA bit is not present in MODE SENSE(6)!");
4778 mode_list(device, cdb_len, dbd, pc, list > 1, task_attr,
4779 retry_count, timeout);
4781 mode_edit(device, cdb_len, desc, dbd, llbaa, pc, page, subpage,
4782 edit, binary, task_attr, retry_count, timeout);
4787 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4788 int task_attr, int retry_count, int timeout)
4791 u_int32_t flags = CAM_DIR_NONE;
4792 u_int8_t *data_ptr = NULL;
4794 u_int8_t atacmd[12];
4795 struct get_hook hook;
4796 int c, data_bytes = 0, valid_bytes;
4802 char *datastr = NULL, *tstr, *resstr = NULL;
4804 int fd_data = 0, fd_res = 0;
4807 ccb = cam_getccb(device);
4810 warnx("scsicmd: error allocating ccb");
4814 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4816 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4820 while (isspace(*tstr) && (*tstr != '\0'))
4822 hook.argc = argc - optind;
4823 hook.argv = argv + optind;
4825 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4828 * Increment optind by the number of arguments the
4829 * encoding routine processed. After each call to
4830 * getopt(3), optind points to the argument that
4831 * getopt should process _next_. In this case,
4832 * that means it points to the first command string
4833 * argument, if there is one. Once we increment
4834 * this, it should point to either the next command
4835 * line argument, or it should be past the end of
4842 while (isspace(*tstr) && (*tstr != '\0'))
4844 hook.argc = argc - optind;
4845 hook.argv = argv + optind;
4847 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4850 * Increment optind by the number of arguments the
4851 * encoding routine processed. After each call to
4852 * getopt(3), optind points to the argument that
4853 * getopt should process _next_. In this case,
4854 * that means it points to the first command string
4855 * argument, if there is one. Once we increment
4856 * this, it should point to either the next command
4857 * line argument, or it should be past the end of
4869 if (arglist & CAM_ARG_CMD_OUT) {
4870 warnx("command must either be "
4871 "read or write, not both");
4873 goto scsicmd_bailout;
4875 arglist |= CAM_ARG_CMD_IN;
4877 data_bytes = strtol(optarg, NULL, 0);
4878 if (data_bytes <= 0) {
4879 warnx("invalid number of input bytes %d",
4882 goto scsicmd_bailout;
4884 hook.argc = argc - optind;
4885 hook.argv = argv + optind;
4888 datastr = cget(&hook, NULL);
4890 * If the user supplied "-" instead of a format, he
4891 * wants the data to be written to stdout.
4893 if ((datastr != NULL)
4894 && (datastr[0] == '-'))
4897 data_ptr = (u_int8_t *)malloc(data_bytes);
4898 if (data_ptr == NULL) {
4899 warnx("can't malloc memory for data_ptr");
4901 goto scsicmd_bailout;
4905 if (arglist & CAM_ARG_CMD_IN) {
4906 warnx("command must either be "
4907 "read or write, not both");
4909 goto scsicmd_bailout;
4911 arglist |= CAM_ARG_CMD_OUT;
4912 flags = CAM_DIR_OUT;
4913 data_bytes = strtol(optarg, NULL, 0);
4914 if (data_bytes <= 0) {
4915 warnx("invalid number of output bytes %d",
4918 goto scsicmd_bailout;
4920 hook.argc = argc - optind;
4921 hook.argv = argv + optind;
4923 datastr = cget(&hook, NULL);
4924 data_ptr = (u_int8_t *)malloc(data_bytes);
4925 if (data_ptr == NULL) {
4926 warnx("can't malloc memory for data_ptr");
4928 goto scsicmd_bailout;
4930 bzero(data_ptr, data_bytes);
4932 * If the user supplied "-" instead of a format, he
4933 * wants the data to be read from stdin.
4935 if ((datastr != NULL)
4936 && (datastr[0] == '-'))
4939 buff_encode_visit(data_ptr, data_bytes, datastr,
4945 hook.argc = argc - optind;
4946 hook.argv = argv + optind;
4948 resstr = cget(&hook, NULL);
4949 if ((resstr != NULL) && (resstr[0] == '-'))
4959 * If fd_data is set, and we're writing to the device, we need to
4960 * read the data the user wants written from stdin.
4962 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4964 int amt_to_read = data_bytes;
4965 u_int8_t *buf_ptr = data_ptr;
4967 for (amt_read = 0; amt_to_read > 0;
4968 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4969 if (amt_read == -1) {
4970 warn("error reading data from stdin");
4972 goto scsicmd_bailout;
4974 amt_to_read -= amt_read;
4975 buf_ptr += amt_read;
4979 if (arglist & CAM_ARG_ERR_RECOVER)
4980 flags |= CAM_PASS_ERR_RECOVER;
4982 /* Disable freezing the device queue */
4983 flags |= CAM_DEV_QFRZDIS;
4987 * This is taken from the SCSI-3 draft spec.
4988 * (T10/1157D revision 0.3)
4989 * The top 3 bits of an opcode are the group code.
4990 * The next 5 bits are the command code.
4991 * Group 0: six byte commands
4992 * Group 1: ten byte commands
4993 * Group 2: ten byte commands
4995 * Group 4: sixteen byte commands
4996 * Group 5: twelve byte commands
4997 * Group 6: vendor specific
4998 * Group 7: vendor specific
5000 switch((cdb[0] >> 5) & 0x7) {
5011 /* computed by buff_encode_visit */
5022 * We should probably use csio_build_visit or something like that
5023 * here, but it's easier to encode arguments as you go. The
5024 * alternative would be skipping the CDB argument and then encoding
5025 * it here, since we've got the data buffer argument by now.
5027 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
5029 cam_fill_csio(&ccb->csio,
5030 /*retries*/ retry_count,
5033 /*tag_action*/ task_attr,
5034 /*data_ptr*/ data_ptr,
5035 /*dxfer_len*/ data_bytes,
5036 /*sense_len*/ SSD_FULL_SIZE,
5037 /*cdb_len*/ cdb_len,
5038 /*timeout*/ timeout ? timeout : 5000);
5041 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
5043 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5045 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5047 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5049 cam_fill_ataio(&ccb->ataio,
5050 /*retries*/ retry_count,
5054 /*data_ptr*/ data_ptr,
5055 /*dxfer_len*/ data_bytes,
5056 /*timeout*/ timeout ? timeout : 5000);
5059 if (((retval = cam_send_ccb(device, ccb)) < 0)
5060 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
5061 const char warnstr[] = "error sending command";
5068 if (arglist & CAM_ARG_VERBOSE) {
5069 cam_error_print(device, ccb, CAM_ESF_ALL,
5070 CAM_EPF_ALL, stderr);
5074 goto scsicmd_bailout;
5077 if (atacmd_len && need_res) {
5079 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
5081 fprintf(stdout, "\n");
5084 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
5085 ccb->ataio.res.status,
5086 ccb->ataio.res.error,
5087 ccb->ataio.res.lba_low,
5088 ccb->ataio.res.lba_mid,
5089 ccb->ataio.res.lba_high,
5090 ccb->ataio.res.device,
5091 ccb->ataio.res.lba_low_exp,
5092 ccb->ataio.res.lba_mid_exp,
5093 ccb->ataio.res.lba_high_exp,
5094 ccb->ataio.res.sector_count,
5095 ccb->ataio.res.sector_count_exp);
5101 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
5103 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
5104 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
5105 && (arglist & CAM_ARG_CMD_IN)
5106 && (valid_bytes > 0)) {
5108 buff_decode_visit(data_ptr, valid_bytes, datastr,
5110 fprintf(stdout, "\n");
5112 ssize_t amt_written;
5113 int amt_to_write = valid_bytes;
5114 u_int8_t *buf_ptr = data_ptr;
5116 for (amt_written = 0; (amt_to_write > 0) &&
5117 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
5118 amt_to_write -= amt_written;
5119 buf_ptr += amt_written;
5121 if (amt_written == -1) {
5122 warn("error writing data to stdout");
5124 goto scsicmd_bailout;
5125 } else if ((amt_written == 0)
5126 && (amt_to_write > 0)) {
5127 warnx("only wrote %u bytes out of %u",
5128 valid_bytes - amt_to_write, valid_bytes);
5135 if ((data_bytes > 0) && (data_ptr != NULL))
5144 camdebug(int argc, char **argv, char *combinedopt)
5147 path_id_t bus = CAM_BUS_WILDCARD;
5148 target_id_t target = CAM_TARGET_WILDCARD;
5149 lun_id_t lun = CAM_LUN_WILDCARD;
5154 bzero(&ccb, sizeof(union ccb));
5156 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5159 arglist |= CAM_ARG_DEBUG_INFO;
5160 ccb.cdbg.flags |= CAM_DEBUG_INFO;
5163 arglist |= CAM_ARG_DEBUG_PERIPH;
5164 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
5167 arglist |= CAM_ARG_DEBUG_SUBTRACE;
5168 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
5171 arglist |= CAM_ARG_DEBUG_TRACE;
5172 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
5175 arglist |= CAM_ARG_DEBUG_XPT;
5176 ccb.cdbg.flags |= CAM_DEBUG_XPT;
5179 arglist |= CAM_ARG_DEBUG_CDB;
5180 ccb.cdbg.flags |= CAM_DEBUG_CDB;
5183 arglist |= CAM_ARG_DEBUG_PROBE;
5184 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
5195 warnx("you must specify \"off\", \"all\" or a bus,");
5196 warnx("bus:target, bus:target:lun or periph");
5201 while (isspace(*tstr) && (*tstr != '\0'))
5204 if (strncmp(tstr, "off", 3) == 0) {
5205 ccb.cdbg.flags = CAM_DEBUG_NONE;
5206 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
5207 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
5208 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
5210 rv = parse_btl(tstr, &bus, &target, &lun, &arglist);
5212 warnx("you must specify \"all\", \"off\", or a bus,");
5213 warnx("bus:target, bus:target:lun or periph to debug");
5218 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
5219 warnx("error opening transport layer device %s", XPT_DEVICE);
5220 warn("%s", XPT_DEVICE);
5224 ccb.ccb_h.func_code = XPT_DEBUG;
5225 ccb.ccb_h.path_id = bus;
5226 ccb.ccb_h.target_id = target;
5227 ccb.ccb_h.target_lun = lun;
5229 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
5230 warn("CAMIOCOMMAND ioctl failed");
5233 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
5234 CAM_FUNC_NOTAVAIL) {
5235 warnx("CAM debugging not available");
5236 warnx("you need to put options CAMDEBUG in"
5237 " your kernel config file!");
5239 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
5241 warnx("XPT_DEBUG CCB failed with status %#x",
5245 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
5247 "Debugging turned off\n");
5250 "Debugging enabled for "
5252 bus, target, (uintmax_t)lun);
5262 tagcontrol(struct cam_device *device, int argc, char **argv,
5272 ccb = cam_getccb(device);
5275 warnx("tagcontrol: error allocating ccb");
5279 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5282 numtags = strtol(optarg, NULL, 0);
5284 warnx("tag count %d is < 0", numtags);
5286 goto tagcontrol_bailout;
5297 cam_path_string(device, pathstr, sizeof(pathstr));
5300 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
5301 ccb->ccb_h.func_code = XPT_REL_SIMQ;
5302 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5303 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5304 ccb->crs.openings = numtags;
5307 if (cam_send_ccb(device, ccb) < 0) {
5308 perror("error sending XPT_REL_SIMQ CCB");
5310 goto tagcontrol_bailout;
5313 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5314 warnx("XPT_REL_SIMQ CCB failed");
5315 cam_error_print(device, ccb, CAM_ESF_ALL,
5316 CAM_EPF_ALL, stderr);
5318 goto tagcontrol_bailout;
5323 fprintf(stdout, "%stagged openings now %d\n",
5324 pathstr, ccb->crs.openings);
5327 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5329 ccb->ccb_h.func_code = XPT_GDEV_STATS;
5331 if (cam_send_ccb(device, ccb) < 0) {
5332 perror("error sending XPT_GDEV_STATS CCB");
5334 goto tagcontrol_bailout;
5337 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5338 warnx("XPT_GDEV_STATS CCB failed");
5339 cam_error_print(device, ccb, CAM_ESF_ALL,
5340 CAM_EPF_ALL, stderr);
5342 goto tagcontrol_bailout;
5345 if (arglist & CAM_ARG_VERBOSE) {
5346 fprintf(stdout, "%s", pathstr);
5347 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5348 fprintf(stdout, "%s", pathstr);
5349 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5350 fprintf(stdout, "%s", pathstr);
5351 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5352 fprintf(stdout, "%s", pathstr);
5353 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5354 fprintf(stdout, "%s", pathstr);
5355 fprintf(stdout, "held %d\n", ccb->cgds.held);
5356 fprintf(stdout, "%s", pathstr);
5357 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5358 fprintf(stdout, "%s", pathstr);
5359 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5362 fprintf(stdout, "%s", pathstr);
5363 fprintf(stdout, "device openings: ");
5365 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5366 ccb->cgds.dev_active);
5376 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5380 cam_path_string(device, pathstr, sizeof(pathstr));
5382 if (cts->transport == XPORT_SPI) {
5383 struct ccb_trans_settings_spi *spi =
5384 &cts->xport_specific.spi;
5386 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5388 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5391 if (spi->sync_offset != 0) {
5394 freq = scsi_calc_syncsrate(spi->sync_period);
5395 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5396 pathstr, freq / 1000, freq % 1000);
5400 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5401 fprintf(stdout, "%soffset: %d\n", pathstr,
5405 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5406 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5407 (0x01 << spi->bus_width) * 8);
5410 if (spi->valid & CTS_SPI_VALID_DISC) {
5411 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5412 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5413 "enabled" : "disabled");
5416 if (cts->transport == XPORT_FC) {
5417 struct ccb_trans_settings_fc *fc =
5418 &cts->xport_specific.fc;
5420 if (fc->valid & CTS_FC_VALID_WWNN)
5421 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5422 (long long) fc->wwnn);
5423 if (fc->valid & CTS_FC_VALID_WWPN)
5424 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5425 (long long) fc->wwpn);
5426 if (fc->valid & CTS_FC_VALID_PORT)
5427 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5428 if (fc->valid & CTS_FC_VALID_SPEED)
5429 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5430 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5432 if (cts->transport == XPORT_SAS) {
5433 struct ccb_trans_settings_sas *sas =
5434 &cts->xport_specific.sas;
5436 if (sas->valid & CTS_SAS_VALID_SPEED)
5437 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5438 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5440 if (cts->transport == XPORT_ATA) {
5441 struct ccb_trans_settings_pata *pata =
5442 &cts->xport_specific.ata;
5444 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5445 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5446 ata_mode2string(pata->mode));
5448 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5449 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5452 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5453 fprintf(stdout, "%sPIO transaction length: %d\n",
5454 pathstr, pata->bytecount);
5457 if (cts->transport == XPORT_SATA) {
5458 struct ccb_trans_settings_sata *sata =
5459 &cts->xport_specific.sata;
5461 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5462 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5465 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5466 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5467 ata_mode2string(sata->mode));
5469 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5470 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5473 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5474 fprintf(stdout, "%sPIO transaction length: %d\n",
5475 pathstr, sata->bytecount);
5477 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5478 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5481 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5482 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5485 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5486 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5490 if (cts->protocol == PROTO_ATA) {
5491 struct ccb_trans_settings_ata *ata=
5492 &cts->proto_specific.ata;
5494 if (ata->valid & CTS_ATA_VALID_TQ) {
5495 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5496 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5497 "enabled" : "disabled");
5500 if (cts->protocol == PROTO_SCSI) {
5501 struct ccb_trans_settings_scsi *scsi=
5502 &cts->proto_specific.scsi;
5504 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5505 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5506 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5507 "enabled" : "disabled");
5511 if (cts->protocol == PROTO_NVME) {
5512 struct ccb_trans_settings_nvme *nvmex =
5513 &cts->xport_specific.nvme;
5515 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5516 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5517 NVME_MAJOR(nvmex->spec),
5518 NVME_MINOR(nvmex->spec));
5520 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5521 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5522 nvmex->lanes, nvmex->max_lanes);
5523 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5524 nvmex->speed, nvmex->max_speed);
5531 * Get a path inquiry CCB for the specified device.
5534 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5539 ccb = cam_getccb(device);
5541 warnx("get_cpi: couldn't allocate CCB");
5544 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5545 ccb->ccb_h.func_code = XPT_PATH_INQ;
5546 if (cam_send_ccb(device, ccb) < 0) {
5547 warn("get_cpi: error sending Path Inquiry CCB");
5548 if (arglist & CAM_ARG_VERBOSE)
5549 cam_error_print(device, ccb, CAM_ESF_ALL,
5550 CAM_EPF_ALL, stderr);
5552 goto get_cpi_bailout;
5554 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5555 if (arglist & CAM_ARG_VERBOSE)
5556 cam_error_print(device, ccb, CAM_ESF_ALL,
5557 CAM_EPF_ALL, stderr);
5559 goto get_cpi_bailout;
5561 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5569 * Get a get device CCB for the specified device.
5572 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5577 ccb = cam_getccb(device);
5579 warnx("get_cgd: couldn't allocate CCB");
5582 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5583 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5584 if (cam_send_ccb(device, ccb) < 0) {
5585 warn("get_cgd: error sending Path Inquiry CCB");
5586 if (arglist & CAM_ARG_VERBOSE)
5587 cam_error_print(device, ccb, CAM_ESF_ALL,
5588 CAM_EPF_ALL, stderr);
5590 goto get_cgd_bailout;
5592 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5593 if (arglist & CAM_ARG_VERBOSE)
5594 cam_error_print(device, ccb, CAM_ESF_ALL,
5595 CAM_EPF_ALL, stderr);
5597 goto get_cgd_bailout;
5599 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5607 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5611 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5612 int timeout, int verbosemode)
5614 union ccb *ccb = NULL;
5615 struct scsi_vpd_supported_page_list sup_pages;
5619 ccb = cam_getccb(dev);
5621 warn("Unable to allocate CCB");
5626 /* cam_getccb cleans up the header, caller has to zero the payload */
5627 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5629 bzero(&sup_pages, sizeof(sup_pages));
5631 scsi_inquiry(&ccb->csio,
5632 /*retries*/ retry_count,
5634 /* tag_action */ MSG_SIMPLE_Q_TAG,
5635 /* inq_buf */ (u_int8_t *)&sup_pages,
5636 /* inq_len */ sizeof(sup_pages),
5638 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5639 /* sense_len */ SSD_FULL_SIZE,
5640 /* timeout */ timeout ? timeout : 5000);
5642 /* Disable freezing the device queue */
5643 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5645 if (retry_count != 0)
5646 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5648 if (cam_send_ccb(dev, ccb) < 0) {
5655 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5656 if (verbosemode != 0)
5657 cam_error_print(dev, ccb, CAM_ESF_ALL,
5658 CAM_EPF_ALL, stderr);
5663 for (i = 0; i < sup_pages.length; i++) {
5664 if (sup_pages.list[i] == page_id) {
5677 * devtype is filled in with the type of device.
5678 * Returns 0 for success, non-zero for failure.
5681 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5682 int verbosemode, camcontrol_devtype *devtype)
5684 struct ccb_getdev cgd;
5687 retval = get_cgd(dev, &cgd);
5691 switch (cgd.protocol) {
5697 *devtype = CC_DT_ATA;
5699 break; /*NOTREACHED*/
5701 *devtype = CC_DT_NVME;
5703 break; /*NOTREACHED*/
5705 *devtype = CC_DT_MMCSD;
5707 break; /*NOTREACHED*/
5709 *devtype = CC_DT_UNKNOWN;
5711 break; /*NOTREACHED*/
5714 if (retry_count == -1) {
5716 * For a retry count of -1, used only the cached data to avoid
5717 * I/O to the drive. Sending the identify command to the drive
5718 * can cause issues for SATL attachaed drives since identify is
5719 * not an NCQ command.
5721 if (cgd.ident_data.config != 0)
5722 *devtype = CC_DT_SATL;
5724 *devtype = CC_DT_SCSI;
5727 * Check for the ATA Information VPD page (0x89). If this is an
5728 * ATA device behind a SCSI to ATA translation layer (SATL),
5729 * this VPD page should be present.
5731 * If that VPD page isn't present, or we get an error back from
5732 * the INQUIRY command, we'll just treat it as a normal SCSI
5735 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5736 timeout, verbosemode);
5738 *devtype = CC_DT_SATL;
5740 *devtype = CC_DT_SCSI;
5749 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5750 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5751 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5752 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5753 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5754 int is48bit, camcontrol_devtype devtype)
5758 if (devtype == CC_DT_ATA) {
5759 cam_fill_ataio(&ccb->ataio,
5760 /*retries*/ retry_count,
5763 /*tag_action*/ tag_action,
5764 /*data_ptr*/ data_ptr,
5765 /*dxfer_len*/ dxfer_len,
5766 /*timeout*/ timeout);
5767 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5768 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5771 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5774 if (auxiliary != 0) {
5775 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5776 ccb->ataio.aux = auxiliary;
5779 if (ata_flags & AP_FLAG_CHK_COND)
5780 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5782 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5783 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5784 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5785 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5787 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5788 protocol |= AP_EXTEND;
5790 retval = scsi_ata_pass(&ccb->csio,
5791 /*retries*/ retry_count,
5794 /*tag_action*/ tag_action,
5795 /*protocol*/ protocol,
5796 /*ata_flags*/ ata_flags,
5797 /*features*/ features,
5798 /*sector_count*/ sector_count,
5800 /*command*/ command,
5803 /*auxiliary*/ auxiliary,
5805 /*data_ptr*/ data_ptr,
5806 /*dxfer_len*/ dxfer_len,
5807 /*cdb_storage*/ cdb_storage,
5808 /*cdb_storage_len*/ cdb_storage_len,
5809 /*minimum_cmd_size*/ 0,
5810 /*sense_len*/ sense_len,
5811 /*timeout*/ timeout);
5818 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5819 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5823 switch (ccb->ccb_h.func_code) {
5826 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5829 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5830 * or 16 byte, and need to see what
5832 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5833 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5835 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5836 if ((opcode != ATA_PASS_12)
5837 && (opcode != ATA_PASS_16)) {
5839 warnx("%s: unsupported opcode %02x", __func__, opcode);
5843 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5845 /* Note: the _ccb() variant returns 0 for an error */
5852 switch (error_code) {
5853 case SSD_DESC_CURRENT_ERROR:
5854 case SSD_DESC_DEFERRED_ERROR: {
5855 struct scsi_sense_data_desc *sense;
5856 struct scsi_sense_ata_ret_desc *desc;
5859 sense = (struct scsi_sense_data_desc *)
5860 &ccb->csio.sense_data;
5862 desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len -
5863 ccb->csio.sense_resid, SSD_DESC_ATA);
5864 if (desc_ptr == NULL) {
5865 cam_error_print(dev, ccb, CAM_ESF_ALL,
5866 CAM_EPF_ALL, stderr);
5870 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5872 *error = desc->error;
5873 *count = (desc->count_15_8 << 8) |
5875 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5876 ((uint64_t)desc->lba_39_32 << 32) |
5877 ((uint64_t)desc->lba_31_24 << 24) |
5878 (desc->lba_23_16 << 16) |
5879 (desc->lba_15_8 << 8) |
5881 *device = desc->device;
5882 *status = desc->status;
5885 * If the extend bit isn't set, the result is for a
5886 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5887 * command without the extend bit set. This means
5888 * that the device is supposed to return 28-bit
5889 * status. The count field is only 8 bits, and the
5890 * LBA field is only 8 bits.
5892 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5898 case SSD_CURRENT_ERROR:
5899 case SSD_DEFERRED_ERROR: {
5901 struct scsi_sense_data_fixed *sense;
5904 * XXX KDM need to support fixed sense data.
5906 warnx("%s: Fixed sense data not supported yet",
5910 break; /*NOTREACHED*/
5921 struct ata_res *res;
5924 * In this case, we have an ATA command, and we need to
5925 * fill in the requested values from the result register
5928 res = &ccb->ataio.res;
5929 *error = res->error;
5930 *status = res->status;
5931 *device = res->device;
5932 *count = res->sector_count;
5933 *lba = (res->lba_high << 16) |
5934 (res->lba_mid << 8) |
5936 if (res->flags & CAM_ATAIO_48BIT) {
5937 *count |= (res->sector_count_exp << 8);
5938 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5939 ((uint64_t)res->lba_mid_exp << 32) |
5940 ((uint64_t)res->lba_high_exp << 40);
5942 *lba |= (res->device & 0xf) << 24;
5955 cpi_print(struct ccb_pathinq *cpi)
5957 char adapter_str[1024];
5960 snprintf(adapter_str, sizeof(adapter_str),
5961 "%s%d:", cpi->dev_name, cpi->unit_number);
5963 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5966 for (i = 1; i < UINT8_MAX; i = i << 1) {
5969 if ((i & cpi->hba_inquiry) == 0)
5972 fprintf(stdout, "%s supports ", adapter_str);
5976 str = "MDP message";
5979 str = "32 bit wide SCSI";
5982 str = "16 bit wide SCSI";
5985 str = "SDTR message";
5988 str = "linked CDBs";
5991 str = "tag queue messages";
5994 str = "soft reset alternative";
5997 str = "SATA Port Multiplier";
6000 str = "unknown PI bit set";
6003 fprintf(stdout, "%s\n", str);
6006 for (i = 1; i < UINT32_MAX; i = i << 1) {
6009 if ((i & cpi->hba_misc) == 0)
6012 fprintf(stdout, "%s ", adapter_str);
6016 str = "can understand ata_ext requests";
6019 str = "64bit extended LUNs supported";
6022 str = "bus scans from high ID to low ID";
6025 str = "removable devices not included in scan";
6027 case PIM_NOINITIATOR:
6028 str = "initiator role not supported";
6030 case PIM_NOBUSRESET:
6031 str = "user has disabled initial BUS RESET or"
6032 " controller is in target/mixed mode";
6035 str = "do not send 6-byte commands";
6038 str = "scan bus sequentially";
6041 str = "unmapped I/O supported";
6044 str = "does its own scanning";
6047 str = "unknown PIM bit set";
6050 fprintf(stdout, "%s\n", str);
6053 for (i = 1; i < UINT16_MAX; i = i << 1) {
6056 if ((i & cpi->target_sprt) == 0)
6059 fprintf(stdout, "%s supports ", adapter_str);
6062 str = "target mode processor mode";
6065 str = "target mode phase cog. mode";
6067 case PIT_DISCONNECT:
6068 str = "disconnects in target mode";
6071 str = "terminate I/O message in target mode";
6074 str = "group 6 commands in target mode";
6077 str = "group 7 commands in target mode";
6080 str = "unknown PIT bit set";
6084 fprintf(stdout, "%s\n", str);
6086 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
6088 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
6090 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
6092 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
6093 adapter_str, cpi->hpath_id);
6094 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
6096 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
6097 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
6098 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
6099 adapter_str, cpi->hba_vendor);
6100 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
6101 adapter_str, cpi->hba_device);
6102 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
6103 adapter_str, cpi->hba_subvendor);
6104 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
6105 adapter_str, cpi->hba_subdevice);
6106 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
6107 fprintf(stdout, "%s base transfer speed: ", adapter_str);
6108 if (cpi->base_transfer_speed > 1000)
6109 fprintf(stdout, "%d.%03dMB/sec\n",
6110 cpi->base_transfer_speed / 1000,
6111 cpi->base_transfer_speed % 1000);
6113 fprintf(stdout, "%dKB/sec\n",
6114 (cpi->base_transfer_speed % 1000) * 1000);
6115 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
6116 adapter_str, cpi->maxio);
6120 get_print_cts(struct cam_device *device, int user_settings, int quiet,
6121 struct ccb_trans_settings *cts)
6127 ccb = cam_getccb(device);
6130 warnx("get_print_cts: error allocating ccb");
6134 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
6136 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
6138 if (user_settings == 0)
6139 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
6141 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
6143 if (cam_send_ccb(device, ccb) < 0) {
6144 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
6145 if (arglist & CAM_ARG_VERBOSE)
6146 cam_error_print(device, ccb, CAM_ESF_ALL,
6147 CAM_EPF_ALL, stderr);
6149 goto get_print_cts_bailout;
6152 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6153 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
6154 if (arglist & CAM_ARG_VERBOSE)
6155 cam_error_print(device, ccb, CAM_ESF_ALL,
6156 CAM_EPF_ALL, stderr);
6158 goto get_print_cts_bailout;
6162 cts_print(device, &ccb->cts);
6165 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
6167 get_print_cts_bailout:
6175 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
6176 int timeout, int argc, char **argv, char *combinedopt)
6180 int user_settings = 0;
6182 int disc_enable = -1, tag_enable = -1;
6185 double syncrate = -1;
6188 int change_settings = 0, send_tur = 0;
6189 struct ccb_pathinq cpi;
6191 ccb = cam_getccb(device);
6193 warnx("ratecontrol: error allocating ccb");
6196 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6205 if (strncasecmp(optarg, "enable", 6) == 0)
6207 else if (strncasecmp(optarg, "disable", 7) == 0)
6210 warnx("-D argument \"%s\" is unknown", optarg);
6212 goto ratecontrol_bailout;
6214 change_settings = 1;
6217 mode = ata_string2mode(optarg);
6219 warnx("unknown mode '%s'", optarg);
6221 goto ratecontrol_bailout;
6223 change_settings = 1;
6226 offset = strtol(optarg, NULL, 0);
6228 warnx("offset value %d is < 0", offset);
6230 goto ratecontrol_bailout;
6232 change_settings = 1;
6238 syncrate = atof(optarg);
6240 warnx("sync rate %f is < 0", syncrate);
6242 goto ratecontrol_bailout;
6244 change_settings = 1;
6247 if (strncasecmp(optarg, "enable", 6) == 0)
6249 else if (strncasecmp(optarg, "disable", 7) == 0)
6252 warnx("-T argument \"%s\" is unknown", optarg);
6254 goto ratecontrol_bailout;
6256 change_settings = 1;
6262 bus_width = strtol(optarg, NULL, 0);
6263 if (bus_width < 0) {
6264 warnx("bus width %d is < 0", bus_width);
6266 goto ratecontrol_bailout;
6268 change_settings = 1;
6274 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
6276 * Grab path inquiry information, so we can determine whether
6277 * or not the initiator is capable of the things that the user
6280 ccb->ccb_h.func_code = XPT_PATH_INQ;
6281 if (cam_send_ccb(device, ccb) < 0) {
6282 perror("error sending XPT_PATH_INQ CCB");
6283 if (arglist & CAM_ARG_VERBOSE) {
6284 cam_error_print(device, ccb, CAM_ESF_ALL,
6285 CAM_EPF_ALL, stderr);
6288 goto ratecontrol_bailout;
6290 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6291 warnx("XPT_PATH_INQ CCB failed");
6292 if (arglist & CAM_ARG_VERBOSE) {
6293 cam_error_print(device, ccb, CAM_ESF_ALL,
6294 CAM_EPF_ALL, stderr);
6297 goto ratecontrol_bailout;
6299 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
6300 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
6302 fprintf(stdout, "%s parameters:\n",
6303 user_settings ? "User" : "Current");
6305 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
6307 goto ratecontrol_bailout;
6309 if (arglist & CAM_ARG_VERBOSE)
6312 if (change_settings) {
6313 int didsettings = 0;
6314 struct ccb_trans_settings_spi *spi = NULL;
6315 struct ccb_trans_settings_pata *pata = NULL;
6316 struct ccb_trans_settings_sata *sata = NULL;
6317 struct ccb_trans_settings_ata *ata = NULL;
6318 struct ccb_trans_settings_scsi *scsi = NULL;
6320 if (ccb->cts.transport == XPORT_SPI)
6321 spi = &ccb->cts.xport_specific.spi;
6322 if (ccb->cts.transport == XPORT_ATA)
6323 pata = &ccb->cts.xport_specific.ata;
6324 if (ccb->cts.transport == XPORT_SATA)
6325 sata = &ccb->cts.xport_specific.sata;
6326 if (ccb->cts.protocol == PROTO_ATA)
6327 ata = &ccb->cts.proto_specific.ata;
6328 if (ccb->cts.protocol == PROTO_SCSI)
6329 scsi = &ccb->cts.proto_specific.scsi;
6330 ccb->cts.xport_specific.valid = 0;
6331 ccb->cts.proto_specific.valid = 0;
6332 if (spi && disc_enable != -1) {
6333 spi->valid |= CTS_SPI_VALID_DISC;
6334 if (disc_enable == 0)
6335 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6337 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6340 if (tag_enable != -1) {
6341 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6342 warnx("HBA does not support tagged queueing, "
6343 "so you cannot modify tag settings");
6345 goto ratecontrol_bailout;
6348 ata->valid |= CTS_SCSI_VALID_TQ;
6349 if (tag_enable == 0)
6350 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6352 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6355 scsi->valid |= CTS_SCSI_VALID_TQ;
6356 if (tag_enable == 0)
6357 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6359 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6363 if (spi && offset != -1) {
6364 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6365 warnx("HBA is not capable of changing offset");
6367 goto ratecontrol_bailout;
6369 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6370 spi->sync_offset = offset;
6373 if (spi && syncrate != -1) {
6374 int prelim_sync_period;
6376 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6377 warnx("HBA is not capable of changing "
6380 goto ratecontrol_bailout;
6382 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6384 * The sync rate the user gives us is in MHz.
6385 * We need to translate it into KHz for this
6390 * Next, we calculate a "preliminary" sync period
6391 * in tenths of a nanosecond.
6394 prelim_sync_period = 0;
6396 prelim_sync_period = 10000000 / syncrate;
6398 scsi_calc_syncparam(prelim_sync_period);
6401 if (sata && syncrate != -1) {
6402 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6403 warnx("HBA is not capable of changing "
6406 goto ratecontrol_bailout;
6408 if (!user_settings) {
6409 warnx("You can modify only user rate "
6410 "settings for SATA");
6412 goto ratecontrol_bailout;
6414 sata->revision = ata_speed2revision(syncrate * 100);
6415 if (sata->revision < 0) {
6416 warnx("Invalid rate %f", syncrate);
6418 goto ratecontrol_bailout;
6420 sata->valid |= CTS_SATA_VALID_REVISION;
6423 if ((pata || sata) && mode != -1) {
6424 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6425 warnx("HBA is not capable of changing "
6428 goto ratecontrol_bailout;
6430 if (!user_settings) {
6431 warnx("You can modify only user mode "
6432 "settings for ATA/SATA");
6434 goto ratecontrol_bailout;
6438 pata->valid |= CTS_ATA_VALID_MODE;
6441 sata->valid |= CTS_SATA_VALID_MODE;
6446 * The bus_width argument goes like this:
6450 * Therefore, if you shift the number of bits given on the
6451 * command line right by 4, you should get the correct
6454 if (spi && bus_width != -1) {
6456 * We might as well validate things here with a
6457 * decipherable error message, rather than what
6458 * will probably be an indecipherable error message
6459 * by the time it gets back to us.
6461 if ((bus_width == 16)
6462 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6463 warnx("HBA does not support 16 bit bus width");
6465 goto ratecontrol_bailout;
6466 } else if ((bus_width == 32)
6467 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6468 warnx("HBA does not support 32 bit bus width");
6470 goto ratecontrol_bailout;
6471 } else if ((bus_width != 8)
6472 && (bus_width != 16)
6473 && (bus_width != 32)) {
6474 warnx("Invalid bus width %d", bus_width);
6476 goto ratecontrol_bailout;
6478 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6479 spi->bus_width = bus_width >> 4;
6482 if (didsettings == 0) {
6483 goto ratecontrol_bailout;
6485 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6486 if (cam_send_ccb(device, ccb) < 0) {
6487 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
6488 if (arglist & CAM_ARG_VERBOSE) {
6489 cam_error_print(device, ccb, CAM_ESF_ALL,
6490 CAM_EPF_ALL, stderr);
6493 goto ratecontrol_bailout;
6495 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6496 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6497 if (arglist & CAM_ARG_VERBOSE) {
6498 cam_error_print(device, ccb, CAM_ESF_ALL,
6499 CAM_EPF_ALL, stderr);
6502 goto ratecontrol_bailout;
6506 retval = testunitready(device, task_attr, retry_count, timeout,
6507 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6509 * If the TUR didn't succeed, just bail.
6513 fprintf(stderr, "Test Unit Ready failed\n");
6514 goto ratecontrol_bailout;
6517 if ((change_settings || send_tur) && !quiet &&
6518 (ccb->cts.transport == XPORT_ATA ||
6519 ccb->cts.transport == XPORT_SATA || send_tur)) {
6520 fprintf(stdout, "New parameters:\n");
6521 retval = get_print_cts(device, user_settings, 0, NULL);
6524 ratecontrol_bailout:
6530 scsiformat(struct cam_device *device, int argc, char **argv,
6531 char *combinedopt, int task_attr, int retry_count, int timeout)
6535 int ycount = 0, quiet = 0;
6536 int error = 0, retval = 0;
6537 int use_timeout = 10800 * 1000;
6539 struct format_defect_list_header fh;
6540 u_int8_t *data_ptr = NULL;
6541 u_int32_t dxfer_len = 0;
6543 int num_warnings = 0;
6546 ccb = cam_getccb(device);
6549 warnx("scsiformat: error allocating ccb");
6553 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6555 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6576 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6577 "following device:\n");
6579 error = scsidoinquiry(device, argc, argv, combinedopt,
6580 task_attr, retry_count, timeout);
6583 warnx("scsiformat: error sending inquiry");
6584 goto scsiformat_bailout;
6589 if (!get_confirmation()) {
6591 goto scsiformat_bailout;
6596 use_timeout = timeout;
6599 fprintf(stdout, "Current format timeout is %d seconds\n",
6600 use_timeout / 1000);
6604 * If the user hasn't disabled questions and didn't specify a
6605 * timeout on the command line, ask them if they want the current
6609 && (timeout == 0)) {
6611 int new_timeout = 0;
6613 fprintf(stdout, "Enter new timeout in seconds or press\n"
6614 "return to keep the current timeout [%d] ",
6615 use_timeout / 1000);
6617 if (fgets(str, sizeof(str), stdin) != NULL) {
6619 new_timeout = atoi(str);
6622 if (new_timeout != 0) {
6623 use_timeout = new_timeout * 1000;
6624 fprintf(stdout, "Using new timeout value %d\n",
6625 use_timeout / 1000);
6630 * Keep this outside the if block below to silence any unused
6631 * variable warnings.
6633 bzero(&fh, sizeof(fh));
6636 * If we're in immediate mode, we've got to include the format
6639 if (immediate != 0) {
6640 fh.byte2 = FU_DLH_IMMED;
6641 data_ptr = (u_int8_t *)&fh;
6642 dxfer_len = sizeof(fh);
6643 byte2 = FU_FMT_DATA;
6644 } else if (quiet == 0) {
6645 fprintf(stdout, "Formatting...");
6649 scsi_format_unit(&ccb->csio,
6650 /* retries */ retry_count,
6652 /* tag_action */ task_attr,
6655 /* data_ptr */ data_ptr,
6656 /* dxfer_len */ dxfer_len,
6657 /* sense_len */ SSD_FULL_SIZE,
6658 /* timeout */ use_timeout);
6660 /* Disable freezing the device queue */
6661 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6663 if (arglist & CAM_ARG_ERR_RECOVER)
6664 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6666 if (((retval = cam_send_ccb(device, ccb)) < 0)
6667 || ((immediate == 0)
6668 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6669 const char errstr[] = "error sending format command";
6676 if (arglist & CAM_ARG_VERBOSE) {
6677 cam_error_print(device, ccb, CAM_ESF_ALL,
6678 CAM_EPF_ALL, stderr);
6681 goto scsiformat_bailout;
6685 * If we ran in non-immediate mode, we already checked for errors
6686 * above and printed out any necessary information. If we're in
6687 * immediate mode, we need to loop through and get status
6688 * information periodically.
6690 if (immediate == 0) {
6692 fprintf(stdout, "Format Complete\n");
6694 goto scsiformat_bailout;
6701 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6704 * There's really no need to do error recovery or
6705 * retries here, since we're just going to sit in a
6706 * loop and wait for the device to finish formatting.
6708 scsi_test_unit_ready(&ccb->csio,
6711 /* tag_action */ task_attr,
6712 /* sense_len */ SSD_FULL_SIZE,
6713 /* timeout */ 5000);
6715 /* Disable freezing the device queue */
6716 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6718 retval = cam_send_ccb(device, ccb);
6721 * If we get an error from the ioctl, bail out. SCSI
6722 * errors are expected.
6725 warn("error sending CAMIOCOMMAND ioctl");
6726 if (arglist & CAM_ARG_VERBOSE) {
6727 cam_error_print(device, ccb, CAM_ESF_ALL,
6728 CAM_EPF_ALL, stderr);
6731 goto scsiformat_bailout;
6734 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6736 if ((status != CAM_REQ_CMP)
6737 && (status == CAM_SCSI_STATUS_ERROR)
6738 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6739 struct scsi_sense_data *sense;
6740 int error_code, sense_key, asc, ascq;
6742 sense = &ccb->csio.sense_data;
6743 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6744 ccb->csio.sense_resid, &error_code, &sense_key,
6745 &asc, &ascq, /*show_errors*/ 1);
6748 * According to the SCSI-2 and SCSI-3 specs, a
6749 * drive that is in the middle of a format should
6750 * return NOT READY with an ASC of "logical unit
6751 * not ready, format in progress". The sense key
6752 * specific bytes will then be a progress indicator.
6754 if ((sense_key == SSD_KEY_NOT_READY)
6755 && (asc == 0x04) && (ascq == 0x04)) {
6758 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6759 ccb->csio.sense_resid, sks) == 0)
6762 u_int64_t percentage;
6764 val = scsi_2btoul(&sks[1]);
6765 percentage = 10000ull * val;
6768 "\rFormatting: %ju.%02u %% "
6770 (uintmax_t)(percentage /
6772 (unsigned)((percentage /
6776 } else if ((quiet == 0)
6777 && (++num_warnings <= 1)) {
6778 warnx("Unexpected SCSI Sense Key "
6779 "Specific value returned "
6781 scsi_sense_print(device, &ccb->csio,
6783 warnx("Unable to print status "
6784 "information, but format will "
6786 warnx("will exit when format is "
6791 warnx("Unexpected SCSI error during format");
6792 cam_error_print(device, ccb, CAM_ESF_ALL,
6793 CAM_EPF_ALL, stderr);
6795 goto scsiformat_bailout;
6798 } else if (status != CAM_REQ_CMP) {
6799 warnx("Unexpected CAM status %#x", status);
6800 if (arglist & CAM_ARG_VERBOSE)
6801 cam_error_print(device, ccb, CAM_ESF_ALL,
6802 CAM_EPF_ALL, stderr);
6804 goto scsiformat_bailout;
6807 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6810 fprintf(stdout, "\nFormat Complete\n");
6820 sanitize_wait_ata(struct cam_device *device, union ccb *ccb, int quiet)
6822 struct ata_res *res;
6828 retval = ata_do_cmd(device,
6831 /*flags*/CAM_DIR_NONE,
6832 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
6833 /*ata_flags*/AP_FLAG_CHK_COND,
6834 /*tag_action*/MSG_SIMPLE_Q_TAG,
6835 /*command*/ATA_SANITIZE,
6836 /*features*/0x00, /* SANITIZE STATUS EXT */
6844 warn("error sending CAMIOCOMMAND ioctl");
6845 if (arglist & CAM_ARG_VERBOSE) {
6846 cam_error_print(device, ccb, CAM_ESF_ALL,
6847 CAM_EPF_ALL, stderr);
6852 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6853 if (status == CAM_REQ_CMP) {
6854 res = &ccb->ataio.res;
6855 if (res->sector_count_exp & 0x40) {
6857 val = (res->lba_mid << 8) + res->lba_low;
6860 "Sanitizing: %u.%02u%% (%d/%d)\r",
6861 (perc / (0x10000 * 100)),
6862 ((perc / 0x10000) % 100),
6867 } else if ((res->sector_count_exp & 0x80) == 0) {
6868 warnx("Sanitize complete with an error. ");
6873 } else if (status != CAM_REQ_CMP && status != CAM_REQUEUE_REQ) {
6874 warnx("Unexpected CAM status %#x", status);
6875 if (arglist & CAM_ARG_VERBOSE)
6876 cam_error_print(device, ccb, CAM_ESF_ALL,
6877 CAM_EPF_ALL, stderr);
6885 sanitize_wait_scsi(struct cam_device *device, union ccb *ccb, int task_attr, int quiet)
6887 int warnings = 0, retval;
6892 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6895 * There's really no need to do error recovery or
6896 * retries here, since we're just going to sit in a
6897 * loop and wait for the device to finish sanitizing.
6899 scsi_test_unit_ready(&ccb->csio,
6902 /* tag_action */ task_attr,
6903 /* sense_len */ SSD_FULL_SIZE,
6904 /* timeout */ 5000);
6906 /* Disable freezing the device queue */
6907 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6909 retval = cam_send_ccb(device, ccb);
6912 * If we get an error from the ioctl, bail out. SCSI
6913 * errors are expected.
6916 warn("error sending CAMIOCOMMAND ioctl");
6917 if (arglist & CAM_ARG_VERBOSE) {
6918 cam_error_print(device, ccb, CAM_ESF_ALL,
6919 CAM_EPF_ALL, stderr);
6924 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6925 if ((status == CAM_SCSI_STATUS_ERROR) &&
6926 ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6927 struct scsi_sense_data *sense;
6928 int error_code, sense_key, asc, ascq;
6930 sense = &ccb->csio.sense_data;
6931 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6932 ccb->csio.sense_resid, &error_code, &sense_key,
6933 &asc, &ascq, /*show_errors*/ 1);
6936 * According to the SCSI-3 spec, a drive that is in the
6937 * middle of a sanitize should return NOT READY with an
6938 * ASC of "logical unit not ready, sanitize in
6939 * progress". The sense key specific bytes will then
6940 * be a progress indicator.
6942 if ((sense_key == SSD_KEY_NOT_READY)
6943 && (asc == 0x04) && (ascq == 0x1b)) {
6946 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6947 ccb->csio.sense_resid, sks) == 0)
6949 val = scsi_2btoul(&sks[1]);
6952 "Sanitizing: %u.%02u%% (%d/%d)\r",
6953 (perc / (0x10000 * 100)),
6954 ((perc / 0x10000) % 100),
6957 } else if ((quiet == 0) && (++warnings <= 1)) {
6958 warnx("Unexpected SCSI Sense Key "
6959 "Specific value returned "
6960 "during sanitize:");
6961 scsi_sense_print(device, &ccb->csio,
6963 warnx("Unable to print status "
6964 "information, but sanitze will "
6966 warnx("will exit when sanitize is "
6971 warnx("Unexpected SCSI error during sanitize");
6972 cam_error_print(device, ccb, CAM_ESF_ALL,
6973 CAM_EPF_ALL, stderr);
6977 } else if (status != CAM_REQ_CMP && status != CAM_REQUEUE_REQ) {
6978 warnx("Unexpected CAM status %#x", status);
6979 if (arglist & CAM_ARG_VERBOSE)
6980 cam_error_print(device, ccb, CAM_ESF_ALL,
6981 CAM_EPF_ALL, stderr);
6984 } while ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6989 sanitize(struct cam_device *device, int argc, char **argv,
6990 char *combinedopt, int task_attr, int retry_count, int timeout)
6993 u_int8_t action = 0;
6995 int ycount = 0, quiet = 0;
7003 const char *pattern = NULL;
7004 u_int8_t *data_ptr = NULL;
7005 u_int32_t dxfer_len = 0;
7007 uint16_t feature, count;
7010 camcontrol_devtype dt;
7013 * Get the device type, request no I/O be done to do this.
7015 error = get_device_type(device, -1, 0, 0, &dt);
7016 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
7017 warnx("sanitize: can't get device type");
7021 ccb = cam_getccb(device);
7024 warnx("sanitize: error allocating ccb");
7028 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7030 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7033 if (strcasecmp(optarg, "overwrite") == 0)
7034 action = SSZ_SERVICE_ACTION_OVERWRITE;
7035 else if (strcasecmp(optarg, "block") == 0)
7036 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
7037 else if (strcasecmp(optarg, "crypto") == 0)
7038 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
7039 else if (strcasecmp(optarg, "exitfailure") == 0)
7040 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
7042 warnx("invalid service operation \"%s\"",
7045 goto sanitize_bailout;
7049 passes = strtol(optarg, NULL, 0);
7050 if (passes < 1 || passes > 31) {
7051 warnx("invalid passes value %d", passes);
7053 goto sanitize_bailout;
7072 /* ATA supports only immediate commands. */
7073 if (dt == CC_DT_SCSI)
7086 warnx("an action is required");
7088 goto sanitize_bailout;
7089 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
7090 struct scsi_sanitize_parameter_list *pl;
7094 if (pattern == NULL) {
7095 warnx("overwrite action requires -P argument");
7097 goto sanitize_bailout;
7099 fd = open(pattern, O_RDONLY);
7101 warn("cannot open pattern file %s", pattern);
7103 goto sanitize_bailout;
7105 if (fstat(fd, &sb) < 0) {
7106 warn("cannot stat pattern file %s", pattern);
7108 goto sanitize_bailout;
7111 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
7112 warnx("pattern file size exceeds maximum value %d",
7113 SSZPL_MAX_PATTERN_LENGTH);
7115 goto sanitize_bailout;
7117 dxfer_len = sizeof(*pl) + sz;
7118 data_ptr = calloc(1, dxfer_len);
7119 if (data_ptr == NULL) {
7120 warnx("cannot allocate parameter list buffer");
7122 goto sanitize_bailout;
7125 amt = read(fd, data_ptr + sizeof(*pl), sz);
7127 warn("cannot read pattern file");
7129 goto sanitize_bailout;
7130 } else if (amt != sz) {
7131 warnx("short pattern file read");
7133 goto sanitize_bailout;
7136 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
7142 pl->byte1 |= SSZPL_INVERT;
7143 scsi_ulto2b(sz, pl->length);
7149 else if (invert != 0)
7151 else if (pattern != NULL)
7156 warnx("%s argument only valid with overwrite "
7159 goto sanitize_bailout;
7164 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
7165 "following device:\n");
7167 if (dt == CC_DT_SCSI) {
7168 error = scsidoinquiry(device, argc, argv, combinedopt,
7169 task_attr, retry_count, timeout);
7170 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7171 struct ata_params *ident_buf;
7172 error = ata_do_identify(device, retry_count, timeout,
7175 printf("%s%d: ", device->device_name,
7176 device->dev_unit_num);
7177 ata_print_ident(ident_buf);
7184 warnx("sanitize: error sending inquiry");
7185 goto sanitize_bailout;
7190 if (!get_confirmation()) {
7192 goto sanitize_bailout;
7197 use_timeout = timeout;
7199 use_timeout = (immediate ? 10 : 10800) * 1000;
7201 if (immediate == 0 && quiet == 0) {
7202 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
7203 use_timeout / 1000);
7207 * If the user hasn't disabled questions and didn't specify a
7208 * timeout on the command line, ask them if they want the current
7211 if (immediate == 0 && ycount == 0 && timeout == 0) {
7213 int new_timeout = 0;
7215 fprintf(stdout, "Enter new timeout in seconds or press\n"
7216 "return to keep the current timeout [%d] ",
7217 use_timeout / 1000);
7219 if (fgets(str, sizeof(str), stdin) != NULL) {
7221 new_timeout = atoi(str);
7224 if (new_timeout != 0) {
7225 use_timeout = new_timeout * 1000;
7226 fprintf(stdout, "Using new timeout value %d\n",
7227 use_timeout / 1000);
7231 if (dt == CC_DT_SCSI) {
7234 byte2 |= SSZ_UNRESTRICTED_EXIT;
7237 scsi_sanitize(&ccb->csio,
7238 /* retries */ retry_count,
7240 /* tag_action */ task_attr,
7243 /* data_ptr */ data_ptr,
7244 /* dxfer_len */ dxfer_len,
7245 /* sense_len */ SSD_FULL_SIZE,
7246 /* timeout */ use_timeout);
7248 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7249 if (arglist & CAM_ARG_ERR_RECOVER)
7250 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7251 if (cam_send_ccb(device, ccb) < 0) {
7252 warn("error sending sanitize command");
7254 goto sanitize_bailout;
7256 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7257 if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
7258 feature = 0x14; /* OVERWRITE EXT */
7259 lba = 0x4F5700000000 | scsi_4btoul(data_ptr + 4);
7260 count = (passes == 0) ? 1 : (passes >= 16) ? 0 : passes;
7262 count |= 0x80; /* INVERT PATTERN */
7264 count |= 0x10; /* FAILURE MODE */
7265 } else if (action == SSZ_SERVICE_ACTION_BLOCK_ERASE) {
7266 feature = 0x12; /* BLOCK ERASE EXT */
7267 lba = 0x0000426B4572;
7270 count |= 0x10; /* FAILURE MODE */
7271 } else if (action == SSZ_SERVICE_ACTION_CRYPTO_ERASE) {
7272 feature = 0x11; /* CRYPTO SCRAMBLE EXT */
7273 lba = 0x000043727970;
7276 count |= 0x10; /* FAILURE MODE */
7277 } else if (action == SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE) {
7278 feature = 0x00; /* SANITIZE STATUS EXT */
7280 count = 1; /* CLEAR SANITIZE OPERATION FAILED */
7283 goto sanitize_bailout;
7286 error = ata_do_cmd(device,
7289 /*flags*/CAM_DIR_NONE,
7290 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
7291 /*ata_flags*/AP_FLAG_CHK_COND,
7292 /*tag_action*/MSG_SIMPLE_Q_TAG,
7293 /*command*/ATA_SANITIZE,
7294 /*features*/feature,
7296 /*sector_count*/count,
7299 /*timeout*/ use_timeout,
7303 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7304 struct scsi_sense_data *sense;
7305 int error_code, sense_key, asc, ascq;
7307 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
7308 CAM_SCSI_STATUS_ERROR) {
7309 sense = &ccb->csio.sense_data;
7310 scsi_extract_sense_len(sense, ccb->csio.sense_len -
7311 ccb->csio.sense_resid, &error_code, &sense_key,
7312 &asc, &ascq, /*show_errors*/ 1);
7314 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
7315 asc == 0x20 && ascq == 0x00)
7316 warnx("sanitize is not supported by "
7319 warnx("error sanitizing this device");
7321 warnx("error sanitizing this device");
7323 if (arglist & CAM_ARG_VERBOSE) {
7324 cam_error_print(device, ccb, CAM_ESF_ALL,
7325 CAM_EPF_ALL, stderr);
7328 goto sanitize_bailout;
7332 * If we ran in non-immediate mode, we already checked for errors
7333 * above and printed out any necessary information. If we're in
7334 * immediate mode, we need to loop through and get status
7335 * information periodically.
7337 if (immediate == 0) {
7339 fprintf(stdout, "Sanitize Complete\n");
7341 goto sanitize_bailout;
7345 if (dt == CC_DT_SCSI) {
7346 error = sanitize_wait_scsi(device, ccb, task_attr, quiet);
7347 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7348 error = sanitize_wait_ata(device, ccb, quiet);
7351 if (error == 0 && quiet == 0)
7352 fprintf(stdout, "Sanitize Complete \n");
7357 if (data_ptr != NULL)
7365 scsireportluns(struct cam_device *device, int argc, char **argv,
7366 char *combinedopt, int task_attr, int retry_count, int timeout)
7369 int c, countonly, lunsonly;
7370 struct scsi_report_luns_data *lundata;
7372 uint8_t report_type;
7373 uint32_t list_len, i, j;
7378 report_type = RPL_REPORT_DEFAULT;
7379 ccb = cam_getccb(device);
7382 warnx("%s: error allocating ccb", __func__);
7386 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7391 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7400 if (strcasecmp(optarg, "default") == 0)
7401 report_type = RPL_REPORT_DEFAULT;
7402 else if (strcasecmp(optarg, "wellknown") == 0)
7403 report_type = RPL_REPORT_WELLKNOWN;
7404 else if (strcasecmp(optarg, "all") == 0)
7405 report_type = RPL_REPORT_ALL;
7407 warnx("%s: invalid report type \"%s\"",
7418 if ((countonly != 0)
7419 && (lunsonly != 0)) {
7420 warnx("%s: you can only specify one of -c or -l", __func__);
7425 * According to SPC-4, the allocation length must be at least 16
7426 * bytes -- enough for the header and one LUN.
7428 alloc_len = sizeof(*lundata) + 8;
7432 lundata = malloc(alloc_len);
7434 if (lundata == NULL) {
7435 warn("%s: error mallocing %d bytes", __func__, alloc_len);
7440 scsi_report_luns(&ccb->csio,
7441 /*retries*/ retry_count,
7443 /*tag_action*/ task_attr,
7444 /*select_report*/ report_type,
7445 /*rpl_buf*/ lundata,
7446 /*alloc_len*/ alloc_len,
7447 /*sense_len*/ SSD_FULL_SIZE,
7448 /*timeout*/ timeout ? timeout : 5000);
7450 /* Disable freezing the device queue */
7451 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7453 if (arglist & CAM_ARG_ERR_RECOVER)
7454 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7456 if (cam_send_ccb(device, ccb) < 0) {
7457 warn("error sending REPORT LUNS command");
7459 if (arglist & CAM_ARG_VERBOSE)
7460 cam_error_print(device, ccb, CAM_ESF_ALL,
7461 CAM_EPF_ALL, stderr);
7467 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7468 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7474 list_len = scsi_4btoul(lundata->length);
7477 * If we need to list the LUNs, and our allocation
7478 * length was too short, reallocate and retry.
7480 if ((countonly == 0)
7481 && (list_len > (alloc_len - sizeof(*lundata)))) {
7482 alloc_len = list_len + sizeof(*lundata);
7488 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7489 ((list_len / 8) > 1) ? "s" : "");
7494 for (i = 0; i < (list_len / 8); i++) {
7498 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7500 fprintf(stdout, ",");
7501 switch (lundata->luns[i].lundata[j] &
7502 RPL_LUNDATA_ATYP_MASK) {
7503 case RPL_LUNDATA_ATYP_PERIPH:
7504 if ((lundata->luns[i].lundata[j] &
7505 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7506 fprintf(stdout, "%d:",
7507 lundata->luns[i].lundata[j] &
7508 RPL_LUNDATA_PERIPH_BUS_MASK);
7510 && ((lundata->luns[i].lundata[j+2] &
7511 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7514 fprintf(stdout, "%d",
7515 lundata->luns[i].lundata[j+1]);
7517 case RPL_LUNDATA_ATYP_FLAT: {
7519 tmplun[0] = lundata->luns[i].lundata[j] &
7520 RPL_LUNDATA_FLAT_LUN_MASK;
7521 tmplun[1] = lundata->luns[i].lundata[j+1];
7523 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7527 case RPL_LUNDATA_ATYP_LUN:
7528 fprintf(stdout, "%d:%d:%d",
7529 (lundata->luns[i].lundata[j+1] &
7530 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7531 lundata->luns[i].lundata[j] &
7532 RPL_LUNDATA_LUN_TARG_MASK,
7533 lundata->luns[i].lundata[j+1] &
7534 RPL_LUNDATA_LUN_LUN_MASK);
7536 case RPL_LUNDATA_ATYP_EXTLUN: {
7537 int field_len_code, eam_code;
7539 eam_code = lundata->luns[i].lundata[j] &
7540 RPL_LUNDATA_EXT_EAM_MASK;
7541 field_len_code = (lundata->luns[i].lundata[j] &
7542 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7544 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7545 && (field_len_code == 0x00)) {
7546 fprintf(stdout, "%d",
7547 lundata->luns[i].lundata[j+1]);
7548 } else if ((eam_code ==
7549 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7550 && (field_len_code == 0x03)) {
7554 * This format takes up all 8 bytes.
7555 * If we aren't starting at offset 0,
7559 fprintf(stdout, "Invalid "
7562 "specified format", j);
7566 bzero(tmp_lun, sizeof(tmp_lun));
7567 bcopy(&lundata->luns[i].lundata[j+1],
7568 &tmp_lun[1], sizeof(tmp_lun) - 1);
7569 fprintf(stdout, "%#jx",
7570 (intmax_t)scsi_8btou64(tmp_lun));
7573 fprintf(stderr, "Unknown Extended LUN"
7574 "Address method %#x, length "
7575 "code %#x", eam_code,
7582 fprintf(stderr, "Unknown LUN address method "
7583 "%#x\n", lundata->luns[i].lundata[0] &
7584 RPL_LUNDATA_ATYP_MASK);
7588 * For the flat addressing method, there are no
7589 * other levels after it.
7594 fprintf(stdout, "\n");
7607 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7608 char *combinedopt, int task_attr, int retry_count, int timeout)
7611 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7612 struct scsi_read_capacity_data rcap;
7613 struct scsi_read_capacity_data_long rcaplong;
7628 ccb = cam_getccb(device);
7631 warnx("%s: error allocating ccb", __func__);
7635 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7637 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7667 if ((blocksizeonly != 0)
7668 && (numblocks != 0)) {
7669 warnx("%s: you can only specify one of -b or -N", __func__);
7674 if ((blocksizeonly != 0)
7675 && (sizeonly != 0)) {
7676 warnx("%s: you can only specify one of -b or -s", __func__);
7683 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7689 && (blocksizeonly != 0)) {
7690 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7698 scsi_read_capacity(&ccb->csio,
7699 /*retries*/ retry_count,
7701 /*tag_action*/ task_attr,
7704 /*timeout*/ timeout ? timeout : 5000);
7706 /* Disable freezing the device queue */
7707 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7709 if (arglist & CAM_ARG_ERR_RECOVER)
7710 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7712 if (cam_send_ccb(device, ccb) < 0) {
7713 warn("error sending READ CAPACITY command");
7715 if (arglist & CAM_ARG_VERBOSE)
7716 cam_error_print(device, ccb, CAM_ESF_ALL,
7717 CAM_EPF_ALL, stderr);
7723 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7724 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7729 maxsector = scsi_4btoul(rcap.addr);
7730 block_len = scsi_4btoul(rcap.length);
7733 * A last block of 2^32-1 means that the true capacity is over 2TB,
7734 * and we need to issue the long READ CAPACITY to get the real
7735 * capacity. Otherwise, we're all set.
7737 if (maxsector != 0xffffffff)
7741 scsi_read_capacity_16(&ccb->csio,
7742 /*retries*/ retry_count,
7744 /*tag_action*/ task_attr,
7748 /*rcap_buf*/ (uint8_t *)&rcaplong,
7749 /*rcap_buf_len*/ sizeof(rcaplong),
7750 /*sense_len*/ SSD_FULL_SIZE,
7751 /*timeout*/ timeout ? timeout : 5000);
7753 /* Disable freezing the device queue */
7754 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7756 if (arglist & CAM_ARG_ERR_RECOVER)
7757 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7759 if (cam_send_ccb(device, ccb) < 0) {
7760 warn("error sending READ CAPACITY (16) command");
7762 if (arglist & CAM_ARG_VERBOSE)
7763 cam_error_print(device, ccb, CAM_ESF_ALL,
7764 CAM_EPF_ALL, stderr);
7770 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7771 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7776 maxsector = scsi_8btou64(rcaplong.addr);
7777 block_len = scsi_4btoul(rcaplong.length);
7780 if (blocksizeonly == 0) {
7782 * Humanize implies !quiet, and also implies numblocks.
7784 if (humanize != 0) {
7789 tmpbytes = (maxsector + 1) * block_len;
7790 ret = humanize_number(tmpstr, sizeof(tmpstr),
7791 tmpbytes, "", HN_AUTOSCALE,
7794 HN_DIVISOR_1000 : 0));
7796 warnx("%s: humanize_number failed!", __func__);
7800 fprintf(stdout, "Device Size: %s%s", tmpstr,
7801 (sizeonly == 0) ? ", " : "\n");
7802 } else if (numblocks != 0) {
7803 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7804 "Blocks: " : "", (uintmax_t)maxsector + 1,
7805 (sizeonly == 0) ? ", " : "\n");
7807 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7808 "Last Block: " : "", (uintmax_t)maxsector,
7809 (sizeonly == 0) ? ", " : "\n");
7813 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7814 "Block Length: " : "", block_len, (quiet == 0) ?
7823 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7824 int retry_count, int timeout)
7828 uint8_t *smp_request = NULL, *smp_response = NULL;
7829 int request_size = 0, response_size = 0;
7830 int fd_request = 0, fd_response = 0;
7831 char *datastr = NULL;
7832 struct get_hook hook;
7837 * Note that at the moment we don't support sending SMP CCBs to
7838 * devices that aren't probed by CAM.
7840 ccb = cam_getccb(device);
7842 warnx("%s: error allocating CCB", __func__);
7846 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7848 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7851 arglist |= CAM_ARG_CMD_IN;
7852 response_size = strtol(optarg, NULL, 0);
7853 if (response_size <= 0) {
7854 warnx("invalid number of response bytes %d",
7857 goto smpcmd_bailout;
7859 hook.argc = argc - optind;
7860 hook.argv = argv + optind;
7863 datastr = cget(&hook, NULL);
7865 * If the user supplied "-" instead of a format, he
7866 * wants the data to be written to stdout.
7868 if ((datastr != NULL)
7869 && (datastr[0] == '-'))
7872 smp_response = (u_int8_t *)malloc(response_size);
7873 if (smp_response == NULL) {
7874 warn("can't malloc memory for SMP response");
7876 goto smpcmd_bailout;
7880 arglist |= CAM_ARG_CMD_OUT;
7881 request_size = strtol(optarg, NULL, 0);
7882 if (request_size <= 0) {
7883 warnx("invalid number of request bytes %d",
7886 goto smpcmd_bailout;
7888 hook.argc = argc - optind;
7889 hook.argv = argv + optind;
7891 datastr = cget(&hook, NULL);
7892 smp_request = (u_int8_t *)malloc(request_size);
7893 if (smp_request == NULL) {
7894 warn("can't malloc memory for SMP request");
7896 goto smpcmd_bailout;
7898 bzero(smp_request, request_size);
7900 * If the user supplied "-" instead of a format, he
7901 * wants the data to be read from stdin.
7903 if ((datastr != NULL)
7904 && (datastr[0] == '-'))
7907 buff_encode_visit(smp_request, request_size,
7918 * If fd_data is set, and we're writing to the device, we need to
7919 * read the data the user wants written from stdin.
7921 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7923 int amt_to_read = request_size;
7924 u_int8_t *buf_ptr = smp_request;
7926 for (amt_read = 0; amt_to_read > 0;
7927 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7928 if (amt_read == -1) {
7929 warn("error reading data from stdin");
7931 goto smpcmd_bailout;
7933 amt_to_read -= amt_read;
7934 buf_ptr += amt_read;
7938 if (((arglist & CAM_ARG_CMD_IN) == 0)
7939 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7940 warnx("%s: need both the request (-r) and response (-R) "
7941 "arguments", __func__);
7943 goto smpcmd_bailout;
7946 flags |= CAM_DEV_QFRZDIS;
7948 cam_fill_smpio(&ccb->smpio,
7949 /*retries*/ retry_count,
7952 /*smp_request*/ smp_request,
7953 /*smp_request_len*/ request_size,
7954 /*smp_response*/ smp_response,
7955 /*smp_response_len*/ response_size,
7956 /*timeout*/ timeout ? timeout : 5000);
7958 ccb->smpio.flags = SMP_FLAG_NONE;
7960 if (((retval = cam_send_ccb(device, ccb)) < 0)
7961 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7962 const char warnstr[] = "error sending command";
7969 if (arglist & CAM_ARG_VERBOSE) {
7970 cam_error_print(device, ccb, CAM_ESF_ALL,
7971 CAM_EPF_ALL, stderr);
7975 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7976 && (response_size > 0)) {
7977 if (fd_response == 0) {
7978 buff_decode_visit(smp_response, response_size,
7979 datastr, arg_put, NULL);
7980 fprintf(stdout, "\n");
7982 ssize_t amt_written;
7983 int amt_to_write = response_size;
7984 u_int8_t *buf_ptr = smp_response;
7986 for (amt_written = 0; (amt_to_write > 0) &&
7987 (amt_written = write(STDOUT_FILENO, buf_ptr,
7988 amt_to_write)) > 0;){
7989 amt_to_write -= amt_written;
7990 buf_ptr += amt_written;
7992 if (amt_written == -1) {
7993 warn("error writing data to stdout");
7995 goto smpcmd_bailout;
7996 } else if ((amt_written == 0)
7997 && (amt_to_write > 0)) {
7998 warnx("only wrote %u bytes out of %u",
7999 response_size - amt_to_write,
8008 if (smp_request != NULL)
8011 if (smp_response != NULL)
8018 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
8019 int retry_count, int timeout)
8023 int32_t mmc_opcode = 0, mmc_arg = 0;
8024 int32_t mmc_flags = -1;
8027 int is_bw_4 = 0, is_bw_1 = 0;
8028 int is_highspeed = 0, is_stdspeed = 0;
8029 int is_info_request = 0;
8031 uint8_t mmc_data_byte = 0;
8033 /* For IO_RW_EXTENDED command */
8034 uint8_t *mmc_data = NULL;
8035 struct mmc_data mmc_d;
8036 int mmc_data_len = 0;
8039 * Note that at the moment we don't support sending SMP CCBs to
8040 * devices that aren't probed by CAM.
8042 ccb = cam_getccb(device);
8044 warnx("%s: error allocating CCB", __func__);
8048 bzero(&(&ccb->ccb_h)[1],
8049 sizeof(union ccb) - sizeof(struct ccb_hdr));
8051 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8060 if (!strcmp(optarg, "high"))
8066 is_info_request = 1;
8069 mmc_opcode = strtol(optarg, NULL, 0);
8070 if (mmc_opcode < 0) {
8071 warnx("invalid MMC opcode %d",
8074 goto mmccmd_bailout;
8078 mmc_arg = strtol(optarg, NULL, 0);
8080 warnx("invalid MMC arg %d",
8083 goto mmccmd_bailout;
8087 mmc_flags = strtol(optarg, NULL, 0);
8088 if (mmc_flags < 0) {
8089 warnx("invalid MMC flags %d",
8092 goto mmccmd_bailout;
8096 mmc_data_len = strtol(optarg, NULL, 0);
8097 if (mmc_data_len <= 0) {
8098 warnx("invalid MMC data len %d",
8101 goto mmccmd_bailout;
8108 mmc_data_byte = strtol(optarg, NULL, 0);
8114 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
8116 /* If flags are left default, supply the right flags */
8118 switch (mmc_opcode) {
8119 case MMC_GO_IDLE_STATE:
8120 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
8122 case IO_SEND_OP_COND:
8123 mmc_flags = MMC_RSP_R4;
8125 case SD_SEND_RELATIVE_ADDR:
8126 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
8128 case MMC_SELECT_CARD:
8129 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
8130 mmc_arg = mmc_arg << 16;
8132 case SD_IO_RW_DIRECT:
8133 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
8134 mmc_arg = SD_IO_RW_ADR(mmc_arg);
8136 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
8138 case SD_IO_RW_EXTENDED:
8139 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
8140 mmc_arg = SD_IO_RW_ADR(mmc_arg);
8141 int len_arg = mmc_data_len;
8142 if (mmc_data_len == 512)
8146 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
8148 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
8151 mmc_flags = MMC_RSP_R1;
8155 // Switch bus width instead of sending IO command
8156 if (is_bw_4 || is_bw_1) {
8157 struct ccb_trans_settings_mmc *cts;
8158 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
8159 ccb->ccb_h.flags = 0;
8160 cts = &ccb->cts.proto_specific.mmc;
8161 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
8162 cts->ios_valid = MMC_BW;
8163 if (((retval = cam_send_ccb(device, ccb)) < 0)
8164 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8165 warn("Error sending command");
8167 printf("Parameters set OK\n");
8173 // Switch bus speed instead of sending IO command
8174 if (is_stdspeed || is_highspeed) {
8175 struct ccb_trans_settings_mmc *cts;
8176 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
8177 ccb->ccb_h.flags = 0;
8178 cts = &ccb->cts.proto_specific.mmc;
8179 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
8180 cts->ios_valid = MMC_BT;
8181 if (((retval = cam_send_ccb(device, ccb)) < 0)
8182 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8183 warn("Error sending command");
8185 printf("Speed set OK (HS: %d)\n", is_highspeed);
8191 // Get information about controller and its settings
8192 if (is_info_request) {
8193 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
8194 ccb->ccb_h.flags = 0;
8195 struct ccb_trans_settings_mmc *cts;
8196 cts = &ccb->cts.proto_specific.mmc;
8197 if (((retval = cam_send_ccb(device, ccb)) < 0)
8198 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8199 warn("Error sending command");
8202 printf("Host controller information\n");
8203 printf("Host OCR: 0x%x\n", cts->host_ocr);
8204 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
8205 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
8206 printf("Supported bus width: ");
8207 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
8209 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
8211 printf("\nCurrent settings:\n");
8212 printf("Bus width: ");
8213 switch (cts->ios.bus_width) {
8224 printf("Freq: %d.%03d MHz%s\n",
8225 cts->ios.clock / 1000000,
8226 (cts->ios.clock / 1000) % 1000,
8227 cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : "");
8231 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
8233 if (mmc_data_len > 0) {
8234 flags |= CAM_DIR_IN;
8235 mmc_data = malloc(mmc_data_len);
8236 memset(mmc_data, 0, mmc_data_len);
8237 memset(&mmc_d, 0, sizeof(mmc_d));
8238 mmc_d.len = mmc_data_len;
8239 mmc_d.data = mmc_data;
8240 mmc_d.flags = MMC_DATA_READ;
8241 } else flags |= CAM_DIR_NONE;
8243 cam_fill_mmcio(&ccb->mmcio,
8244 /*retries*/ retry_count,
8247 /*mmc_opcode*/ mmc_opcode,
8248 /*mmc_arg*/ mmc_arg,
8249 /*mmc_flags*/ mmc_flags,
8250 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
8251 /*timeout*/ timeout ? timeout : 5000);
8253 if (((retval = cam_send_ccb(device, ccb)) < 0)
8254 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8255 const char warnstr[] = "error sending command";
8262 if (arglist & CAM_ARG_VERBOSE) {
8263 cam_error_print(device, ccb, CAM_ESF_ALL,
8264 CAM_EPF_ALL, stderr);
8268 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
8269 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
8270 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
8271 ccb->mmcio.cmd.resp[1],
8272 ccb->mmcio.cmd.resp[2],
8273 ccb->mmcio.cmd.resp[3]);
8275 switch (mmc_opcode) {
8276 case SD_IO_RW_DIRECT:
8277 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
8278 SD_R5_DATA(ccb->mmcio.cmd.resp),
8279 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
8281 case SD_IO_RW_EXTENDED:
8282 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
8283 hexdump(mmc_data, mmc_data_len, NULL, 0);
8285 case SD_SEND_RELATIVE_ADDR:
8286 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
8289 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
8296 if (mmc_data_len > 0 && mmc_data != NULL)
8303 smpreportgeneral(struct cam_device *device, int argc, char **argv,
8304 char *combinedopt, int retry_count, int timeout)
8307 struct smp_report_general_request *request = NULL;
8308 struct smp_report_general_response *response = NULL;
8309 struct sbuf *sb = NULL;
8311 int c, long_response = 0;
8315 * Note that at the moment we don't support sending SMP CCBs to
8316 * devices that aren't probed by CAM.
8318 ccb = cam_getccb(device);
8320 warnx("%s: error allocating CCB", __func__);
8324 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8326 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8335 request = malloc(sizeof(*request));
8336 if (request == NULL) {
8337 warn("%s: unable to allocate %zd bytes", __func__,
8343 response = malloc(sizeof(*response));
8344 if (response == NULL) {
8345 warn("%s: unable to allocate %zd bytes", __func__,
8352 smp_report_general(&ccb->smpio,
8356 /*request_len*/ sizeof(*request),
8357 (uint8_t *)response,
8358 /*response_len*/ sizeof(*response),
8359 /*long_response*/ long_response,
8362 if (((retval = cam_send_ccb(device, ccb)) < 0)
8363 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8364 const char warnstr[] = "error sending command";
8371 if (arglist & CAM_ARG_VERBOSE) {
8372 cam_error_print(device, ccb, CAM_ESF_ALL,
8373 CAM_EPF_ALL, stderr);
8380 * If the device supports the long response bit, try again and see
8381 * if we can get all of the data.
8383 if ((response->long_response & SMP_RG_LONG_RESPONSE)
8384 && (long_response == 0)) {
8385 ccb->ccb_h.status = CAM_REQ_INPROG;
8386 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8392 * XXX KDM detect and decode SMP errors here.
8394 sb = sbuf_new_auto();
8396 warnx("%s: error allocating sbuf", __func__);
8400 smp_report_general_sbuf(response, sizeof(*response), sb);
8402 if (sbuf_finish(sb) != 0) {
8403 warnx("%s: sbuf_finish", __func__);
8407 printf("%s", sbuf_data(sb));
8413 if (request != NULL)
8416 if (response != NULL)
8425 static struct camcontrol_opts phy_ops[] = {
8426 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
8427 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
8428 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
8429 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
8430 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
8431 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
8432 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
8433 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
8434 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
8439 smpphycontrol(struct cam_device *device, int argc, char **argv,
8440 char *combinedopt, int retry_count, int timeout)
8443 struct smp_phy_control_request *request = NULL;
8444 struct smp_phy_control_response *response = NULL;
8445 int long_response = 0;
8448 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
8450 uint64_t attached_dev_name = 0;
8451 int dev_name_set = 0;
8452 uint32_t min_plr = 0, max_plr = 0;
8453 uint32_t pp_timeout_val = 0;
8454 int slumber_partial = 0;
8455 int set_pp_timeout_val = 0;
8459 * Note that at the moment we don't support sending SMP CCBs to
8460 * devices that aren't probed by CAM.
8462 ccb = cam_getccb(device);
8464 warnx("%s: error allocating CCB", __func__);
8468 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8470 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8478 if (strcasecmp(optarg, "enable") == 0)
8480 else if (strcasecmp(optarg, "disable") == 0)
8483 warnx("%s: Invalid argument %s", __func__,
8490 slumber_partial |= enable <<
8491 SMP_PC_SAS_SLUMBER_SHIFT;
8494 slumber_partial |= enable <<
8495 SMP_PC_SAS_PARTIAL_SHIFT;
8498 slumber_partial |= enable <<
8499 SMP_PC_SATA_SLUMBER_SHIFT;
8502 slumber_partial |= enable <<
8503 SMP_PC_SATA_PARTIAL_SHIFT;
8506 warnx("%s: programmer error", __func__);
8509 break; /*NOTREACHED*/
8514 attached_dev_name = (uintmax_t)strtoumax(optarg,
8523 * We don't do extensive checking here, so this
8524 * will continue to work when new speeds come out.
8526 min_plr = strtoul(optarg, NULL, 0);
8528 || (min_plr > 0xf)) {
8529 warnx("%s: invalid link rate %x",
8537 * We don't do extensive checking here, so this
8538 * will continue to work when new speeds come out.
8540 max_plr = strtoul(optarg, NULL, 0);
8542 || (max_plr > 0xf)) {
8543 warnx("%s: invalid link rate %x",
8550 camcontrol_optret optreturn;
8551 cam_argmask argnums;
8554 if (phy_op_set != 0) {
8555 warnx("%s: only one phy operation argument "
8556 "(-o) allowed", __func__);
8564 * Allow the user to specify the phy operation
8565 * numerically, as well as with a name. This will
8566 * future-proof it a bit, so options that are added
8567 * in future specs can be used.
8569 if (isdigit(optarg[0])) {
8570 phy_operation = strtoul(optarg, NULL, 0);
8571 if ((phy_operation == 0)
8572 || (phy_operation > 0xff)) {
8573 warnx("%s: invalid phy operation %#x",
8574 __func__, phy_operation);
8580 optreturn = getoption(phy_ops, optarg, &phy_operation,
8583 if (optreturn == CC_OR_AMBIGUOUS) {
8584 warnx("%s: ambiguous option %s", __func__,
8589 } else if (optreturn == CC_OR_NOT_FOUND) {
8590 warnx("%s: option %s not found", __func__,
8602 pp_timeout_val = strtoul(optarg, NULL, 0);
8603 if (pp_timeout_val > 15) {
8604 warnx("%s: invalid partial pathway timeout "
8605 "value %u, need a value less than 16",
8606 __func__, pp_timeout_val);
8610 set_pp_timeout_val = 1;
8618 warnx("%s: a PHY (-p phy) argument is required",__func__);
8623 if (((dev_name_set != 0)
8624 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8625 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8626 && (dev_name_set == 0))) {
8627 warnx("%s: -d name and -o setdevname arguments both "
8628 "required to set device name", __func__);
8633 request = malloc(sizeof(*request));
8634 if (request == NULL) {
8635 warn("%s: unable to allocate %zd bytes", __func__,
8641 response = malloc(sizeof(*response));
8642 if (response == NULL) {
8643 warn("%s: unable to allocate %zd bytes", __func__,
8649 smp_phy_control(&ccb->smpio,
8654 (uint8_t *)response,
8657 /*expected_exp_change_count*/ 0,
8660 (set_pp_timeout_val != 0) ? 1 : 0,
8668 if (((retval = cam_send_ccb(device, ccb)) < 0)
8669 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8670 const char warnstr[] = "error sending command";
8677 if (arglist & CAM_ARG_VERBOSE) {
8679 * Use CAM_EPF_NORMAL so we only get one line of
8680 * SMP command decoding.
8682 cam_error_print(device, ccb, CAM_ESF_ALL,
8683 CAM_EPF_NORMAL, stderr);
8689 /* XXX KDM print out something here for success? */
8694 if (request != NULL)
8697 if (response != NULL)
8704 smpmaninfo(struct cam_device *device, int argc, char **argv,
8705 char *combinedopt, int retry_count, int timeout)
8708 struct smp_report_manuf_info_request request;
8709 struct smp_report_manuf_info_response response;
8710 struct sbuf *sb = NULL;
8711 int long_response = 0;
8716 * Note that at the moment we don't support sending SMP CCBs to
8717 * devices that aren't probed by CAM.
8719 ccb = cam_getccb(device);
8721 warnx("%s: error allocating CCB", __func__);
8725 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8727 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8736 bzero(&request, sizeof(request));
8737 bzero(&response, sizeof(response));
8739 smp_report_manuf_info(&ccb->smpio,
8744 (uint8_t *)&response,
8749 if (((retval = cam_send_ccb(device, ccb)) < 0)
8750 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8751 const char warnstr[] = "error sending command";
8758 if (arglist & CAM_ARG_VERBOSE) {
8759 cam_error_print(device, ccb, CAM_ESF_ALL,
8760 CAM_EPF_ALL, stderr);
8766 sb = sbuf_new_auto();
8768 warnx("%s: error allocating sbuf", __func__);
8772 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8774 if (sbuf_finish(sb) != 0) {
8775 warnx("%s: sbuf_finish", __func__);
8779 printf("%s", sbuf_data(sb));
8793 getdevid(struct cam_devitem *item)
8796 union ccb *ccb = NULL;
8798 struct cam_device *dev;
8800 dev = cam_open_btl(item->dev_match.path_id,
8801 item->dev_match.target_id,
8802 item->dev_match.target_lun, O_RDWR, NULL);
8805 warnx("%s", cam_errbuf);
8810 item->device_id_len = 0;
8812 ccb = cam_getccb(dev);
8814 warnx("%s: error allocating CCB", __func__);
8819 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8822 * On the first try, we just probe for the size of the data, and
8823 * then allocate that much memory and try again.
8826 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8827 ccb->ccb_h.flags = CAM_DIR_IN;
8828 ccb->cdai.flags = CDAI_FLAG_NONE;
8829 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8830 ccb->cdai.bufsiz = item->device_id_len;
8831 if (item->device_id_len != 0)
8832 ccb->cdai.buf = (uint8_t *)item->device_id;
8834 if (cam_send_ccb(dev, ccb) < 0) {
8835 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8840 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8841 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8846 if (item->device_id_len == 0) {
8848 * This is our first time through. Allocate the buffer,
8849 * and then go back to get the data.
8851 if (ccb->cdai.provsiz == 0) {
8852 warnx("%s: invalid .provsiz field returned with "
8853 "XPT_GDEV_ADVINFO CCB", __func__);
8857 item->device_id_len = ccb->cdai.provsiz;
8858 item->device_id = malloc(item->device_id_len);
8859 if (item->device_id == NULL) {
8860 warn("%s: unable to allocate %d bytes", __func__,
8861 item->device_id_len);
8865 ccb->ccb_h.status = CAM_REQ_INPROG;
8871 cam_close_device(dev);
8880 * XXX KDM merge this code with getdevtree()?
8883 buildbusdevlist(struct cam_devlist *devlist)
8886 int bufsize, fd = -1;
8887 struct dev_match_pattern *patterns;
8888 struct cam_devitem *item = NULL;
8889 int skip_device = 0;
8892 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8893 warn("couldn't open %s", XPT_DEVICE);
8897 bzero(&ccb, sizeof(union ccb));
8899 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8900 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8901 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8903 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8904 bufsize = sizeof(struct dev_match_result) * 100;
8905 ccb.cdm.match_buf_len = bufsize;
8906 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8907 if (ccb.cdm.matches == NULL) {
8908 warnx("can't malloc memory for matches");
8912 ccb.cdm.num_matches = 0;
8913 ccb.cdm.num_patterns = 2;
8914 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8915 ccb.cdm.num_patterns;
8917 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8918 if (patterns == NULL) {
8919 warnx("can't malloc memory for patterns");
8924 ccb.cdm.patterns = patterns;
8925 bzero(patterns, ccb.cdm.pattern_buf_len);
8927 patterns[0].type = DEV_MATCH_DEVICE;
8928 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8929 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8930 patterns[1].type = DEV_MATCH_PERIPH;
8931 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8932 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8935 * We do the ioctl multiple times if necessary, in case there are
8936 * more than 100 nodes in the EDT.
8941 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8942 warn("error sending CAMIOCOMMAND ioctl");
8947 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8948 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8949 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8950 warnx("got CAM error %#x, CDM error %d\n",
8951 ccb.ccb_h.status, ccb.cdm.status);
8956 for (i = 0; i < ccb.cdm.num_matches; i++) {
8957 switch (ccb.cdm.matches[i].type) {
8958 case DEV_MATCH_DEVICE: {
8959 struct device_match_result *dev_result;
8962 &ccb.cdm.matches[i].result.device_result;
8964 if (dev_result->flags &
8965 DEV_RESULT_UNCONFIGURED) {
8971 item = malloc(sizeof(*item));
8973 warn("%s: unable to allocate %zd bytes",
8974 __func__, sizeof(*item));
8978 bzero(item, sizeof(*item));
8979 bcopy(dev_result, &item->dev_match,
8980 sizeof(*dev_result));
8981 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8984 if (getdevid(item) != 0) {
8990 case DEV_MATCH_PERIPH: {
8991 struct periph_match_result *periph_result;
8994 &ccb.cdm.matches[i].result.periph_result;
8996 if (skip_device != 0)
8998 item->num_periphs++;
8999 item->periph_matches = realloc(
9000 item->periph_matches,
9002 sizeof(struct periph_match_result));
9003 if (item->periph_matches == NULL) {
9004 warn("%s: error allocating periph "
9009 bcopy(periph_result, &item->periph_matches[
9010 item->num_periphs - 1],
9011 sizeof(*periph_result));
9015 fprintf(stderr, "%s: unexpected match "
9016 "type %d\n", __func__,
9017 ccb.cdm.matches[i].type);
9020 break; /*NOTREACHED*/
9023 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
9024 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
9032 free(ccb.cdm.matches);
9035 freebusdevlist(devlist);
9041 freebusdevlist(struct cam_devlist *devlist)
9043 struct cam_devitem *item, *item2;
9045 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
9046 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
9048 free(item->device_id);
9049 free(item->periph_matches);
9054 static struct cam_devitem *
9055 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
9057 struct cam_devitem *item;
9059 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
9060 struct scsi_vpd_id_descriptor *idd;
9063 * XXX KDM look for LUN IDs as well?
9065 idd = scsi_get_devid(item->device_id,
9066 item->device_id_len,
9067 scsi_devid_is_sas_target);
9071 if (scsi_8btou64(idd->identifier) == sasaddr)
9079 smpphylist(struct cam_device *device, int argc, char **argv,
9080 char *combinedopt, int retry_count, int timeout)
9082 struct smp_report_general_request *rgrequest = NULL;
9083 struct smp_report_general_response *rgresponse = NULL;
9084 struct smp_discover_request *disrequest = NULL;
9085 struct smp_discover_response *disresponse = NULL;
9086 struct cam_devlist devlist;
9088 int long_response = 0;
9095 * Note that at the moment we don't support sending SMP CCBs to
9096 * devices that aren't probed by CAM.
9098 ccb = cam_getccb(device);
9100 warnx("%s: error allocating CCB", __func__);
9104 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
9105 STAILQ_INIT(&devlist.dev_queue);
9107 rgrequest = malloc(sizeof(*rgrequest));
9108 if (rgrequest == NULL) {
9109 warn("%s: unable to allocate %zd bytes", __func__,
9110 sizeof(*rgrequest));
9115 rgresponse = malloc(sizeof(*rgresponse));
9116 if (rgresponse == NULL) {
9117 warn("%s: unable to allocate %zd bytes", __func__,
9118 sizeof(*rgresponse));
9123 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9136 smp_report_general(&ccb->smpio,
9140 /*request_len*/ sizeof(*rgrequest),
9141 (uint8_t *)rgresponse,
9142 /*response_len*/ sizeof(*rgresponse),
9143 /*long_response*/ long_response,
9146 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9148 if (((retval = cam_send_ccb(device, ccb)) < 0)
9149 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
9150 const char warnstr[] = "error sending command";
9157 if (arglist & CAM_ARG_VERBOSE) {
9158 cam_error_print(device, ccb, CAM_ESF_ALL,
9159 CAM_EPF_ALL, stderr);
9165 num_phys = rgresponse->num_phys;
9167 if (num_phys == 0) {
9169 fprintf(stdout, "%s: No Phys reported\n", __func__);
9174 devlist.path_id = device->path_id;
9176 retval = buildbusdevlist(&devlist);
9181 fprintf(stdout, "%d PHYs:\n", num_phys);
9182 fprintf(stdout, "PHY Attached SAS Address\n");
9185 disrequest = malloc(sizeof(*disrequest));
9186 if (disrequest == NULL) {
9187 warn("%s: unable to allocate %zd bytes", __func__,
9188 sizeof(*disrequest));
9193 disresponse = malloc(sizeof(*disresponse));
9194 if (disresponse == NULL) {
9195 warn("%s: unable to allocate %zd bytes", __func__,
9196 sizeof(*disresponse));
9201 for (i = 0; i < num_phys; i++) {
9202 struct cam_devitem *item;
9203 struct device_match_result *dev_match;
9204 char vendor[16], product[48], revision[16];
9208 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
9210 ccb->ccb_h.status = CAM_REQ_INPROG;
9211 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9213 smp_discover(&ccb->smpio,
9217 sizeof(*disrequest),
9218 (uint8_t *)disresponse,
9219 sizeof(*disresponse),
9221 /*ignore_zone_group*/ 0,
9225 if (((retval = cam_send_ccb(device, ccb)) < 0)
9226 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
9227 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
9228 const char warnstr[] = "error sending command";
9235 if (arglist & CAM_ARG_VERBOSE) {
9236 cam_error_print(device, ccb, CAM_ESF_ALL,
9237 CAM_EPF_ALL, stderr);
9243 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
9245 fprintf(stdout, "%3d <vacant>\n", i);
9249 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
9252 item = findsasdevice(&devlist,
9253 scsi_8btou64(disresponse->attached_sas_address));
9257 || (item != NULL)) {
9258 fprintf(stdout, "%3d 0x%016jx", i,
9259 (uintmax_t)scsi_8btou64(
9260 disresponse->attached_sas_address));
9262 fprintf(stdout, "\n");
9265 } else if (quiet != 0)
9268 dev_match = &item->dev_match;
9270 if (dev_match->protocol == PROTO_SCSI) {
9271 cam_strvis(vendor, dev_match->inq_data.vendor,
9272 sizeof(dev_match->inq_data.vendor),
9274 cam_strvis(product, dev_match->inq_data.product,
9275 sizeof(dev_match->inq_data.product),
9277 cam_strvis(revision, dev_match->inq_data.revision,
9278 sizeof(dev_match->inq_data.revision),
9280 sprintf(tmpstr, "<%s %s %s>", vendor, product,
9282 } else if ((dev_match->protocol == PROTO_ATA)
9283 || (dev_match->protocol == PROTO_SATAPM)) {
9284 cam_strvis(product, dev_match->ident_data.model,
9285 sizeof(dev_match->ident_data.model),
9287 cam_strvis(revision, dev_match->ident_data.revision,
9288 sizeof(dev_match->ident_data.revision),
9290 sprintf(tmpstr, "<%s %s>", product, revision);
9292 sprintf(tmpstr, "<>");
9294 fprintf(stdout, " %-33s ", tmpstr);
9297 * If we have 0 periphs, that's a bug...
9299 if (item->num_periphs == 0) {
9300 fprintf(stdout, "\n");
9304 fprintf(stdout, "(");
9305 for (j = 0; j < item->num_periphs; j++) {
9307 fprintf(stdout, ",");
9309 fprintf(stdout, "%s%d",
9310 item->periph_matches[j].periph_name,
9311 item->periph_matches[j].unit_number);
9314 fprintf(stdout, ")\n");
9328 freebusdevlist(&devlist);
9334 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
9336 struct ata_res *res;
9338 res = &ccb->ataio.res;
9339 if (res->status & ATA_STATUS_ERROR) {
9340 if (arglist & CAM_ARG_VERBOSE) {
9341 cam_error_print(device, ccb, CAM_ESF_ALL,
9342 CAM_EPF_ALL, stderr);
9343 printf("error = 0x%02x, sector_count = 0x%04x, "
9344 "device = 0x%02x, status = 0x%02x\n",
9345 res->error, res->sector_count,
9346 res->device, res->status);
9352 if (arglist & CAM_ARG_VERBOSE) {
9353 fprintf(stdout, "%s%d: Raw native check power data:\n",
9354 device->device_name, device->dev_unit_num);
9355 /* res is 4 byte aligned */
9356 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
9358 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
9359 "status = 0x%02x\n", res->error, res->sector_count,
9360 res->device, res->status);
9363 printf("%s%d: ", device->device_name, device->dev_unit_num);
9364 switch (res->sector_count) {
9366 printf("Standby mode\n");
9369 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
9372 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
9375 printf("Idle mode\n");
9378 printf("Active or Idle mode\n");
9381 printf("Unknown mode 0x%02x\n", res->sector_count);
9389 atapm(struct cam_device *device, int argc, char **argv,
9390 char *combinedopt, int retry_count, int timeout)
9396 u_int8_t ata_flags = 0;
9399 ccb = cam_getccb(device);
9402 warnx("%s: error allocating ccb", __func__);
9406 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9415 if (strcmp(argv[1], "idle") == 0) {
9417 cmd = ATA_IDLE_IMMEDIATE;
9420 } else if (strcmp(argv[1], "standby") == 0) {
9422 cmd = ATA_STANDBY_IMMEDIATE;
9424 cmd = ATA_STANDBY_CMD;
9425 } else if (strcmp(argv[1], "powermode") == 0) {
9426 cmd = ATA_CHECK_POWER_MODE;
9427 ata_flags = AP_FLAG_CHK_COND;
9436 else if (t <= (240 * 5))
9438 else if (t <= (252 * 5))
9439 /* special encoding for 21 minutes */
9441 else if (t <= (11 * 30 * 60))
9442 sc = (t - 1) / (30 * 60) + 241;
9446 retval = ata_do_cmd(device,
9448 /*retries*/retry_count,
9449 /*flags*/CAM_DIR_NONE,
9450 /*protocol*/AP_PROTO_NON_DATA,
9451 /*ata_flags*/ata_flags,
9452 /*tag_action*/MSG_SIMPLE_Q_TAG,
9459 /*timeout*/timeout ? timeout : 30 * 1000,
9464 if (retval || cmd != ATA_CHECK_POWER_MODE)
9467 return (atapm_proc_resp(device, ccb));
9471 ataaxm(struct cam_device *device, int argc, char **argv,
9472 char *combinedopt, int retry_count, int timeout)
9480 ccb = cam_getccb(device);
9483 warnx("%s: error allocating ccb", __func__);
9487 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9497 if (strcmp(argv[1], "apm") == 0) {
9513 retval = ata_do_28bit_cmd(device,
9515 /*retries*/retry_count,
9516 /*flags*/CAM_DIR_NONE,
9517 /*protocol*/AP_PROTO_NON_DATA,
9518 /*tag_action*/MSG_SIMPLE_Q_TAG,
9519 /*command*/ATA_SETFEATURES,
9525 /*timeout*/timeout ? timeout : 30 * 1000,
9533 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9534 int show_sa_errors, int sa_set, int service_action,
9535 int timeout_desc, int task_attr, int retry_count, int timeout,
9536 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9538 union ccb *ccb = NULL;
9539 uint8_t *buf = NULL;
9540 uint32_t alloc_len = 0, num_opcodes;
9541 uint32_t valid_len = 0;
9542 uint32_t avail_len = 0;
9543 struct scsi_report_supported_opcodes_all *all_hdr;
9544 struct scsi_report_supported_opcodes_one *one;
9549 * Make it clear that we haven't yet allocated or filled anything.
9554 ccb = cam_getccb(device);
9556 warnx("couldn't allocate CCB");
9561 /* cam_getccb cleans up the header, caller has to zero the payload */
9562 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9564 if (opcode_set != 0) {
9565 options |= RSO_OPTIONS_OC;
9567 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9570 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9571 sizeof(struct scsi_report_supported_opcodes_descr));
9574 if (timeout_desc != 0) {
9575 options |= RSO_RCTD;
9576 alloc_len += num_opcodes *
9577 sizeof(struct scsi_report_supported_opcodes_timeout);
9581 options |= RSO_OPTIONS_OC_SA;
9582 if (show_sa_errors != 0)
9583 options &= ~RSO_OPTIONS_OC;
9592 buf = malloc(alloc_len);
9594 warn("Unable to allocate %u bytes", alloc_len);
9598 bzero(buf, alloc_len);
9600 scsi_report_supported_opcodes(&ccb->csio,
9601 /*retries*/ retry_count,
9603 /*tag_action*/ task_attr,
9604 /*options*/ options,
9605 /*req_opcode*/ opcode,
9606 /*req_service_action*/ service_action,
9608 /*dxfer_len*/ alloc_len,
9609 /*sense_len*/ SSD_FULL_SIZE,
9610 /*timeout*/ timeout ? timeout : 10000);
9612 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9614 if (retry_count != 0)
9615 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9617 if (cam_send_ccb(device, ccb) < 0) {
9618 perror("error sending REPORT SUPPORTED OPERATION CODES");
9623 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9624 if (verbosemode != 0)
9625 cam_error_print(device, ccb, CAM_ESF_ALL,
9626 CAM_EPF_ALL, stderr);
9631 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9633 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9634 && (valid_len >= sizeof(*all_hdr))) {
9635 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9636 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9637 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9638 && (valid_len >= sizeof(*one))) {
9639 uint32_t cdb_length;
9641 one = (struct scsi_report_supported_opcodes_one *)buf;
9642 cdb_length = scsi_2btoul(one->cdb_length);
9643 avail_len = sizeof(*one) + cdb_length;
9644 if (one->support & RSO_ONE_CTDP) {
9645 struct scsi_report_supported_opcodes_timeout *td;
9647 td = (struct scsi_report_supported_opcodes_timeout *)
9649 if (valid_len >= (avail_len + sizeof(td->length))) {
9650 avail_len += scsi_2btoul(td->length) +
9653 avail_len += sizeof(*td);
9659 * avail_len could be zero if we didn't get enough data back from
9660 * thet target to determine
9662 if ((avail_len != 0)
9663 && (avail_len > valid_len)) {
9664 alloc_len = avail_len;
9668 *fill_len = valid_len;
9680 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9681 int req_sa, uint8_t *buf, uint32_t valid_len)
9683 struct scsi_report_supported_opcodes_one *one;
9684 struct scsi_report_supported_opcodes_timeout *td;
9685 uint32_t cdb_len = 0, td_len = 0;
9686 const char *op_desc = NULL;
9690 one = (struct scsi_report_supported_opcodes_one *)buf;
9693 * If we don't have the full single opcode descriptor, no point in
9696 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9698 warnx("Only %u bytes returned, not enough to verify support",
9704 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9706 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9709 printf(", SA 0x%x", req_sa);
9712 switch (one->support & RSO_ONE_SUP_MASK) {
9713 case RSO_ONE_SUP_UNAVAIL:
9714 printf("No command support information currently available\n");
9716 case RSO_ONE_SUP_NOT_SUP:
9717 printf("Command not supported\n");
9720 break; /*NOTREACHED*/
9721 case RSO_ONE_SUP_AVAIL:
9722 printf("Command is supported, complies with a SCSI standard\n");
9724 case RSO_ONE_SUP_VENDOR:
9725 printf("Command is supported, vendor-specific "
9726 "implementation\n");
9729 printf("Unknown command support flags 0x%#x\n",
9730 one->support & RSO_ONE_SUP_MASK);
9735 * If we don't have the CDB length, it isn't exactly an error, the
9736 * command probably isn't supported.
9738 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9742 cdb_len = scsi_2btoul(one->cdb_length);
9745 * If our valid data doesn't include the full reported length,
9746 * return. The caller should have detected this and adjusted his
9747 * allocation length to get all of the available data.
9749 if (valid_len < sizeof(*one) + cdb_len) {
9755 * If all we have is the opcode, there is no point in printing out
9763 printf("CDB usage bitmap:");
9764 for (i = 0; i < cdb_len; i++) {
9765 printf(" %02x", one->cdb_usage[i]);
9770 * If we don't have a timeout descriptor, we're done.
9772 if ((one->support & RSO_ONE_CTDP) == 0)
9776 * If we don't have enough valid length to include the timeout
9777 * descriptor length, we're done.
9779 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9782 td = (struct scsi_report_supported_opcodes_timeout *)
9783 &buf[sizeof(*one) + cdb_len];
9784 td_len = scsi_2btoul(td->length);
9785 td_len += sizeof(td->length);
9788 * If we don't have the full timeout descriptor, we're done.
9790 if (td_len < sizeof(*td))
9794 * If we don't have enough valid length to contain the full timeout
9795 * descriptor, we're done.
9797 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9800 printf("Timeout information:\n");
9801 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9802 printf("Nominal timeout: %u seconds\n",
9803 scsi_4btoul(td->nominal_time));
9804 printf("Recommended timeout: %u seconds\n",
9805 scsi_4btoul(td->recommended_time));
9812 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9815 struct scsi_report_supported_opcodes_all *hdr;
9816 struct scsi_report_supported_opcodes_descr *desc;
9817 uint32_t avail_len = 0, used_len = 0;
9821 if (valid_len < sizeof(*hdr)) {
9822 warnx("%s: not enough returned data (%u bytes) opcode list",
9823 __func__, valid_len);
9827 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9828 avail_len = scsi_4btoul(hdr->length);
9829 avail_len += sizeof(hdr->length);
9831 * Take the lesser of the amount of data the drive claims is
9832 * available, and the amount of data the HBA says was returned.
9834 avail_len = MIN(avail_len, valid_len);
9836 used_len = sizeof(hdr->length);
9838 printf("%-6s %4s %8s ",
9839 "Opcode", "SA", "CDB len" );
9842 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9843 printf(" Description\n");
9845 while ((avail_len - used_len) > sizeof(*desc)) {
9846 struct scsi_report_supported_opcodes_timeout *td;
9848 const char *op_desc = NULL;
9850 cur_ptr = &buf[used_len];
9851 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9853 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9854 if (op_desc == NULL)
9855 op_desc = "UNKNOWN";
9857 printf("0x%02x %#4x %8u ", desc->opcode,
9858 scsi_2btoul(desc->service_action),
9859 scsi_2btoul(desc->cdb_length));
9861 used_len += sizeof(*desc);
9863 if ((desc->flags & RSO_CTDP) == 0) {
9864 printf(" %s\n", op_desc);
9869 * If we don't have enough space to fit a timeout
9870 * descriptor, then we're done.
9872 if (avail_len - used_len < sizeof(*td)) {
9873 used_len = avail_len;
9874 printf(" %s\n", op_desc);
9877 cur_ptr = &buf[used_len];
9878 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9879 td_len = scsi_2btoul(td->length);
9880 td_len += sizeof(td->length);
9884 * If the given timeout descriptor length is less than what
9885 * we understand, skip it.
9887 if (td_len < sizeof(*td)) {
9888 printf(" %s\n", op_desc);
9892 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9893 scsi_4btoul(td->nominal_time),
9894 scsi_4btoul(td->recommended_time), op_desc);
9901 scsiopcodes(struct cam_device *device, int argc, char **argv,
9902 char *combinedopt, int task_attr, int retry_count, int timeout,
9906 uint32_t opcode = 0, service_action = 0;
9907 int td_set = 0, opcode_set = 0, sa_set = 0;
9908 int show_sa_errors = 1;
9909 uint32_t valid_len = 0;
9910 uint8_t *buf = NULL;
9914 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9920 opcode = strtoul(optarg, &endptr, 0);
9921 if (*endptr != '\0') {
9922 warnx("Invalid opcode \"%s\", must be a number",
9927 if (opcode > 0xff) {
9928 warnx("Invalid opcode 0x%#x, must be between"
9929 "0 and 0xff inclusive", opcode);
9936 service_action = strtoul(optarg, &endptr, 0);
9937 if (*endptr != '\0') {
9938 warnx("Invalid service action \"%s\", must "
9939 "be a number", optarg);
9943 if (service_action > 0xffff) {
9944 warnx("Invalid service action 0x%#x, must "
9945 "be between 0 and 0xffff inclusive",
9960 && (opcode_set == 0)) {
9961 warnx("You must specify an opcode with -o if a service "
9966 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9967 sa_set, service_action, td_set, task_attr,
9968 retry_count, timeout, verbosemode, &valid_len,
9973 if ((opcode_set != 0)
9975 retval = scsiprintoneopcode(device, opcode, sa_set,
9976 service_action, buf, valid_len);
9978 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9989 reprobe(struct cam_device *device)
9994 ccb = cam_getccb(device);
9997 warnx("%s: error allocating ccb", __func__);
10001 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
10003 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
10005 if (cam_send_ccb(device, ccb) < 0) {
10006 warn("error sending XPT_REPROBE_LUN CCB");
10011 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
10012 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
10024 usage(int printlong)
10027 fprintf(printlong ? stdout : stderr,
10028 "usage: camcontrol <command> [device id][generic args][command args]\n"
10029 " camcontrol devlist [-b] [-v]\n"
10030 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
10031 " camcontrol tur [dev_id][generic args]\n"
10032 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
10033 " camcontrol identify [dev_id][generic args] [-v]\n"
10034 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
10035 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
10036 " [-q] [-s] [-l]\n"
10037 " camcontrol start [dev_id][generic args]\n"
10038 " camcontrol stop [dev_id][generic args]\n"
10039 " camcontrol load [dev_id][generic args]\n"
10040 " camcontrol eject [dev_id][generic args]\n"
10041 " camcontrol reprobe [dev_id][generic args]\n"
10042 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
10043 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
10044 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
10045 " [-q][-s][-S offset][-X]\n"
10046 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
10047 " [-P pagectl][-e | -b][-d]\n"
10048 " camcontrol cmd [dev_id][generic args]\n"
10049 " <-a cmd [args] | -c cmd [args]>\n"
10050 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
10051 " camcontrol smpcmd [dev_id][generic args]\n"
10052 " <-r len fmt [args]> <-R len fmt [args]>\n"
10053 " camcontrol smprg [dev_id][generic args][-l]\n"
10054 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
10055 " [-o operation][-d name][-m rate][-M rate]\n"
10056 " [-T pp_timeout][-a enable|disable]\n"
10057 " [-A enable|disable][-s enable|disable]\n"
10058 " [-S enable|disable]\n"
10059 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
10060 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
10061 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
10062 " <all|dev_id|bus[:target[:lun]]|off>\n"
10063 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
10064 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
10065 " [-D <enable|disable>][-M mode][-O offset]\n"
10066 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
10067 " [-U][-W bus_width]\n"
10068 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
10069 " camcontrol sanitize [dev_id][generic args]\n"
10070 " [-a overwrite|block|crypto|exitfailure]\n"
10071 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
10073 " camcontrol idle [dev_id][generic args][-t time]\n"
10074 " camcontrol standby [dev_id][generic args][-t time]\n"
10075 " camcontrol sleep [dev_id][generic args]\n"
10076 " camcontrol powermode [dev_id][generic args]\n"
10077 " camcontrol apm [dev_id][generic args][-l level]\n"
10078 " camcontrol aam [dev_id][generic args][-l level]\n"
10079 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
10081 " camcontrol security [dev_id][generic args]\n"
10082 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
10083 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
10084 " [-U <user|master>] [-y]\n"
10085 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
10086 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
10087 " camcontrol ama [dev_id][generic args] [-f] [-q] [-s max_sectors]\n"
10088 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
10089 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
10090 " [-s scope][-S][-T type][-U]\n"
10091 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
10092 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
10093 " [-p part][-s start][-T type][-V vol]\n"
10094 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
10096 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
10097 " [-o rep_opts] [-P print_opts]\n"
10098 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
10099 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
10100 " [-S power_src] [-T timer]\n"
10101 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
10102 " <-s <-f format -T time | -U >>\n"
10103 " camcontrol devtype [dev_id]\n"
10105 " camcontrol help\n");
10109 "Specify one of the following options:\n"
10110 "devlist list all CAM devices\n"
10111 "periphlist list all CAM peripheral drivers attached to a device\n"
10112 "tur send a test unit ready to the named device\n"
10113 "inquiry send a SCSI inquiry command to the named device\n"
10114 "identify send a ATA identify command to the named device\n"
10115 "reportluns send a SCSI report luns command to the device\n"
10116 "readcap send a SCSI read capacity command to the device\n"
10117 "start send a Start Unit command to the device\n"
10118 "stop send a Stop Unit command to the device\n"
10119 "load send a Start Unit command to the device with the load bit set\n"
10120 "eject send a Stop Unit command to the device with the eject bit set\n"
10121 "reprobe update capacity information of the given device\n"
10122 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
10123 "reset reset all buses, the given bus, bus:target:lun or device\n"
10124 "defects read the defect list of the specified device\n"
10125 "modepage display or edit (-e) the given mode page\n"
10126 "cmd send the given SCSI command, may need -i or -o as well\n"
10127 "smpcmd send the given SMP command, requires -o and -i\n"
10128 "smprg send the SMP Report General command\n"
10129 "smppc send the SMP PHY Control command, requires -p\n"
10130 "smpphylist display phys attached to a SAS expander\n"
10131 "smpmaninfo send the SMP Report Manufacturer Info command\n"
10132 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
10133 "tags report or set the number of transaction slots for a device\n"
10134 "negotiate report or set device negotiation parameters\n"
10135 "format send the SCSI FORMAT UNIT command to the named device\n"
10136 "sanitize send the SCSI SANITIZE command to the named device\n"
10137 "idle send the ATA IDLE command to the named device\n"
10138 "standby send the ATA STANDBY command to the named device\n"
10139 "sleep send the ATA SLEEP command to the named device\n"
10140 "powermode send the ATA CHECK POWER MODE command to the named device\n"
10141 "fwdownload program firmware of the named device with the given image\n"
10142 "security report or send ATA security commands to the named device\n"
10143 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
10144 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
10145 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
10146 "zone manage Zoned Block (Shingled) devices\n"
10147 "epc send ATA Extended Power Conditions commands\n"
10148 "timestamp report or set the device's timestamp\n"
10149 "devtype report the type of device\n"
10150 "help this message\n"
10151 "Device Identifiers:\n"
10152 "bus:target specify the bus and target, lun defaults to 0\n"
10153 "bus:target:lun specify the bus, target and lun\n"
10154 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
10155 "Generic arguments:\n"
10156 "-v be verbose, print out sense information\n"
10157 "-t timeout command timeout in seconds, overrides default timeout\n"
10158 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
10159 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
10160 "-E have the kernel attempt to perform SCSI error recovery\n"
10161 "-C count specify the SCSI command retry count (needs -E to work)\n"
10162 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
10163 "modepage arguments:\n"
10164 "-l list all available mode pages\n"
10165 "-m page specify the mode page to view or edit\n"
10166 "-e edit the specified mode page\n"
10167 "-b force view to binary mode\n"
10168 "-d disable block descriptors for mode sense\n"
10169 "-P pgctl page control field 0-3\n"
10170 "defects arguments:\n"
10171 "-f format specify defect list format (block, bfi or phys)\n"
10172 "-G get the grown defect list\n"
10173 "-P get the permanent defect list\n"
10174 "inquiry arguments:\n"
10175 "-D get the standard inquiry data\n"
10176 "-S get the serial number\n"
10177 "-R get the transfer rate, etc.\n"
10178 "reportluns arguments:\n"
10179 "-c only report a count of available LUNs\n"
10180 "-l only print out luns, and not a count\n"
10181 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
10182 "readcap arguments\n"
10183 "-b only report the blocksize\n"
10184 "-h human readable device size, base 2\n"
10185 "-H human readable device size, base 10\n"
10186 "-N print the number of blocks instead of last block\n"
10187 "-q quiet, print numbers only\n"
10188 "-s only report the last block/device size\n"
10190 "-c cdb [args] specify the SCSI CDB\n"
10191 "-i len fmt specify input data and input data format\n"
10192 "-o len fmt [args] specify output data and output data fmt\n"
10193 "smpcmd arguments:\n"
10194 "-r len fmt [args] specify the SMP command to be sent\n"
10195 "-R len fmt [args] specify SMP response format\n"
10196 "smprg arguments:\n"
10197 "-l specify the long response format\n"
10198 "smppc arguments:\n"
10199 "-p phy specify the PHY to operate on\n"
10200 "-l specify the long request/response format\n"
10201 "-o operation specify the phy control operation\n"
10202 "-d name set the attached device name\n"
10203 "-m rate set the minimum physical link rate\n"
10204 "-M rate set the maximum physical link rate\n"
10205 "-T pp_timeout set the partial pathway timeout value\n"
10206 "-a enable|disable enable or disable SATA slumber\n"
10207 "-A enable|disable enable or disable SATA partial phy power\n"
10208 "-s enable|disable enable or disable SAS slumber\n"
10209 "-S enable|disable enable or disable SAS partial phy power\n"
10210 "smpphylist arguments:\n"
10211 "-l specify the long response format\n"
10212 "-q only print phys with attached devices\n"
10213 "smpmaninfo arguments:\n"
10214 "-l specify the long response format\n"
10215 "debug arguments:\n"
10216 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
10217 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
10218 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
10219 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
10220 "tags arguments:\n"
10221 "-N tags specify the number of tags to use for this device\n"
10222 "-q be quiet, don't report the number of tags\n"
10223 "-v report a number of tag-related parameters\n"
10224 "negotiate arguments:\n"
10225 "-a send a test unit ready after negotiation\n"
10226 "-c report/set current negotiation settings\n"
10227 "-D <arg> \"enable\" or \"disable\" disconnection\n"
10228 "-M mode set ATA mode\n"
10229 "-O offset set command delay offset\n"
10230 "-q be quiet, don't report anything\n"
10231 "-R syncrate synchronization rate in MHz\n"
10232 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
10233 "-U report/set user negotiation settings\n"
10234 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
10235 "-v also print a Path Inquiry CCB for the controller\n"
10236 "format arguments:\n"
10237 "-q be quiet, don't print status messages\n"
10238 "-r run in report only mode\n"
10239 "-w don't send immediate format command\n"
10240 "-y don't ask any questions\n"
10241 "sanitize arguments:\n"
10242 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
10243 "-c passes overwrite passes to perform (1 to 31)\n"
10244 "-I invert overwrite pattern after each pass\n"
10245 "-P pattern path to overwrite pattern file\n"
10246 "-q be quiet, don't print status messages\n"
10247 "-r run in report only mode\n"
10248 "-U run operation in unrestricted completion exit mode\n"
10249 "-w don't send immediate sanitize command\n"
10250 "-y don't ask any questions\n"
10251 "idle/standby arguments:\n"
10252 "-t <arg> number of seconds before respective state.\n"
10253 "fwdownload arguments:\n"
10254 "-f fw_image path to firmware image file\n"
10255 "-q don't print informational messages, only errors\n"
10256 "-s run in simulation mode\n"
10257 "-v print info for every firmware segment sent to device\n"
10258 "-y don't ask any questions\n"
10259 "security arguments:\n"
10260 "-d pwd disable security using the given password for the selected\n"
10262 "-e pwd erase the device using the given pwd for the selected user\n"
10263 "-f freeze the security configuration of the specified device\n"
10264 "-h pwd enhanced erase the device using the given pwd for the\n"
10266 "-k pwd unlock the device using the given pwd for the selected\n"
10268 "-l <high|maximum> specifies which security level to set: high or maximum\n"
10269 "-q be quiet, do not print any status messages\n"
10270 "-s pwd password the device (enable security) using the given\n"
10271 " pwd for the selected user\n"
10272 "-T timeout overrides the timeout (seconds) used for erase operation\n"
10273 "-U <user|master> specifies which user to set: user or master\n"
10274 "-y don't ask any questions\n"
10276 "-f freeze the HPA configuration of the device\n"
10277 "-l lock the HPA configuration of the device\n"
10278 "-P make the HPA max sectors persist\n"
10279 "-p pwd Set the HPA configuration password required for unlock\n"
10281 "-q be quiet, do not print any status messages\n"
10282 "-s sectors configures the maximum user accessible sectors of the\n"
10284 "-U pwd unlock the HPA configuration of the device\n"
10285 "-y don't ask any questions\n"
10287 "-f freeze the AMA configuration of the device\n"
10288 "-q be quiet, do not print any status messages\n"
10289 "-s sectors configures the maximum user accessible sectors of the\n"
10291 "persist arguments:\n"
10292 "-i action specify read_keys, read_reservation, report_cap, or\n"
10293 " read_full_status\n"
10294 "-o action specify register, register_ignore, reserve, release,\n"
10295 " clear, preempt, preempt_abort, register_move, replace_lost\n"
10296 "-a set the All Target Ports (ALL_TG_PT) bit\n"
10297 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
10298 "-k key specify the Reservation Key\n"
10299 "-K sa_key specify the Service Action Reservation Key\n"
10300 "-p set the Activate Persist Through Power Loss bit\n"
10301 "-R rtp specify the Relative Target Port\n"
10302 "-s scope specify the scope: lun, extent, element or a number\n"
10303 "-S specify Transport ID for register, requires -I\n"
10304 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
10305 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
10306 "-U unregister the current initiator for register_move\n"
10307 "attrib arguments:\n"
10308 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
10310 "-w attr specify an attribute to write, one -w argument per attr\n"
10311 "-a attr_num only display this attribute number\n"
10312 "-c get cached attributes\n"
10313 "-e elem_addr request attributes for the given element in a changer\n"
10314 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
10315 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
10316 " field_none, field_desc, field_num, field_size, field_rw\n"
10317 "-p partition request attributes for the given partition\n"
10318 "-s start_attr request attributes starting at the given number\n"
10319 "-T elem_type specify the element type (used with -e)\n"
10320 "-V logical_vol specify the logical volume ID\n"
10321 "opcodes arguments:\n"
10322 "-o opcode specify the individual opcode to list\n"
10323 "-s service_action specify the service action for the opcode\n"
10324 "-N do not return SCSI error for unsupported SA\n"
10325 "-T request nominal and recommended timeout values\n"
10326 "zone arguments:\n"
10327 "-c cmd required: rz, open, close, finish, or rwp\n"
10328 "-a apply the action to all zones\n"
10329 "-l LBA specify the zone starting LBA\n"
10330 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
10331 " closed, full, ro, offline, reset, nonseq, nonwp\n"
10332 "-P print_opt report zones printing: normal, summary, script\n"
10334 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
10335 " source, status, list\n"
10336 "-d disable power mode (timer, state)\n"
10337 "-D delayed entry (goto)\n"
10338 "-e enable power mode (timer, state)\n"
10339 "-H hold power mode (goto)\n"
10340 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
10342 "-P only display power mode (status)\n"
10343 "-r rst_src restore settings from: default, saved (restore)\n"
10344 "-s save mode (timer, state, restore)\n"
10345 "-S power_src set power source: battery, nonbattery (source)\n"
10346 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
10347 "timestamp arguments:\n"
10348 "-r report the timestamp of the device\n"
10349 "-f format report the timestamp of the device with the given\n"
10350 " strftime(3) format string\n"
10351 "-m report the timestamp of the device as milliseconds since\n"
10352 " January 1st, 1970\n"
10353 "-U report the time with UTC instead of the local time zone\n"
10354 "-s set the timestamp of the device\n"
10355 "-f format the format of the time string passed into strptime(3)\n"
10356 "-T time the time value passed into strptime(3)\n"
10357 "-U set the timestamp of the device to UTC time\n"
10362 main(int argc, char **argv)
10365 char *device = NULL;
10367 struct cam_device *cam_dev = NULL;
10368 int timeout = 0, retry_count = 1;
10369 camcontrol_optret optreturn;
10371 const char *mainopt = "C:En:Q:t:u:v";
10372 const char *subopt = NULL;
10373 char combinedopt[256];
10374 int error = 0, optstart = 2;
10375 int task_attr = MSG_SIMPLE_Q_TAG;
10378 target_id_t target;
10381 cmdlist = CAM_CMD_NONE;
10382 arglist = CAM_ARG_NONE;
10390 * Get the base option.
10392 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
10394 if (optreturn == CC_OR_AMBIGUOUS) {
10395 warnx("ambiguous option %s", argv[1]);
10398 } else if (optreturn == CC_OR_NOT_FOUND) {
10399 warnx("option %s not found", argv[1]);
10405 * Ahh, getopt(3) is a pain.
10407 * This is a gross hack. There really aren't many other good
10408 * options (excuse the pun) for parsing options in a situation like
10409 * this. getopt is kinda braindead, so you end up having to run
10410 * through the options twice, and give each invocation of getopt
10411 * the option string for the other invocation.
10413 * You would think that you could just have two groups of options.
10414 * The first group would get parsed by the first invocation of
10415 * getopt, and the second group would get parsed by the second
10416 * invocation of getopt. It doesn't quite work out that way. When
10417 * the first invocation of getopt finishes, it leaves optind pointing
10418 * to the argument _after_ the first argument in the second group.
10419 * So when the second invocation of getopt comes around, it doesn't
10420 * recognize the first argument it gets and then bails out.
10422 * A nice alternative would be to have a flag for getopt that says
10423 * "just keep parsing arguments even when you encounter an unknown
10424 * argument", but there isn't one. So there's no real clean way to
10425 * easily parse two sets of arguments without having one invocation
10426 * of getopt know about the other.
10428 * Without this hack, the first invocation of getopt would work as
10429 * long as the generic arguments are first, but the second invocation
10430 * (in the subfunction) would fail in one of two ways. In the case
10431 * where you don't set optreset, it would fail because optind may be
10432 * pointing to the argument after the one it should be pointing at.
10433 * In the case where you do set optreset, and reset optind, it would
10434 * fail because getopt would run into the first set of options, which
10435 * it doesn't understand.
10437 * All of this would "sort of" work if you could somehow figure out
10438 * whether optind had been incremented one option too far. The
10439 * mechanics of that, however, are more daunting than just giving
10440 * both invocations all of the expect options for either invocation.
10442 * Needless to say, I wouldn't mind if someone invented a better
10443 * (non-GPL!) command line parsing interface than getopt. I
10444 * wouldn't mind if someone added more knobs to getopt to make it
10445 * work better. Who knows, I may talk myself into doing it someday,
10446 * if the standards weenies let me. As it is, it just leads to
10447 * hackery like this and causes people to avoid it in some cases.
10449 * KDM, September 8th, 1998
10451 if (subopt != NULL)
10452 sprintf(combinedopt, "%s%s", mainopt, subopt);
10454 sprintf(combinedopt, "%s", mainopt);
10457 * For these options we do not parse optional device arguments and
10458 * we do not open a passthrough device.
10460 if ((cmdlist == CAM_CMD_RESCAN)
10461 || (cmdlist == CAM_CMD_RESET)
10462 || (cmdlist == CAM_CMD_DEVTREE)
10463 || (cmdlist == CAM_CMD_USAGE)
10464 || (cmdlist == CAM_CMD_DEBUG))
10468 && (argc > 2 && argv[2][0] != '-')) {
10472 if (isdigit(argv[2][0])) {
10473 /* device specified as bus:target[:lun] */
10474 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10476 errx(1, "numeric device specification must "
10477 "be either bus:target, or "
10479 /* default to 0 if lun was not specified */
10480 if ((arglist & CAM_ARG_LUN) == 0) {
10482 arglist |= CAM_ARG_LUN;
10486 if (cam_get_device(argv[2], name, sizeof name, &unit)
10488 errx(1, "%s", cam_errbuf);
10489 device = strdup(name);
10490 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10495 * Start getopt processing at argv[2/3], since we've already
10496 * accepted argv[1..2] as the command name, and as a possible
10502 * Now we run through the argument list looking for generic
10503 * options, and ignoring options that possibly belong to
10506 while ((c = getopt(argc, argv, combinedopt))!= -1){
10509 retry_count = strtol(optarg, NULL, 0);
10510 if (retry_count < 0)
10511 errx(1, "retry count %d is < 0",
10513 arglist |= CAM_ARG_RETRIES;
10516 arglist |= CAM_ARG_ERR_RECOVER;
10519 arglist |= CAM_ARG_DEVICE;
10521 while (isspace(*tstr) && (*tstr != '\0'))
10523 device = (char *)strdup(tstr);
10527 int table_entry = 0;
10530 while (isspace(*tstr) && (*tstr != '\0'))
10532 if (isdigit(*tstr)) {
10533 task_attr = strtol(tstr, &endptr, 0);
10534 if (*endptr != '\0') {
10535 errx(1, "Invalid queue option "
10540 scsi_nv_status status;
10542 table_size = sizeof(task_attrs) /
10543 sizeof(task_attrs[0]);
10544 status = scsi_get_nv(task_attrs,
10545 table_size, tstr, &table_entry,
10546 SCSI_NV_FLAG_IG_CASE);
10547 if (status == SCSI_NV_FOUND)
10548 task_attr = task_attrs[
10549 table_entry].value;
10551 errx(1, "%s option %s",
10552 (status == SCSI_NV_AMBIGUOUS)?
10553 "ambiguous" : "invalid",
10560 timeout = strtol(optarg, NULL, 0);
10562 errx(1, "invalid timeout %d", timeout);
10563 /* Convert the timeout from seconds to ms */
10565 arglist |= CAM_ARG_TIMEOUT;
10568 arglist |= CAM_ARG_UNIT;
10569 unit = strtol(optarg, NULL, 0);
10572 arglist |= CAM_ARG_VERBOSE;
10580 * For most commands we'll want to open the passthrough device
10581 * associated with the specified device. In the case of the rescan
10582 * commands, we don't use a passthrough device at all, just the
10583 * transport layer device.
10585 if (devopen == 1) {
10586 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10587 && (((arglist & CAM_ARG_DEVICE) == 0)
10588 || ((arglist & CAM_ARG_UNIT) == 0))) {
10589 errx(1, "subcommand \"%s\" requires a valid device "
10590 "identifier", argv[1]);
10593 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10594 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10595 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10597 errx(1,"%s", cam_errbuf);
10601 * Reset optind to 2, and reset getopt, so these routines can parse
10602 * the arguments again.
10608 case CAM_CMD_DEVLIST:
10609 error = getdevlist(cam_dev);
10612 error = atahpa(cam_dev, retry_count, timeout,
10613 argc, argv, combinedopt);
10616 error = ataama(cam_dev, retry_count, timeout,
10617 argc, argv, combinedopt);
10619 case CAM_CMD_DEVTREE:
10620 error = getdevtree(argc, argv, combinedopt);
10622 case CAM_CMD_DEVTYPE:
10623 error = getdevtype(cam_dev);
10626 error = testunitready(cam_dev, task_attr, retry_count,
10629 case CAM_CMD_INQUIRY:
10630 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10631 task_attr, retry_count, timeout);
10633 case CAM_CMD_IDENTIFY:
10634 error = identify(cam_dev, retry_count, timeout);
10636 case CAM_CMD_STARTSTOP:
10637 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10638 arglist & CAM_ARG_EJECT, task_attr,
10639 retry_count, timeout);
10641 case CAM_CMD_RESCAN:
10642 error = dorescan_or_reset(argc, argv, 1);
10644 case CAM_CMD_RESET:
10645 error = dorescan_or_reset(argc, argv, 0);
10647 case CAM_CMD_READ_DEFECTS:
10648 error = readdefects(cam_dev, argc, argv, combinedopt,
10649 task_attr, retry_count, timeout);
10651 case CAM_CMD_MODE_PAGE:
10652 modepage(cam_dev, argc, argv, combinedopt,
10653 task_attr, retry_count, timeout);
10655 case CAM_CMD_SCSI_CMD:
10656 error = scsicmd(cam_dev, argc, argv, combinedopt,
10657 task_attr, retry_count, timeout);
10659 case CAM_CMD_MMCSD_CMD:
10660 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10661 retry_count, timeout);
10663 case CAM_CMD_SMP_CMD:
10664 error = smpcmd(cam_dev, argc, argv, combinedopt,
10665 retry_count, timeout);
10667 case CAM_CMD_SMP_RG:
10668 error = smpreportgeneral(cam_dev, argc, argv,
10669 combinedopt, retry_count,
10672 case CAM_CMD_SMP_PC:
10673 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10674 retry_count, timeout);
10676 case CAM_CMD_SMP_PHYLIST:
10677 error = smpphylist(cam_dev, argc, argv, combinedopt,
10678 retry_count, timeout);
10680 case CAM_CMD_SMP_MANINFO:
10681 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10682 retry_count, timeout);
10684 case CAM_CMD_DEBUG:
10685 error = camdebug(argc, argv, combinedopt);
10688 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10691 error = ratecontrol(cam_dev, task_attr, retry_count,
10692 timeout, argc, argv, combinedopt);
10694 case CAM_CMD_FORMAT:
10695 error = scsiformat(cam_dev, argc, argv,
10696 combinedopt, task_attr, retry_count,
10699 case CAM_CMD_REPORTLUNS:
10700 error = scsireportluns(cam_dev, argc, argv,
10701 combinedopt, task_attr,
10702 retry_count, timeout);
10704 case CAM_CMD_READCAP:
10705 error = scsireadcapacity(cam_dev, argc, argv,
10706 combinedopt, task_attr,
10707 retry_count, timeout);
10710 case CAM_CMD_STANDBY:
10711 case CAM_CMD_SLEEP:
10712 case CAM_CMD_POWER_MODE:
10713 error = atapm(cam_dev, argc, argv,
10714 combinedopt, retry_count, timeout);
10718 error = ataaxm(cam_dev, argc, argv,
10719 combinedopt, retry_count, timeout);
10721 case CAM_CMD_SECURITY:
10722 error = atasecurity(cam_dev, retry_count, timeout,
10723 argc, argv, combinedopt);
10725 case CAM_CMD_DOWNLOAD_FW:
10726 error = fwdownload(cam_dev, argc, argv, combinedopt,
10727 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10730 case CAM_CMD_SANITIZE:
10731 error = sanitize(cam_dev, argc, argv, combinedopt, task_attr,
10732 retry_count, timeout);
10734 case CAM_CMD_PERSIST:
10735 error = scsipersist(cam_dev, argc, argv, combinedopt,
10736 task_attr, retry_count, timeout,
10737 arglist & CAM_ARG_VERBOSE,
10738 arglist & CAM_ARG_ERR_RECOVER);
10740 case CAM_CMD_ATTRIB:
10741 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10742 task_attr, retry_count, timeout,
10743 arglist & CAM_ARG_VERBOSE,
10744 arglist & CAM_ARG_ERR_RECOVER);
10746 case CAM_CMD_OPCODES:
10747 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10748 task_attr, retry_count, timeout,
10749 arglist & CAM_ARG_VERBOSE);
10751 case CAM_CMD_REPROBE:
10752 error = reprobe(cam_dev);
10755 error = zone(cam_dev, argc, argv, combinedopt,
10756 task_attr, retry_count, timeout,
10757 arglist & CAM_ARG_VERBOSE);
10760 error = epc(cam_dev, argc, argv, combinedopt,
10761 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10763 case CAM_CMD_TIMESTAMP:
10764 error = timestamp(cam_dev, argc, argv, combinedopt,
10765 task_attr, retry_count, timeout,
10766 arglist & CAM_ARG_VERBOSE);
10768 case CAM_CMD_USAGE:
10777 if (cam_dev != NULL)
10778 cam_close_device(cam_dev);