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>
55 #include <cam/cam_debug.h>
56 #include <cam/cam_ccb.h>
57 #include <cam/scsi/scsi_all.h>
58 #include <cam/scsi/scsi_da.h>
59 #include <cam/scsi/scsi_pass.h>
60 #include <cam/scsi/scsi_message.h>
61 #include <cam/scsi/smp_all.h>
62 #include <cam/ata/ata_all.h>
63 #include <cam/mmc/mmc_all.h>
65 #include "camcontrol.h"
67 #include "nvmecontrol_ext.h"
71 CAM_CMD_NONE = 0x00000000,
72 CAM_CMD_DEVLIST = 0x00000001,
73 CAM_CMD_TUR = 0x00000002,
74 CAM_CMD_INQUIRY = 0x00000003,
75 CAM_CMD_STARTSTOP = 0x00000004,
76 CAM_CMD_RESCAN = 0x00000005,
77 CAM_CMD_READ_DEFECTS = 0x00000006,
78 CAM_CMD_MODE_PAGE = 0x00000007,
79 CAM_CMD_SCSI_CMD = 0x00000008,
80 CAM_CMD_DEVTREE = 0x00000009,
81 CAM_CMD_USAGE = 0x0000000a,
82 CAM_CMD_DEBUG = 0x0000000b,
83 CAM_CMD_RESET = 0x0000000c,
84 CAM_CMD_FORMAT = 0x0000000d,
85 CAM_CMD_TAG = 0x0000000e,
86 CAM_CMD_RATE = 0x0000000f,
87 CAM_CMD_DETACH = 0x00000010,
88 CAM_CMD_REPORTLUNS = 0x00000011,
89 CAM_CMD_READCAP = 0x00000012,
90 CAM_CMD_IDENTIFY = 0x00000013,
91 CAM_CMD_IDLE = 0x00000014,
92 CAM_CMD_STANDBY = 0x00000015,
93 CAM_CMD_SLEEP = 0x00000016,
94 CAM_CMD_SMP_CMD = 0x00000017,
95 CAM_CMD_SMP_RG = 0x00000018,
96 CAM_CMD_SMP_PC = 0x00000019,
97 CAM_CMD_SMP_PHYLIST = 0x0000001a,
98 CAM_CMD_SMP_MANINFO = 0x0000001b,
99 CAM_CMD_DOWNLOAD_FW = 0x0000001c,
100 CAM_CMD_SECURITY = 0x0000001d,
101 CAM_CMD_HPA = 0x0000001e,
102 CAM_CMD_SANITIZE = 0x0000001f,
103 CAM_CMD_PERSIST = 0x00000020,
104 CAM_CMD_APM = 0x00000021,
105 CAM_CMD_AAM = 0x00000022,
106 CAM_CMD_ATTRIB = 0x00000023,
107 CAM_CMD_OPCODES = 0x00000024,
108 CAM_CMD_REPROBE = 0x00000025,
109 CAM_CMD_ZONE = 0x00000026,
110 CAM_CMD_EPC = 0x00000027,
111 CAM_CMD_TIMESTAMP = 0x00000028,
112 CAM_CMD_MMCSD_CMD = 0x00000029,
113 CAM_CMD_POWER_MODE = 0x0000002a,
114 CAM_CMD_DEVTYPE = 0x0000002b,
115 CAM_CMD_AMA = 0x0000002c,
119 CAM_ARG_NONE = 0x00000000,
120 CAM_ARG_VERBOSE = 0x00000001,
121 CAM_ARG_DEVICE = 0x00000002,
122 CAM_ARG_BUS = 0x00000004,
123 CAM_ARG_TARGET = 0x00000008,
124 CAM_ARG_LUN = 0x00000010,
125 CAM_ARG_EJECT = 0x00000020,
126 CAM_ARG_UNIT = 0x00000040,
127 CAM_ARG_FORMAT_BLOCK = 0x00000080,
128 CAM_ARG_FORMAT_BFI = 0x00000100,
129 CAM_ARG_FORMAT_PHYS = 0x00000200,
130 CAM_ARG_PLIST = 0x00000400,
131 CAM_ARG_GLIST = 0x00000800,
132 CAM_ARG_GET_SERIAL = 0x00001000,
133 CAM_ARG_GET_STDINQ = 0x00002000,
134 CAM_ARG_GET_XFERRATE = 0x00004000,
135 CAM_ARG_INQ_MASK = 0x00007000,
136 CAM_ARG_TIMEOUT = 0x00020000,
137 CAM_ARG_CMD_IN = 0x00040000,
138 CAM_ARG_CMD_OUT = 0x00080000,
139 CAM_ARG_ERR_RECOVER = 0x00200000,
140 CAM_ARG_RETRIES = 0x00400000,
141 CAM_ARG_START_UNIT = 0x00800000,
142 CAM_ARG_DEBUG_INFO = 0x01000000,
143 CAM_ARG_DEBUG_TRACE = 0x02000000,
144 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
145 CAM_ARG_DEBUG_CDB = 0x08000000,
146 CAM_ARG_DEBUG_XPT = 0x10000000,
147 CAM_ARG_DEBUG_PERIPH = 0x20000000,
148 CAM_ARG_DEBUG_PROBE = 0x40000000,
151 struct camcontrol_opts {
159 struct ata_res_pass16 {
160 u_int16_t reserved[5];
163 u_int8_t sector_count_exp;
164 u_int8_t sector_count;
165 u_int8_t lba_low_exp;
167 u_int8_t lba_mid_exp;
169 u_int8_t lba_high_exp;
175 struct ata_set_max_pwd
178 u_int8_t password[32];
179 u_int16_t reserved2[239];
182 static struct scsi_nv task_attrs[] = {
183 { "simple", MSG_SIMPLE_Q_TAG },
184 { "head", MSG_HEAD_OF_Q_TAG },
185 { "ordered", MSG_ORDERED_Q_TAG },
186 { "iwr", MSG_IGN_WIDE_RESIDUE },
187 { "aca", MSG_ACA_TASK }
190 static const char scsicmd_opts[] = "a:c:dfi:o:r";
191 static const char readdefect_opts[] = "f:GPqsS:X";
192 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
193 static const char smprg_opts[] = "l";
194 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
195 static const char smpphylist_opts[] = "lq";
199 static struct camcontrol_opts option_table[] = {
201 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
202 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
203 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
204 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
205 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
206 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
207 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
208 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
209 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHlNqs"},
210 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
211 #endif /* MINIMALISTIC */
212 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
213 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
215 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
216 {"mmcsdcmd", CAM_CMD_MMCSD_CMD, CAM_ARG_NONE, "c:a:f:Wb:l:41S:I"},
217 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
218 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
219 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
220 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
221 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
222 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
223 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
224 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
225 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
226 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
227 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
228 #endif /* MINIMALISTIC */
229 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
230 {"devtype", CAM_CMD_DEVTYPE, CAM_ARG_NONE, ""},
232 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
233 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "6bdelm:DLP:"},
234 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
235 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
236 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
237 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
238 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
239 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
240 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
241 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
242 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
243 {"powermode", CAM_CMD_POWER_MODE, CAM_ARG_NONE, ""},
244 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
245 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
246 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
247 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
248 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
249 {"ama", CAM_CMD_AMA, CAM_ARG_NONE, "fqs:"},
250 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
251 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
252 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
253 {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
254 {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
255 {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
256 #endif /* MINIMALISTIC */
257 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
258 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
259 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
264 struct device_match_result dev_match;
266 struct periph_match_result *periph_matches;
267 struct scsi_vpd_device_id *device_id;
269 STAILQ_ENTRY(cam_devitem) links;
273 STAILQ_HEAD(, cam_devitem) dev_queue;
277 static cam_cmdmask cmdlist;
278 static cam_argmask arglist;
280 static const char *devtype_names[] = {
290 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
291 uint32_t *cmdnum, cam_argmask *argnum,
292 const char **subopt);
294 static int getdevlist(struct cam_device *device);
295 #endif /* MINIMALISTIC */
296 static int getdevtree(int argc, char **argv, char *combinedopt);
297 static int getdevtype(struct cam_device *device);
298 static int print_dev_scsi(struct device_match_result *dev_result, char *tmpstr);
299 static int print_dev_ata(struct device_match_result *dev_result, char *tmpstr);
300 static int print_dev_semb(struct device_match_result *dev_result, char *tmpstr);
301 static int print_dev_mmcsd(struct device_match_result *dev_result,
304 static int print_dev_nvme(struct device_match_result *dev_result, char *tmpstr);
307 static int testunitready(struct cam_device *device, int task_attr,
308 int retry_count, int timeout, int quiet);
309 static int scsistart(struct cam_device *device, int startstop, int loadeject,
310 int task_attr, int retry_count, int timeout);
311 static int scsiinquiry(struct cam_device *device, int task_attr,
312 int retry_count, int timeout);
313 static int scsiserial(struct cam_device *device, int task_attr,
314 int retry_count, int timeout);
315 #endif /* MINIMALISTIC */
316 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
317 lun_id_t *lun, cam_argmask *arglst);
318 static int reprobe(struct cam_device *device);
319 static int dorescan_or_reset(int argc, char **argv, int rescan);
320 static int rescan_or_reset_bus(path_id_t bus, int rescan);
321 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
322 lun_id_t lun, int scan);
324 static int readdefects(struct cam_device *device, int argc, char **argv,
325 char *combinedopt, int task_attr, int retry_count,
327 static void modepage(struct cam_device *device, int argc, char **argv,
328 char *combinedopt, int task_attr, int retry_count,
330 static int scsicmd(struct cam_device *device, int argc, char **argv,
331 char *combinedopt, int task_attr, int retry_count,
333 static int smpcmd(struct cam_device *device, int argc, char **argv,
334 char *combinedopt, int retry_count, int timeout);
335 static int mmcsdcmd(struct cam_device *device, int argc, char **argv,
336 char *combinedopt, int retry_count, int timeout);
337 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
338 char *combinedopt, int retry_count, int timeout);
339 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
340 char *combinedopt, int retry_count, int timeout);
341 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
342 char *combinedopt, int retry_count, int timeout);
343 static int getdevid(struct cam_devitem *item);
344 static int buildbusdevlist(struct cam_devlist *devlist);
345 static void freebusdevlist(struct cam_devlist *devlist);
346 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
348 static int smpphylist(struct cam_device *device, int argc, char **argv,
349 char *combinedopt, int retry_count, int timeout);
350 static int tagcontrol(struct cam_device *device, int argc, char **argv,
352 static void cts_print(struct cam_device *device,
353 struct ccb_trans_settings *cts);
354 static void cpi_print(struct ccb_pathinq *cpi);
355 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
356 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
357 static int get_print_cts(struct cam_device *device, int user_settings,
358 int quiet, struct ccb_trans_settings *cts);
359 static int ratecontrol(struct cam_device *device, int task_attr,
360 int retry_count, int timeout, int argc, char **argv,
362 static int scsiformat(struct cam_device *device, int argc, char **argv,
363 char *combinedopt, int task_attr, int retry_count,
365 static int sanitize(struct cam_device *device, int argc, char **argv,
366 char *combinedopt, int task_attr, int retry_count,
368 static int scsireportluns(struct cam_device *device, int argc, char **argv,
369 char *combinedopt, int task_attr, int retry_count,
371 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
372 char *combinedopt, int task_attr, int retry_count,
374 static int atapm(struct cam_device *device, int argc, char **argv,
375 char *combinedopt, int retry_count, int timeout);
376 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
377 int argc, char **argv, char *combinedopt);
378 static int atahpa(struct cam_device *device, int retry_count, int timeout,
379 int argc, char **argv, char *combinedopt);
380 static int ataama(struct cam_device *device, int retry_count, int timeout,
381 int argc, char **argv, char *combinedopt);
382 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
383 int sa_set, int req_sa, uint8_t *buf,
385 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
387 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
388 char *combinedopt, int task_attr, int retry_count,
389 int timeout, int verbose);
391 #endif /* MINIMALISTIC */
393 #define min(a,b) (((a)<(b))?(a):(b))
396 #define max(a,b) (((a)>(b))?(a):(b))
400 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
401 cam_argmask *argnum, const char **subopt)
403 struct camcontrol_opts *opts;
406 for (opts = table; (opts != NULL) && (opts->optname != NULL);
408 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
409 *cmdnum = opts->cmdnum;
410 *argnum = opts->argnum;
411 *subopt = opts->subopt;
412 if (++num_matches > 1)
413 return (CC_OR_AMBIGUOUS);
418 return (CC_OR_FOUND);
420 return (CC_OR_NOT_FOUND);
425 getdevlist(struct cam_device *device)
431 ccb = cam_getccb(device);
433 ccb->ccb_h.func_code = XPT_GDEVLIST;
434 ccb->ccb_h.flags = CAM_DIR_NONE;
435 ccb->ccb_h.retry_count = 1;
437 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
438 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
439 if (cam_send_ccb(device, ccb) < 0) {
440 warn("error getting device list");
447 switch (ccb->cgdl.status) {
448 case CAM_GDEVLIST_MORE_DEVS:
449 strcpy(status, "MORE");
451 case CAM_GDEVLIST_LAST_DEVICE:
452 strcpy(status, "LAST");
454 case CAM_GDEVLIST_LIST_CHANGED:
455 strcpy(status, "CHANGED");
457 case CAM_GDEVLIST_ERROR:
458 strcpy(status, "ERROR");
463 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
464 ccb->cgdl.periph_name,
465 ccb->cgdl.unit_number,
466 ccb->cgdl.generation,
471 * If the list has changed, we need to start over from the
474 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
482 #endif /* MINIMALISTIC */
485 getdevtree(int argc, char **argv, char *combinedopt)
496 while ((c = getopt(argc, argv, combinedopt)) != -1) {
499 if ((arglist & CAM_ARG_VERBOSE) == 0)
507 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
508 warn("couldn't open %s", XPT_DEVICE);
512 bzero(&ccb, sizeof(union ccb));
514 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
515 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
516 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
518 ccb.ccb_h.func_code = XPT_DEV_MATCH;
519 bufsize = sizeof(struct dev_match_result) * 100;
520 ccb.cdm.match_buf_len = bufsize;
521 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
522 if (ccb.cdm.matches == NULL) {
523 warnx("can't malloc memory for matches");
527 ccb.cdm.num_matches = 0;
530 * We fetch all nodes, since we display most of them in the default
531 * case, and all in the verbose case.
533 ccb.cdm.num_patterns = 0;
534 ccb.cdm.pattern_buf_len = 0;
537 * We do the ioctl multiple times if necessary, in case there are
538 * more than 100 nodes in the EDT.
541 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
542 warn("error sending CAMIOCOMMAND ioctl");
547 if ((ccb.ccb_h.status != CAM_REQ_CMP)
548 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
549 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
550 warnx("got CAM error %#x, CDM error %d\n",
551 ccb.ccb_h.status, ccb.cdm.status);
556 for (i = 0; i < ccb.cdm.num_matches; i++) {
557 switch (ccb.cdm.matches[i].type) {
558 case DEV_MATCH_BUS: {
559 struct bus_match_result *bus_result;
562 * Only print the bus information if the
563 * user turns on the verbose flag.
565 if ((busonly == 0) &&
566 (arglist & CAM_ARG_VERBOSE) == 0)
570 &ccb.cdm.matches[i].result.bus_result;
573 fprintf(stdout, ")\n");
577 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
579 bus_result->dev_name,
580 bus_result->unit_number,
582 (busonly ? "" : ":"));
585 case DEV_MATCH_DEVICE: {
586 struct device_match_result *dev_result;
593 &ccb.cdm.matches[i].result.device_result;
595 if ((dev_result->flags
596 & DEV_RESULT_UNCONFIGURED)
597 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
603 if (dev_result->protocol == PROTO_SCSI) {
604 if (print_dev_scsi(dev_result,
609 } else if (dev_result->protocol == PROTO_ATA ||
610 dev_result->protocol == PROTO_SATAPM) {
611 if (print_dev_ata(dev_result,
616 } else if (dev_result->protocol == PROTO_MMCSD){
617 if (print_dev_mmcsd(dev_result,
622 } else if (dev_result->protocol == PROTO_SEMB) {
623 if (print_dev_semb(dev_result,
629 } else if (dev_result->protocol == PROTO_NVME) {
630 if (print_dev_nvme(dev_result,
637 sprintf(tmpstr, "<>");
640 fprintf(stdout, ")\n");
644 fprintf(stdout, "%-33s at scbus%d "
645 "target %d lun %jx (",
648 dev_result->target_id,
649 (uintmax_t)dev_result->target_lun);
655 case DEV_MATCH_PERIPH: {
656 struct periph_match_result *periph_result;
659 &ccb.cdm.matches[i].result.periph_result;
661 if (busonly || skip_device != 0)
665 fprintf(stdout, ",");
667 fprintf(stdout, "%s%d",
668 periph_result->periph_name,
669 periph_result->unit_number);
675 fprintf(stdout, "unknown match type\n");
680 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
681 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
684 fprintf(stdout, ")\n");
692 getdevtype(struct cam_device *cam_dev)
694 camcontrol_devtype dt;
698 * Get the device type and report it, request no I/O be done to do this.
700 error = get_device_type(cam_dev, -1, 0, 0, &dt);
701 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
702 fprintf(stdout, "illegal\n");
705 fprintf(stdout, "%s\n", devtype_names[dt]);
710 print_dev_scsi(struct device_match_result *dev_result, char *tmpstr)
712 char vendor[16], product[48], revision[16];
714 cam_strvis(vendor, dev_result->inq_data.vendor,
715 sizeof(dev_result->inq_data.vendor), sizeof(vendor));
716 cam_strvis(product, dev_result->inq_data.product,
717 sizeof(dev_result->inq_data.product), sizeof(product));
718 cam_strvis(revision, dev_result->inq_data.revision,
719 sizeof(dev_result->inq_data.revision), sizeof(revision));
720 sprintf(tmpstr, "<%s %s %s>", vendor, product, revision);
726 print_dev_ata(struct device_match_result *dev_result, char *tmpstr)
728 char product[48], revision[16];
730 cam_strvis(product, dev_result->ident_data.model,
731 sizeof(dev_result->ident_data.model), sizeof(product));
732 cam_strvis(revision, dev_result->ident_data.revision,
733 sizeof(dev_result->ident_data.revision), sizeof(revision));
734 sprintf(tmpstr, "<%s %s>", product, revision);
740 print_dev_semb(struct device_match_result *dev_result, char *tmpstr)
742 struct sep_identify_data *sid;
743 char vendor[16], product[48], revision[16], fw[5];
745 sid = (struct sep_identify_data *)&dev_result->ident_data;
746 cam_strvis(vendor, sid->vendor_id,
747 sizeof(sid->vendor_id), sizeof(vendor));
748 cam_strvis(product, sid->product_id,
749 sizeof(sid->product_id), sizeof(product));
750 cam_strvis(revision, sid->product_rev,
751 sizeof(sid->product_rev), sizeof(revision));
752 cam_strvis(fw, sid->firmware_rev,
753 sizeof(sid->firmware_rev), sizeof(fw));
754 sprintf(tmpstr, "<%s %s %s %s>", vendor, product, revision, fw);
760 print_dev_mmcsd(struct device_match_result *dev_result, char *tmpstr)
763 struct ccb_dev_advinfo *advi;
764 struct cam_device *dev;
765 struct mmc_params mmc_ident_data;
767 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
768 dev_result->target_lun, O_RDWR, NULL);
770 warnx("%s", cam_errbuf);
774 ccb = cam_getccb(dev);
776 warnx("couldn't allocate CCB");
777 cam_close_device(dev);
782 advi->ccb_h.flags = CAM_DIR_IN;
783 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
784 advi->flags = CDAI_FLAG_NONE;
785 advi->buftype = CDAI_TYPE_MMC_PARAMS;
786 advi->bufsiz = sizeof(struct mmc_params);
787 advi->buf = (uint8_t *)&mmc_ident_data;
789 if (cam_send_ccb(dev, ccb) < 0) {
790 warn("error sending XPT_DEV_ADVINFO CCB");
792 cam_close_device(dev);
796 if (strlen(mmc_ident_data.model) > 0) {
797 sprintf(tmpstr, "<%s>", mmc_ident_data.model);
799 sprintf(tmpstr, "<%s card>",
800 mmc_ident_data.card_features &
801 CARD_FEATURE_SDIO ? "SDIO" : "unknown");
805 cam_close_device(dev);
811 nvme_get_cdata(struct cam_device *dev, struct nvme_controller_data *cdata)
814 struct ccb_dev_advinfo *advi;
816 ccb = cam_getccb(dev);
818 warnx("couldn't allocate CCB");
819 cam_close_device(dev);
824 advi->ccb_h.flags = CAM_DIR_IN;
825 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
826 advi->flags = CDAI_FLAG_NONE;
827 advi->buftype = CDAI_TYPE_NVME_CNTRL;
828 advi->bufsiz = sizeof(struct nvme_controller_data);
829 advi->buf = (uint8_t *)cdata;
831 if (cam_send_ccb(dev, ccb) < 0) {
832 warn("error sending XPT_DEV_ADVINFO CCB");
834 cam_close_device(dev);
837 if (advi->ccb_h.status != CAM_REQ_CMP) {
838 warnx("got CAM error %#x", advi->ccb_h.status);
840 cam_close_device(dev);
848 print_dev_nvme(struct device_match_result *dev_result, char *tmpstr)
850 struct cam_device *dev;
851 struct nvme_controller_data cdata;
852 char vendor[64], product[64];
854 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
855 dev_result->target_lun, O_RDWR, NULL);
857 warnx("%s", cam_errbuf);
861 if (nvme_get_cdata(dev, &cdata))
864 cam_strvis(vendor, cdata.mn, sizeof(cdata.mn), sizeof(vendor));
865 cam_strvis(product, cdata.fr, sizeof(cdata.fr), sizeof(product));
866 sprintf(tmpstr, "<%s %s>", vendor, product);
868 cam_close_device(dev);
875 testunitready(struct cam_device *device, int task_attr, int retry_count,
876 int timeout, int quiet)
881 ccb = cam_getccb(device);
883 scsi_test_unit_ready(&ccb->csio,
884 /* retries */ retry_count,
886 /* tag_action */ task_attr,
887 /* sense_len */ SSD_FULL_SIZE,
888 /* timeout */ timeout ? timeout : 5000);
890 /* Disable freezing the device queue */
891 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
893 if (arglist & CAM_ARG_ERR_RECOVER)
894 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
896 if (cam_send_ccb(device, ccb) < 0) {
898 warn("error sending TEST UNIT READY command");
903 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
905 fprintf(stdout, "Unit is ready\n");
908 fprintf(stdout, "Unit is not ready\n");
911 if (arglist & CAM_ARG_VERBOSE) {
912 cam_error_print(device, ccb, CAM_ESF_ALL,
913 CAM_EPF_ALL, stderr);
923 scsistart(struct cam_device *device, int startstop, int loadeject,
924 int task_attr, int retry_count, int timeout)
929 ccb = cam_getccb(device);
932 * If we're stopping, send an ordered tag so the drive in question
933 * will finish any previously queued writes before stopping. If
934 * the device isn't capable of tagged queueing, or if tagged
935 * queueing is turned off, the tag action is a no-op. We override
936 * the default simple tag, although this also has the effect of
937 * overriding the user's wishes if he wanted to specify a simple
941 && (task_attr == MSG_SIMPLE_Q_TAG))
942 task_attr = MSG_ORDERED_Q_TAG;
944 scsi_start_stop(&ccb->csio,
945 /* retries */ retry_count,
947 /* tag_action */ task_attr,
948 /* start/stop */ startstop,
949 /* load_eject */ loadeject,
951 /* sense_len */ SSD_FULL_SIZE,
952 /* timeout */ timeout ? timeout : 120000);
954 /* Disable freezing the device queue */
955 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
957 if (arglist & CAM_ARG_ERR_RECOVER)
958 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
960 if (cam_send_ccb(device, ccb) < 0) {
961 warn("error sending START STOP UNIT command");
966 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
968 fprintf(stdout, "Unit started successfully");
970 fprintf(stdout,", Media loaded\n");
972 fprintf(stdout,"\n");
974 fprintf(stdout, "Unit stopped successfully");
976 fprintf(stdout, ", Media ejected\n");
978 fprintf(stdout, "\n");
984 "Error received from start unit command\n");
987 "Error received from stop unit command\n");
989 if (arglist & CAM_ARG_VERBOSE) {
990 cam_error_print(device, ccb, CAM_ESF_ALL,
991 CAM_EPF_ALL, stderr);
1001 scsidoinquiry(struct cam_device *device, int argc, char **argv,
1002 char *combinedopt, int task_attr, int retry_count, int timeout)
1007 while ((c = getopt(argc, argv, combinedopt)) != -1) {
1010 arglist |= CAM_ARG_GET_STDINQ;
1013 arglist |= CAM_ARG_GET_XFERRATE;
1016 arglist |= CAM_ARG_GET_SERIAL;
1024 * If the user didn't specify any inquiry options, he wants all of
1027 if ((arglist & CAM_ARG_INQ_MASK) == 0)
1028 arglist |= CAM_ARG_INQ_MASK;
1030 if (arglist & CAM_ARG_GET_STDINQ)
1031 error = scsiinquiry(device, task_attr, retry_count, timeout);
1036 if (arglist & CAM_ARG_GET_SERIAL)
1037 scsiserial(device, task_attr, retry_count, timeout);
1039 if (arglist & CAM_ARG_GET_XFERRATE)
1040 error = camxferrate(device);
1046 scsiinquiry(struct cam_device *device, int task_attr, int retry_count,
1050 struct scsi_inquiry_data *inq_buf;
1053 ccb = cam_getccb(device);
1056 warnx("couldn't allocate CCB");
1060 /* cam_getccb cleans up the header, caller has to zero the payload */
1061 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1063 inq_buf = (struct scsi_inquiry_data *)malloc(
1064 sizeof(struct scsi_inquiry_data));
1066 if (inq_buf == NULL) {
1068 warnx("can't malloc memory for inquiry\n");
1071 bzero(inq_buf, sizeof(*inq_buf));
1074 * Note that although the size of the inquiry buffer is the full
1075 * 256 bytes specified in the SCSI spec, we only tell the device
1076 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
1077 * two reasons for this:
1079 * - The SCSI spec says that when a length field is only 1 byte,
1080 * a value of 0 will be interpreted as 256. Therefore
1081 * scsi_inquiry() will convert an inq_len (which is passed in as
1082 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
1083 * to 0. Evidently, very few devices meet the spec in that
1084 * regard. Some devices, like many Seagate disks, take the 0 as
1085 * 0, and don't return any data. One Pioneer DVD-R drive
1086 * returns more data than the command asked for.
1088 * So, since there are numerous devices that just don't work
1089 * right with the full inquiry size, we don't send the full size.
1091 * - The second reason not to use the full inquiry data length is
1092 * that we don't need it here. The only reason we issue a
1093 * standard inquiry is to get the vendor name, device name,
1094 * and revision so scsi_print_inquiry() can print them.
1096 * If, at some point in the future, more inquiry data is needed for
1097 * some reason, this code should use a procedure similar to the
1098 * probe code. i.e., issue a short inquiry, and determine from
1099 * the additional length passed back from the device how much
1100 * inquiry data the device supports. Once the amount the device
1101 * supports is determined, issue an inquiry for that amount and no
1106 scsi_inquiry(&ccb->csio,
1107 /* retries */ retry_count,
1109 /* tag_action */ task_attr,
1110 /* inq_buf */ (u_int8_t *)inq_buf,
1111 /* inq_len */ SHORT_INQUIRY_LENGTH,
1114 /* sense_len */ SSD_FULL_SIZE,
1115 /* timeout */ timeout ? timeout : 5000);
1117 /* Disable freezing the device queue */
1118 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1120 if (arglist & CAM_ARG_ERR_RECOVER)
1121 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1123 if (cam_send_ccb(device, ccb) < 0) {
1124 warn("error sending INQUIRY command");
1129 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1132 if (arglist & CAM_ARG_VERBOSE) {
1133 cam_error_print(device, ccb, CAM_ESF_ALL,
1134 CAM_EPF_ALL, stderr);
1145 fprintf(stdout, "%s%d: ", device->device_name,
1146 device->dev_unit_num);
1147 scsi_print_inquiry(inq_buf);
1155 scsiserial(struct cam_device *device, int task_attr, int retry_count,
1159 struct scsi_vpd_unit_serial_number *serial_buf;
1160 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
1163 ccb = cam_getccb(device);
1166 warnx("couldn't allocate CCB");
1170 /* cam_getccb cleans up the header, caller has to zero the payload */
1171 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1173 serial_buf = (struct scsi_vpd_unit_serial_number *)
1174 malloc(sizeof(*serial_buf));
1176 if (serial_buf == NULL) {
1178 warnx("can't malloc memory for serial number");
1182 scsi_inquiry(&ccb->csio,
1183 /*retries*/ retry_count,
1185 /* tag_action */ task_attr,
1186 /* inq_buf */ (u_int8_t *)serial_buf,
1187 /* inq_len */ sizeof(*serial_buf),
1189 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
1190 /* sense_len */ SSD_FULL_SIZE,
1191 /* timeout */ timeout ? timeout : 5000);
1193 /* Disable freezing the device queue */
1194 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1196 if (arglist & CAM_ARG_ERR_RECOVER)
1197 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1199 if (cam_send_ccb(device, ccb) < 0) {
1200 warn("error sending INQUIRY command");
1206 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1209 if (arglist & CAM_ARG_VERBOSE) {
1210 cam_error_print(device, ccb, CAM_ESF_ALL,
1211 CAM_EPF_ALL, stderr);
1222 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1223 serial_num[serial_buf->length] = '\0';
1225 if ((arglist & CAM_ARG_GET_STDINQ)
1226 || (arglist & CAM_ARG_GET_XFERRATE))
1227 fprintf(stdout, "%s%d: Serial Number ",
1228 device->device_name, device->dev_unit_num);
1230 fprintf(stdout, "%.60s\n", serial_num);
1238 camxferrate(struct cam_device *device)
1240 struct ccb_pathinq cpi;
1242 u_int32_t speed = 0;
1247 if ((retval = get_cpi(device, &cpi)) != 0)
1250 ccb = cam_getccb(device);
1253 warnx("couldn't allocate CCB");
1257 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
1259 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1260 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1262 if (((retval = cam_send_ccb(device, ccb)) < 0)
1263 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1264 const char error_string[] = "error getting transfer settings";
1269 warnx(error_string);
1271 if (arglist & CAM_ARG_VERBOSE)
1272 cam_error_print(device, ccb, CAM_ESF_ALL,
1273 CAM_EPF_ALL, stderr);
1277 goto xferrate_bailout;
1281 speed = cpi.base_transfer_speed;
1283 if (ccb->cts.transport == XPORT_SPI) {
1284 struct ccb_trans_settings_spi *spi =
1285 &ccb->cts.xport_specific.spi;
1287 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1288 freq = scsi_calc_syncsrate(spi->sync_period);
1291 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1292 speed *= (0x01 << spi->bus_width);
1294 } else if (ccb->cts.transport == XPORT_FC) {
1295 struct ccb_trans_settings_fc *fc =
1296 &ccb->cts.xport_specific.fc;
1298 if (fc->valid & CTS_FC_VALID_SPEED)
1299 speed = fc->bitrate;
1300 } else if (ccb->cts.transport == XPORT_SAS) {
1301 struct ccb_trans_settings_sas *sas =
1302 &ccb->cts.xport_specific.sas;
1304 if (sas->valid & CTS_SAS_VALID_SPEED)
1305 speed = sas->bitrate;
1306 } else if (ccb->cts.transport == XPORT_ATA) {
1307 struct ccb_trans_settings_pata *pata =
1308 &ccb->cts.xport_specific.ata;
1310 if (pata->valid & CTS_ATA_VALID_MODE)
1311 speed = ata_mode2speed(pata->mode);
1312 } else if (ccb->cts.transport == XPORT_SATA) {
1313 struct ccb_trans_settings_sata *sata =
1314 &ccb->cts.xport_specific.sata;
1316 if (sata->valid & CTS_SATA_VALID_REVISION)
1317 speed = ata_revision2speed(sata->revision);
1322 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1323 device->device_name, device->dev_unit_num,
1326 fprintf(stdout, "%s%d: %dKB/s transfers",
1327 device->device_name, device->dev_unit_num,
1331 if (ccb->cts.transport == XPORT_SPI) {
1332 struct ccb_trans_settings_spi *spi =
1333 &ccb->cts.xport_specific.spi;
1335 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1336 && (spi->sync_offset != 0))
1337 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1338 freq % 1000, spi->sync_offset);
1340 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1341 && (spi->bus_width > 0)) {
1342 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1343 && (spi->sync_offset != 0)) {
1344 fprintf(stdout, ", ");
1346 fprintf(stdout, " (");
1348 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1349 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1350 && (spi->sync_offset != 0)) {
1351 fprintf(stdout, ")");
1353 } else if (ccb->cts.transport == XPORT_ATA) {
1354 struct ccb_trans_settings_pata *pata =
1355 &ccb->cts.xport_specific.ata;
1358 if (pata->valid & CTS_ATA_VALID_MODE)
1359 printf("%s, ", ata_mode2string(pata->mode));
1360 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1361 printf("ATAPI %dbytes, ", pata->atapi);
1362 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1363 printf("PIO %dbytes", pata->bytecount);
1365 } else if (ccb->cts.transport == XPORT_SATA) {
1366 struct ccb_trans_settings_sata *sata =
1367 &ccb->cts.xport_specific.sata;
1370 if (sata->valid & CTS_SATA_VALID_REVISION)
1371 printf("SATA %d.x, ", sata->revision);
1374 if (sata->valid & CTS_SATA_VALID_MODE)
1375 printf("%s, ", ata_mode2string(sata->mode));
1376 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1377 printf("ATAPI %dbytes, ", sata->atapi);
1378 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1379 printf("PIO %dbytes", sata->bytecount);
1383 if (ccb->cts.protocol == PROTO_SCSI) {
1384 struct ccb_trans_settings_scsi *scsi =
1385 &ccb->cts.proto_specific.scsi;
1386 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1387 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1388 fprintf(stdout, ", Command Queueing Enabled");
1393 fprintf(stdout, "\n");
1403 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1405 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1406 ((u_int32_t)parm->lba_size_2 << 16);
1408 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1409 ((u_int64_t)parm->lba_size48_2 << 16) |
1410 ((u_int64_t)parm->lba_size48_3 << 32) |
1411 ((u_int64_t)parm->lba_size48_4 << 48);
1415 "Support Enabled Value\n");
1418 printf("Host Protected Area (HPA) ");
1419 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1420 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1421 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1424 printf("HPA - Security ");
1425 if (parm->support.command2 & ATA_SUPPORT_MAXSECURITY)
1426 printf("yes %s\n", (parm->enabled.command2 &
1427 ATA_SUPPORT_MAXSECURITY) ? "yes" : "no ");
1436 ataama_print(struct ata_params *parm, u_int64_t nativesize, int header)
1438 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1439 ((u_int32_t)parm->lba_size_2 << 16);
1441 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1442 ((u_int64_t)parm->lba_size48_2 << 16) |
1443 ((u_int64_t)parm->lba_size48_3 << 32) |
1444 ((u_int64_t)parm->lba_size48_4 << 48);
1448 "Support Enabled Value\n");
1451 printf("Accessible Max Address Config ");
1452 if (parm->support2 & ATA_SUPPORT_AMAX_ADDR) {
1453 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1454 printf("yes %s %ju/%ju\n",
1455 (nativesize > lba) ? "yes" : "no ", lba, nativesize);
1462 atasata(struct ata_params *parm)
1466 if (parm->satacapabilities != 0xffff &&
1467 parm->satacapabilities != 0x0000)
1474 atacapprint(struct ata_params *parm)
1477 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1478 ((u_int32_t)parm->lba_size_2 << 16);
1480 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1481 ((u_int64_t)parm->lba_size48_2 << 16) |
1482 ((u_int64_t)parm->lba_size48_3 << 32) |
1483 ((u_int64_t)parm->lba_size48_4 << 48);
1486 printf("protocol ");
1487 proto = (parm->config == ATA_PROTO_CFA) ? "CFA" :
1488 (parm->config & ATA_PROTO_ATAPI) ? "ATAPI" : "ATA";
1489 if (ata_version(parm->version_major) == 0) {
1490 printf("%s", proto);
1491 } else if (ata_version(parm->version_major) <= 7) {
1492 printf("%s-%d", proto,
1493 ata_version(parm->version_major));
1494 } else if (ata_version(parm->version_major) == 8) {
1495 printf("%s8-ACS", proto);
1498 ata_version(parm->version_major) - 7, proto);
1500 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1501 if (parm->satacapabilities & ATA_SATA_GEN3)
1502 printf(" SATA 3.x\n");
1503 else if (parm->satacapabilities & ATA_SATA_GEN2)
1504 printf(" SATA 2.x\n");
1505 else if (parm->satacapabilities & ATA_SATA_GEN1)
1506 printf(" SATA 1.x\n");
1512 printf("device model %.40s\n", parm->model);
1513 printf("firmware revision %.8s\n", parm->revision);
1514 printf("serial number %.20s\n", parm->serial);
1515 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1516 printf("WWN %04x%04x%04x%04x\n",
1517 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1519 printf("additional product id %.8s\n", parm->product_id);
1520 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1521 printf("media serial number %.30s\n",
1522 parm->media_serial);
1525 printf("cylinders %d\n", parm->cylinders);
1526 printf("heads %d\n", parm->heads);
1527 printf("sectors/track %d\n", parm->sectors);
1528 printf("sector size logical %u, physical %lu, offset %lu\n",
1529 ata_logical_sector_size(parm),
1530 (unsigned long)ata_physical_sector_size(parm),
1531 (unsigned long)ata_logical_sector_offset(parm));
1533 if (parm->config == ATA_PROTO_CFA ||
1534 (parm->support.command2 & ATA_SUPPORT_CFA))
1535 printf("CFA supported\n");
1537 printf("LBA%ssupported ",
1538 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1540 printf("%d sectors\n", lbasize);
1544 printf("LBA48%ssupported ",
1545 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1547 printf("%ju sectors\n", (uintmax_t)lbasize48);
1551 printf("PIO supported PIO");
1552 switch (ata_max_pmode(parm)) {
1568 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1569 printf(" w/o IORDY");
1572 printf("DMA%ssupported ",
1573 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1574 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1575 if (parm->mwdmamodes & 0xff) {
1577 if (parm->mwdmamodes & 0x04)
1579 else if (parm->mwdmamodes & 0x02)
1581 else if (parm->mwdmamodes & 0x01)
1585 if ((parm->atavalid & ATA_FLAG_88) &&
1586 (parm->udmamodes & 0xff)) {
1588 if (parm->udmamodes & 0x40)
1590 else if (parm->udmamodes & 0x20)
1592 else if (parm->udmamodes & 0x10)
1594 else if (parm->udmamodes & 0x08)
1596 else if (parm->udmamodes & 0x04)
1598 else if (parm->udmamodes & 0x02)
1600 else if (parm->udmamodes & 0x01)
1607 if (parm->media_rotation_rate == 1) {
1608 printf("media RPM non-rotating\n");
1609 } else if (parm->media_rotation_rate >= 0x0401 &&
1610 parm->media_rotation_rate <= 0xFFFE) {
1611 printf("media RPM %d\n",
1612 parm->media_rotation_rate);
1615 printf("Zoned-Device Commands ");
1616 switch (parm->support3 & ATA_SUPPORT_ZONE_MASK) {
1617 case ATA_SUPPORT_ZONE_DEV_MANAGED:
1618 printf("device managed\n");
1620 case ATA_SUPPORT_ZONE_HOST_AWARE:
1621 printf("host aware\n");
1628 "Support Enabled Value Vendor\n");
1629 printf("read ahead %s %s\n",
1630 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1631 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1632 printf("write cache %s %s\n",
1633 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1634 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1635 printf("flush cache %s %s\n",
1636 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1637 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1638 printf("overlap %s\n",
1639 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1640 printf("Tagged Command Queuing (TCQ) %s %s",
1641 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1642 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1643 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1644 printf(" %d tags\n",
1645 ATA_QUEUE_LEN(parm->queue) + 1);
1648 printf("Native Command Queuing (NCQ) ");
1649 if (atasata(parm) && (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1650 printf("yes %d tags\n",
1651 ATA_QUEUE_LEN(parm->queue) + 1);
1652 printf("NCQ Priority Information %s\n",
1653 parm->satacapabilities & ATA_SUPPORT_NCQ_PRIO ?
1655 printf("NCQ Non-Data Command %s\n",
1656 parm->satacapabilities2 & ATA_SUPPORT_NCQ_NON_DATA ?
1658 printf("NCQ Streaming %s\n",
1659 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1661 printf("Receive & Send FPDMA Queued %s\n",
1662 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1664 printf("NCQ Autosense %s\n",
1665 parm->satasupport & ATA_SUPPORT_NCQ_AUTOSENSE ?
1670 printf("SMART %s %s\n",
1671 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1672 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1673 printf("security %s %s\n",
1674 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1675 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1676 printf("power management %s %s\n",
1677 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1678 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1679 printf("microcode download %s %s\n",
1680 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1681 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1682 printf("advanced power management %s %s",
1683 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1684 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1685 if (parm->support.command2 & ATA_SUPPORT_APM) {
1686 printf(" %d/0x%02X\n",
1687 parm->apm_value & 0xff, parm->apm_value & 0xff);
1690 printf("automatic acoustic management %s %s",
1691 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1692 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1693 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1694 printf(" %d/0x%02X %d/0x%02X\n",
1695 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1696 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1697 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1698 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1701 printf("media status notification %s %s\n",
1702 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1703 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1704 printf("power-up in Standby %s %s\n",
1705 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1706 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1707 printf("write-read-verify %s %s",
1708 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1709 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1710 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1711 printf(" %d/0x%x\n",
1712 parm->wrv_mode, parm->wrv_mode);
1715 printf("unload %s %s\n",
1716 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1717 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1718 printf("general purpose logging %s %s\n",
1719 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1720 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1721 printf("free-fall %s %s\n",
1722 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1723 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1724 printf("sense data reporting %s %s\n",
1725 parm->support2 & ATA_SUPPORT_SENSE_REPORT ? "yes" : "no",
1726 parm->enabled2 & ATA_SUPPORT_SENSE_REPORT ? "yes" : "no");
1727 printf("extended power conditions %s %s\n",
1728 parm->support2 & ATA_SUPPORT_EPC ? "yes" : "no",
1729 parm->enabled2 & ATA_SUPPORT_EPC ? "yes" : "no");
1730 printf("device statistics notification %s %s\n",
1731 parm->support2 & ATA_SUPPORT_DSN ? "yes" : "no",
1732 parm->enabled2 & ATA_SUPPORT_DSN ? "yes" : "no");
1733 printf("Data Set Management (DSM/TRIM) ");
1734 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1736 printf("DSM - max 512byte blocks ");
1737 if (parm->max_dsm_blocks == 0x00)
1738 printf("yes not specified\n");
1741 parm->max_dsm_blocks);
1743 printf("DSM - deterministic read ");
1744 if (parm->support3 & ATA_SUPPORT_DRAT) {
1745 if (parm->support3 & ATA_SUPPORT_RZAT)
1746 printf("yes zeroed\n");
1748 printf("yes any value\n");
1755 printf("encrypts all user data %s\n",
1756 parm->support3 & ATA_ENCRYPTS_ALL_USER_DATA ? "yes" : "no");
1757 printf("Sanitize ");
1758 if (parm->multi & ATA_SUPPORT_SANITIZE) {
1759 printf("yes\t\t%s%s%s\n",
1760 parm->multi & ATA_SUPPORT_BLOCK_ERASE_EXT ? "block, " : "",
1761 parm->multi & ATA_SUPPORT_OVERWRITE_EXT ? "overwrite, " : "",
1762 parm->multi & ATA_SUPPORT_CRYPTO_SCRAMBLE_EXT ? "crypto" : "");
1763 printf("Sanitize - commands allowed %s\n",
1764 parm->multi & ATA_SUPPORT_SANITIZE_ALLOWED ? "yes" : "no");
1765 printf("Sanitize - antifreeze lock %s\n",
1766 parm->multi & ATA_SUPPORT_ANTIFREEZE_LOCK_EXT ? "yes" : "no");
1773 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb)
1775 struct ata_pass_16 *ata_pass_16;
1776 struct ata_cmd ata_cmd;
1778 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1779 ata_cmd.command = ata_pass_16->command;
1780 ata_cmd.control = ata_pass_16->control;
1781 ata_cmd.features = ata_pass_16->features;
1783 if (arglist & CAM_ARG_VERBOSE) {
1784 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1785 ata_op_string(&ata_cmd),
1786 ccb->csio.ccb_h.timeout);
1789 /* Disable freezing the device queue */
1790 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1792 if (arglist & CAM_ARG_ERR_RECOVER)
1793 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1795 if (cam_send_ccb(device, ccb) < 0) {
1796 warn("error sending ATA %s via pass_16", ata_op_string(&ata_cmd));
1801 * Consider any non-CAM_REQ_CMP status as error and report it here,
1802 * unless caller set AP_FLAG_CHK_COND, in which case it is reponsible.
1804 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1805 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1806 warnx("ATA %s via pass_16 failed", ata_op_string(&ata_cmd));
1807 if (arglist & CAM_ARG_VERBOSE) {
1808 cam_error_print(device, ccb, CAM_ESF_ALL,
1809 CAM_EPF_ALL, stderr);
1819 ata_cam_send(struct cam_device *device, union ccb *ccb)
1821 if (arglist & CAM_ARG_VERBOSE) {
1822 warnx("sending ATA %s with timeout of %u msecs",
1823 ata_op_string(&(ccb->ataio.cmd)),
1824 ccb->ataio.ccb_h.timeout);
1827 /* Disable freezing the device queue */
1828 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1830 if (arglist & CAM_ARG_ERR_RECOVER)
1831 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1833 if (cam_send_ccb(device, ccb) < 0) {
1834 warn("error sending ATA %s", ata_op_string(&(ccb->ataio.cmd)));
1839 * Consider any non-CAM_REQ_CMP status as error and report it here,
1840 * unless caller set AP_FLAG_CHK_COND, in which case it is reponsible.
1842 if (!(ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT) &&
1843 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1844 warnx("ATA %s failed", ata_op_string(&(ccb->ataio.cmd)));
1845 if (arglist & CAM_ARG_VERBOSE) {
1846 cam_error_print(device, ccb, CAM_ESF_ALL,
1847 CAM_EPF_ALL, stderr);
1856 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1857 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1858 u_int8_t tag_action, u_int8_t command, u_int16_t features,
1859 u_int64_t lba, u_int16_t sector_count, u_int8_t *data_ptr,
1860 u_int16_t dxfer_len, int timeout)
1862 if (data_ptr != NULL) {
1863 if (flags & CAM_DIR_OUT)
1864 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1866 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1868 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1871 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1873 scsi_ata_pass_16(&ccb->csio,
1887 /*sense_len*/SSD_FULL_SIZE,
1890 return scsi_cam_pass_16_send(device, ccb);
1894 ata_try_pass_16(struct cam_device *device)
1896 struct ccb_pathinq cpi;
1898 if (get_cpi(device, &cpi) != 0) {
1899 warnx("couldn't get CPI");
1903 if (cpi.protocol == PROTO_SCSI) {
1904 /* possibly compatible with pass_16 */
1908 /* likely not compatible with pass_16 */
1913 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1914 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1915 u_int8_t tag_action, u_int8_t command, u_int16_t features,
1916 u_int64_t lba, u_int16_t sector_count, u_int8_t *data_ptr,
1917 u_int16_t dxfer_len, int timeout, int force48bit)
1921 retval = ata_try_pass_16(device);
1926 return (ata_do_pass_16(device, ccb, retries, flags, protocol,
1927 ata_flags, tag_action, command, features,
1928 lba, sector_count, data_ptr, dxfer_len,
1932 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1933 cam_fill_ataio(&ccb->ataio,
1942 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1943 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1945 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1947 if (ata_flags & AP_FLAG_CHK_COND)
1948 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1950 return ata_cam_send(device, ccb);
1954 dump_data(uint16_t *ptr, uint32_t len)
1958 for (i = 0; i < len / 2; i++) {
1960 printf(" %3d: ", i);
1961 printf("%04hx ", ptr[i]);
1970 atahpa_proc_resp(struct cam_device *device, union ccb *ccb, u_int64_t *hpasize)
1972 uint8_t error = 0, ata_device = 0, status = 0;
1977 retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
1980 if (arglist & CAM_ARG_VERBOSE) {
1981 cam_error_print(device, ccb, CAM_ESF_ALL,
1982 CAM_EPF_ALL, stderr);
1984 warnx("Can't get ATA command status");
1988 if (status & ATA_STATUS_ERROR) {
1989 if (arglist & CAM_ARG_VERBOSE) {
1990 cam_error_print(device, ccb, CAM_ESF_ALL,
1991 CAM_EPF_ALL, stderr);
1994 if (error & ATA_ERROR_ID_NOT_FOUND) {
1995 warnx("Max address has already been set since "
1996 "last power-on or hardware reset");
1997 } else if (hpasize == NULL)
1998 warnx("Command failed with ATA error");
2003 if (hpasize != NULL) {
2004 if (retval == 2 || retval == 6)
2013 ata_read_native_max(struct cam_device *device, int retry_count,
2014 u_int32_t timeout, union ccb *ccb,
2015 struct ata_params *parm, u_int64_t *hpasize)
2021 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
2022 protocol = AP_PROTO_NON_DATA;
2025 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
2026 protocol |= AP_EXTEND;
2028 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
2031 error = ata_do_cmd(device,
2034 /*flags*/CAM_DIR_NONE,
2035 /*protocol*/protocol,
2036 /*ata_flags*/AP_FLAG_CHK_COND,
2037 /*tag_action*/MSG_SIMPLE_Q_TAG,
2044 timeout ? timeout : 5000,
2050 return atahpa_proc_resp(device, ccb, hpasize);
2054 atahpa_set_max(struct cam_device *device, int retry_count,
2055 u_int32_t timeout, union ccb *ccb,
2056 int is48bit, u_int64_t maxsize, int persist)
2062 protocol = AP_PROTO_NON_DATA;
2065 cmd = ATA_SET_MAX_ADDRESS48;
2066 protocol |= AP_EXTEND;
2068 cmd = ATA_SET_MAX_ADDRESS;
2071 /* lba's are zero indexed so the max lba is requested max - 1 */
2075 error = ata_do_cmd(device,
2078 /*flags*/CAM_DIR_NONE,
2079 /*protocol*/protocol,
2080 /*ata_flags*/AP_FLAG_CHK_COND,
2081 /*tag_action*/MSG_SIMPLE_Q_TAG,
2083 /*features*/ATA_HPA_FEAT_MAX_ADDR,
2085 /*sector_count*/persist,
2088 timeout ? timeout : 1000,
2094 return atahpa_proc_resp(device, ccb, NULL);
2098 atahpa_password(struct cam_device *device, int retry_count,
2099 u_int32_t timeout, union ccb *ccb,
2100 int is48bit, struct ata_set_max_pwd *pwd)
2105 protocol = AP_PROTO_PIO_OUT;
2106 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2108 return (ata_do_cmd(device,
2111 /*flags*/CAM_DIR_OUT,
2112 /*protocol*/protocol,
2113 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2114 AP_FLAG_TLEN_SECT_CNT,
2115 /*tag_action*/MSG_SIMPLE_Q_TAG,
2117 /*features*/ATA_HPA_FEAT_SET_PWD,
2119 /*sector_count*/sizeof(*pwd) / 512,
2120 /*data_ptr*/(u_int8_t*)pwd,
2121 /*dxfer_len*/sizeof(*pwd),
2122 timeout ? timeout : 1000,
2127 atahpa_lock(struct cam_device *device, int retry_count,
2128 u_int32_t timeout, union ccb *ccb, int is48bit)
2133 protocol = AP_PROTO_NON_DATA;
2134 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2136 return (ata_do_cmd(device,
2139 /*flags*/CAM_DIR_NONE,
2140 /*protocol*/protocol,
2142 /*tag_action*/MSG_SIMPLE_Q_TAG,
2144 /*features*/ATA_HPA_FEAT_LOCK,
2149 timeout ? timeout : 1000,
2154 atahpa_unlock(struct cam_device *device, int retry_count,
2155 u_int32_t timeout, union ccb *ccb,
2156 int is48bit, struct ata_set_max_pwd *pwd)
2161 protocol = AP_PROTO_PIO_OUT;
2162 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2164 return (ata_do_cmd(device,
2167 /*flags*/CAM_DIR_OUT,
2168 /*protocol*/protocol,
2169 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2170 AP_FLAG_TLEN_SECT_CNT,
2171 /*tag_action*/MSG_SIMPLE_Q_TAG,
2173 /*features*/ATA_HPA_FEAT_UNLOCK,
2175 /*sector_count*/sizeof(*pwd) / 512,
2176 /*data_ptr*/(u_int8_t*)pwd,
2177 /*dxfer_len*/sizeof(*pwd),
2178 timeout ? timeout : 1000,
2183 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2184 u_int32_t timeout, union ccb *ccb, int is48bit)
2189 protocol = AP_PROTO_NON_DATA;
2190 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2192 return (ata_do_cmd(device,
2195 /*flags*/CAM_DIR_NONE,
2196 /*protocol*/protocol,
2198 /*tag_action*/MSG_SIMPLE_Q_TAG,
2200 /*features*/ATA_HPA_FEAT_FREEZE,
2205 timeout ? timeout : 1000,
2210 ata_get_native_max(struct cam_device *device, int retry_count,
2211 u_int32_t timeout, union ccb *ccb,
2212 u_int64_t *nativesize)
2216 error = ata_do_cmd(device,
2219 /*flags*/CAM_DIR_NONE,
2220 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2221 /*ata_flags*/AP_FLAG_CHK_COND,
2222 /*tag_action*/MSG_SIMPLE_Q_TAG,
2223 /*command*/ATA_AMAX_ADDR,
2224 /*features*/ATA_AMAX_ADDR_GET,
2229 timeout ? timeout : 30 * 1000,
2235 return atahpa_proc_resp(device, ccb, nativesize);
2239 ataama_set(struct cam_device *device, int retry_count,
2240 u_int32_t timeout, union ccb *ccb, u_int64_t maxsize)
2244 /* lba's are zero indexed so the max lba is requested max - 1 */
2248 error = ata_do_cmd(device,
2251 /*flags*/CAM_DIR_NONE,
2252 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2253 /*ata_flags*/AP_FLAG_CHK_COND,
2254 /*tag_action*/MSG_SIMPLE_Q_TAG,
2255 /*command*/ATA_AMAX_ADDR,
2256 /*features*/ATA_AMAX_ADDR_SET,
2261 timeout ? timeout : 30 * 1000,
2267 return atahpa_proc_resp(device, ccb, NULL);
2271 ataama_freeze(struct cam_device *device, int retry_count,
2272 u_int32_t timeout, union ccb *ccb)
2275 return (ata_do_cmd(device,
2278 /*flags*/CAM_DIR_NONE,
2279 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2281 /*tag_action*/MSG_SIMPLE_Q_TAG,
2282 /*command*/ATA_AMAX_ADDR,
2283 /*features*/ATA_AMAX_ADDR_FREEZE,
2288 timeout ? timeout : 30 * 1000,
2293 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2294 union ccb *ccb, struct ata_params** ident_bufp)
2296 struct ata_params *ident_buf;
2297 struct ccb_pathinq cpi;
2298 struct ccb_getdev cgd;
2301 u_int8_t command, retry_command;
2303 if (get_cpi(device, &cpi) != 0) {
2304 warnx("couldn't get CPI");
2308 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2309 if (cpi.protocol == PROTO_ATA) {
2310 if (get_cgd(device, &cgd) != 0) {
2311 warnx("couldn't get CGD");
2315 command = (cgd.protocol == PROTO_ATA) ?
2316 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2319 /* We don't know which for sure so try both */
2320 command = ATA_ATA_IDENTIFY;
2321 retry_command = ATA_ATAPI_IDENTIFY;
2324 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2326 warnx("can't calloc memory for identify\n");
2331 error = ata_do_cmd(device,
2333 /*retries*/retry_count,
2334 /*flags*/CAM_DIR_IN,
2335 /*protocol*/AP_PROTO_PIO_IN,
2336 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2337 AP_FLAG_TLEN_SECT_CNT,
2338 /*tag_action*/MSG_SIMPLE_Q_TAG,
2342 /*sector_count*/sizeof(struct ata_params) / 512,
2343 /*data_ptr*/(u_int8_t *)ptr,
2344 /*dxfer_len*/sizeof(struct ata_params),
2345 /*timeout*/timeout ? timeout : 30 * 1000,
2349 if (retry_command != 0) {
2350 command = retry_command;
2358 ident_buf = (struct ata_params *)ptr;
2359 ata_param_fixup(ident_buf);
2362 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2367 /* check for invalid (all zero) response */
2369 warnx("Invalid identify response detected");
2374 *ident_bufp = ident_buf;
2381 ataidentify(struct cam_device *device, int retry_count, int timeout)
2384 struct ata_params *ident_buf;
2385 u_int64_t hpasize = 0, nativesize = 0;
2387 if ((ccb = cam_getccb(device)) == NULL) {
2388 warnx("couldn't allocate CCB");
2392 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2397 if (arglist & CAM_ARG_VERBOSE) {
2398 printf("%s%d: Raw identify data:\n",
2399 device->device_name, device->dev_unit_num);
2400 dump_data((void*)ident_buf, sizeof(struct ata_params));
2403 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2404 ata_read_native_max(device, retry_count, timeout, ccb,
2405 ident_buf, &hpasize);
2407 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR) {
2408 ata_get_native_max(device, retry_count, timeout, ccb,
2412 printf("%s%d: ", device->device_name, device->dev_unit_num);
2413 ata_print_ident(ident_buf);
2414 camxferrate(device);
2415 atacapprint(ident_buf);
2416 atahpa_print(ident_buf, hpasize, 0);
2417 ataama_print(ident_buf, nativesize, 0);
2427 nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused)
2429 struct nvme_controller_data cdata;
2431 if (nvme_get_cdata(device, &cdata))
2433 nvme_print_controller(&cdata);
2440 identify(struct cam_device *device, int retry_count, int timeout)
2443 struct ccb_pathinq cpi;
2445 if (get_cpi(device, &cpi) != 0) {
2446 warnx("couldn't get CPI");
2450 if (cpi.protocol == PROTO_NVME) {
2451 return (nvmeidentify(device, retry_count, timeout));
2454 return (ataidentify(device, retry_count, timeout));
2456 #endif /* MINIMALISTIC */
2459 #ifndef MINIMALISTIC
2461 ATA_SECURITY_ACTION_PRINT,
2462 ATA_SECURITY_ACTION_FREEZE,
2463 ATA_SECURITY_ACTION_UNLOCK,
2464 ATA_SECURITY_ACTION_DISABLE,
2465 ATA_SECURITY_ACTION_ERASE,
2466 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2467 ATA_SECURITY_ACTION_SET_PASSWORD
2471 atasecurity_print_time(u_int16_t tw)
2475 printf("unspecified");
2477 printf("> 508 min");
2479 printf("%i min", 2 * tw);
2483 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2487 return 2 * 3600 * 1000; /* default: two hours */
2488 else if (timeout > 255)
2489 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2491 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2496 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2500 bzero(&cmd, sizeof(cmd));
2501 cmd.command = command;
2502 printf("Issuing %s", ata_op_string(&cmd));
2505 char pass[sizeof(pwd->password)+1];
2507 /* pwd->password may not be null terminated */
2508 pass[sizeof(pwd->password)] = '\0';
2509 strncpy(pass, pwd->password, sizeof(pwd->password));
2510 printf(" password='%s', user='%s'",
2512 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2515 if (command == ATA_SECURITY_SET_PASSWORD) {
2516 printf(", mode='%s'",
2517 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2518 "maximum" : "high");
2526 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2527 int retry_count, u_int32_t timeout, int quiet)
2531 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2533 return ata_do_cmd(device,
2536 /*flags*/CAM_DIR_NONE,
2537 /*protocol*/AP_PROTO_NON_DATA,
2539 /*tag_action*/MSG_SIMPLE_Q_TAG,
2540 /*command*/ATA_SECURITY_FREEZE_LOCK,
2551 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2552 int retry_count, u_int32_t timeout,
2553 struct ata_security_password *pwd, int quiet)
2557 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2559 return ata_do_cmd(device,
2562 /*flags*/CAM_DIR_OUT,
2563 /*protocol*/AP_PROTO_PIO_OUT,
2564 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2565 AP_FLAG_TLEN_SECT_CNT,
2566 /*tag_action*/MSG_SIMPLE_Q_TAG,
2567 /*command*/ATA_SECURITY_UNLOCK,
2570 /*sector_count*/sizeof(*pwd) / 512,
2571 /*data_ptr*/(u_int8_t *)pwd,
2572 /*dxfer_len*/sizeof(*pwd),
2578 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2579 int retry_count, u_int32_t timeout,
2580 struct ata_security_password *pwd, int quiet)
2584 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2585 return ata_do_cmd(device,
2588 /*flags*/CAM_DIR_OUT,
2589 /*protocol*/AP_PROTO_PIO_OUT,
2590 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2591 AP_FLAG_TLEN_SECT_CNT,
2592 /*tag_action*/MSG_SIMPLE_Q_TAG,
2593 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2596 /*sector_count*/sizeof(*pwd) / 512,
2597 /*data_ptr*/(u_int8_t *)pwd,
2598 /*dxfer_len*/sizeof(*pwd),
2605 atasecurity_erase_confirm(struct cam_device *device,
2606 struct ata_params* ident_buf)
2609 printf("\nYou are about to ERASE ALL DATA from the following"
2610 " device:\n%s%d,%s%d: ", device->device_name,
2611 device->dev_unit_num, device->given_dev_name,
2612 device->given_unit_number);
2613 ata_print_ident(ident_buf);
2617 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2619 if (fgets(str, sizeof(str), stdin) != NULL) {
2620 if (strncasecmp(str, "yes", 3) == 0) {
2622 } else if (strncasecmp(str, "no", 2) == 0) {
2625 printf("Please answer \"yes\" or "
2636 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2637 int retry_count, u_int32_t timeout,
2638 u_int32_t erase_timeout,
2639 struct ata_security_password *pwd, int quiet)
2644 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2646 error = ata_do_cmd(device,
2649 /*flags*/CAM_DIR_NONE,
2650 /*protocol*/AP_PROTO_NON_DATA,
2652 /*tag_action*/MSG_SIMPLE_Q_TAG,
2653 /*command*/ATA_SECURITY_ERASE_PREPARE,
2666 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2668 error = ata_do_cmd(device,
2671 /*flags*/CAM_DIR_OUT,
2672 /*protocol*/AP_PROTO_PIO_OUT,
2673 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2674 AP_FLAG_TLEN_SECT_CNT,
2675 /*tag_action*/MSG_SIMPLE_Q_TAG,
2676 /*command*/ATA_SECURITY_ERASE_UNIT,
2679 /*sector_count*/sizeof(*pwd) / 512,
2680 /*data_ptr*/(u_int8_t *)pwd,
2681 /*dxfer_len*/sizeof(*pwd),
2682 /*timeout*/erase_timeout,
2685 if (error == 0 && quiet == 0)
2686 printf("\nErase Complete\n");
2692 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2693 int retry_count, u_int32_t timeout,
2694 struct ata_security_password *pwd, int quiet)
2698 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2700 return ata_do_cmd(device,
2703 /*flags*/CAM_DIR_OUT,
2704 /*protocol*/AP_PROTO_PIO_OUT,
2705 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2706 AP_FLAG_TLEN_SECT_CNT,
2707 /*tag_action*/MSG_SIMPLE_Q_TAG,
2708 /*command*/ATA_SECURITY_SET_PASSWORD,
2711 /*sector_count*/sizeof(*pwd) / 512,
2712 /*data_ptr*/(u_int8_t *)pwd,
2713 /*dxfer_len*/sizeof(*pwd),
2719 atasecurity_print(struct ata_params *parm)
2722 printf("\nSecurity Option Value\n");
2723 if (arglist & CAM_ARG_VERBOSE) {
2724 printf("status %04x\n",
2725 parm->security_status);
2727 printf("supported %s\n",
2728 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2729 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2731 printf("enabled %s\n",
2732 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2733 printf("drive locked %s\n",
2734 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2735 printf("security config frozen %s\n",
2736 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2737 printf("count expired %s\n",
2738 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2739 printf("security level %s\n",
2740 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2741 printf("enhanced erase supported %s\n",
2742 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2743 printf("erase time ");
2744 atasecurity_print_time(parm->erase_time);
2746 printf("enhanced erase time ");
2747 atasecurity_print_time(parm->enhanced_erase_time);
2749 printf("master password rev %04x%s\n",
2750 parm->master_passwd_revision,
2751 parm->master_passwd_revision == 0x0000 ||
2752 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2756 * Validates and copies the password in optarg to the passed buffer.
2757 * If the password in optarg is the same length as the buffer then
2758 * the data will still be copied but no null termination will occur.
2761 ata_getpwd(u_int8_t *passwd, int max, char opt)
2765 len = strlen(optarg);
2767 warnx("-%c password is too long", opt);
2769 } else if (len == 0) {
2770 warnx("-%c password is missing", opt);
2772 } else if (optarg[0] == '-'){
2773 warnx("-%c password starts with '-' (generic arg?)", opt);
2775 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2776 warnx("-%c password conflicts with existing password from -%c",
2781 /* Callers pass in a buffer which does NOT need to be terminated */
2782 strncpy(passwd, optarg, max);
2789 ATA_HPA_ACTION_PRINT,
2790 ATA_HPA_ACTION_SET_MAX,
2791 ATA_HPA_ACTION_SET_PWD,
2792 ATA_HPA_ACTION_LOCK,
2793 ATA_HPA_ACTION_UNLOCK,
2794 ATA_HPA_ACTION_FREEZE_LOCK
2798 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2799 u_int64_t maxsize, int persist)
2801 printf("\nYou are about to configure HPA to limit the user accessible\n"
2802 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2803 persist ? "persistently" : "temporarily",
2804 device->device_name, device->dev_unit_num,
2805 device->given_dev_name, device->given_unit_number);
2806 ata_print_ident(ident_buf);
2810 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2812 if (NULL != fgets(str, sizeof(str), stdin)) {
2813 if (0 == strncasecmp(str, "yes", 3)) {
2815 } else if (0 == strncasecmp(str, "no", 2)) {
2818 printf("Please answer \"yes\" or "
2829 atahpa(struct cam_device *device, int retry_count, int timeout,
2830 int argc, char **argv, char *combinedopt)
2833 struct ata_params *ident_buf;
2834 struct ccb_getdev cgd;
2835 struct ata_set_max_pwd pwd;
2836 int error, confirm, quiet, c, action, actions, persist;
2837 int security, is48bit, pwdsize;
2838 u_int64_t hpasize, maxsize;
2847 memset(&pwd, 0, sizeof(pwd));
2849 /* default action is to print hpa information */
2850 action = ATA_HPA_ACTION_PRINT;
2851 pwdsize = sizeof(pwd.password);
2853 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2856 action = ATA_HPA_ACTION_SET_MAX;
2857 maxsize = strtoumax(optarg, NULL, 0);
2862 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2864 action = ATA_HPA_ACTION_SET_PWD;
2870 action = ATA_HPA_ACTION_LOCK;
2876 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2878 action = ATA_HPA_ACTION_UNLOCK;
2884 action = ATA_HPA_ACTION_FREEZE_LOCK;
2904 warnx("too many hpa actions specified");
2908 if (get_cgd(device, &cgd) != 0) {
2909 warnx("couldn't get CGD");
2913 ccb = cam_getccb(device);
2915 warnx("couldn't allocate CCB");
2919 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2926 printf("%s%d: ", device->device_name, device->dev_unit_num);
2927 ata_print_ident(ident_buf);
2928 camxferrate(device);
2931 if (action == ATA_HPA_ACTION_PRINT) {
2933 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)
2934 ata_read_native_max(device, retry_count, timeout, ccb,
2935 ident_buf, &hpasize);
2936 atahpa_print(ident_buf, hpasize, 1);
2943 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2944 warnx("HPA is not supported by this device");
2950 if (security && !(ident_buf->support.command2 & ATA_SUPPORT_MAXSECURITY)) {
2951 warnx("HPA Security is not supported by this device");
2957 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2960 * The ATA spec requires:
2961 * 1. Read native max addr is called directly before set max addr
2962 * 2. Read native max addr is NOT called before any other set max call
2965 case ATA_HPA_ACTION_SET_MAX:
2967 atahpa_set_confirm(device, ident_buf, maxsize,
2974 error = ata_read_native_max(device, retry_count, timeout,
2975 ccb, ident_buf, &hpasize);
2977 error = atahpa_set_max(device, retry_count, timeout,
2978 ccb, is48bit, maxsize, persist);
2981 /* redo identify to get new values */
2982 error = ata_do_identify(device,
2983 retry_count, timeout, ccb,
2985 atahpa_print(ident_buf, hpasize, 1);
2987 /* Hint CAM to reprobe the device. */
2993 case ATA_HPA_ACTION_SET_PWD:
2994 error = atahpa_password(device, retry_count, timeout,
2995 ccb, is48bit, &pwd);
2996 if (error == 0 && quiet == 0)
2997 printf("HPA password has been set\n");
3000 case ATA_HPA_ACTION_LOCK:
3001 error = atahpa_lock(device, retry_count, timeout,
3003 if (error == 0 && quiet == 0)
3004 printf("HPA has been locked\n");
3007 case ATA_HPA_ACTION_UNLOCK:
3008 error = atahpa_unlock(device, retry_count, timeout,
3009 ccb, is48bit, &pwd);
3010 if (error == 0 && quiet == 0)
3011 printf("HPA has been unlocked\n");
3014 case ATA_HPA_ACTION_FREEZE_LOCK:
3015 error = atahpa_freeze_lock(device, retry_count, timeout,
3017 if (error == 0 && quiet == 0)
3018 printf("HPA has been frozen\n");
3022 errx(1, "Option currently not supported");
3032 ATA_AMA_ACTION_PRINT,
3033 ATA_AMA_ACTION_SET_MAX,
3034 ATA_AMA_ACTION_FREEZE_LOCK
3038 ataama(struct cam_device *device, int retry_count, int timeout,
3039 int argc, char **argv, char *combinedopt)
3042 struct ata_params *ident_buf;
3043 struct ccb_getdev cgd;
3044 int error, quiet, c, action, actions;
3045 u_int64_t nativesize, maxsize;
3051 /* default action is to print AMA information */
3052 action = ATA_AMA_ACTION_PRINT;
3054 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3057 action = ATA_AMA_ACTION_SET_MAX;
3058 maxsize = strtoumax(optarg, NULL, 0);
3063 action = ATA_AMA_ACTION_FREEZE_LOCK;
3074 warnx("too many AMA actions specified");
3078 if (get_cgd(device, &cgd) != 0) {
3079 warnx("couldn't get CGD");
3083 ccb = cam_getccb(device);
3085 warnx("couldn't allocate CCB");
3089 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3096 printf("%s%d: ", device->device_name, device->dev_unit_num);
3097 ata_print_ident(ident_buf);
3098 camxferrate(device);
3101 if (action == ATA_AMA_ACTION_PRINT) {
3103 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)
3104 ata_get_native_max(device, retry_count, timeout, ccb,
3106 ataama_print(ident_buf, nativesize, 1);
3113 if (!(ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)) {
3114 warnx("Accessible Max Address is not supported by this device");
3121 case ATA_AMA_ACTION_SET_MAX:
3122 error = ata_get_native_max(device, retry_count, timeout, ccb,
3125 error = ataama_set(device, retry_count, timeout,
3129 /* redo identify to get new values */
3130 error = ata_do_identify(device,
3131 retry_count, timeout, ccb,
3133 ataama_print(ident_buf, nativesize, 1);
3135 /* Hint CAM to reprobe the device. */
3141 case ATA_AMA_ACTION_FREEZE_LOCK:
3142 error = ataama_freeze(device, retry_count, timeout,
3144 if (error == 0 && quiet == 0)
3145 printf("Accessible Max Address has been frozen\n");
3149 errx(1, "Option currently not supported");
3159 atasecurity(struct cam_device *device, int retry_count, int timeout,
3160 int argc, char **argv, char *combinedopt)
3163 struct ata_params *ident_buf;
3164 int error, confirm, quiet, c, action, actions, setpwd;
3165 int security_enabled, erase_timeout, pwdsize;
3166 struct ata_security_password pwd;
3174 memset(&pwd, 0, sizeof(pwd));
3176 /* default action is to print security information */
3177 action = ATA_SECURITY_ACTION_PRINT;
3179 /* user is master by default as its safer that way */
3180 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3181 pwdsize = sizeof(pwd.password);
3183 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3186 action = ATA_SECURITY_ACTION_FREEZE;
3191 if (strcasecmp(optarg, "user") == 0) {
3192 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
3193 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
3194 } else if (strcasecmp(optarg, "master") == 0) {
3195 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3196 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
3198 warnx("-U argument '%s' is invalid (must be "
3199 "'user' or 'master')", optarg);
3205 if (strcasecmp(optarg, "high") == 0) {
3206 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3207 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3208 } else if (strcasecmp(optarg, "maximum") == 0) {
3209 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3210 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3212 warnx("-l argument '%s' is unknown (must be "
3213 "'high' or 'maximum')", optarg);
3219 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3221 action = ATA_SECURITY_ACTION_UNLOCK;
3226 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3228 action = ATA_SECURITY_ACTION_DISABLE;
3233 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3235 action = ATA_SECURITY_ACTION_ERASE;
3240 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3242 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3243 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3248 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3251 if (action == ATA_SECURITY_ACTION_PRINT)
3252 action = ATA_SECURITY_ACTION_SET_PASSWORD;
3254 * Don't increment action as this can be combined
3255 * with other actions.
3268 erase_timeout = atoi(optarg) * 1000;
3274 warnx("too many security actions specified");
3278 if ((ccb = cam_getccb(device)) == NULL) {
3279 warnx("couldn't allocate CCB");
3283 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3290 printf("%s%d: ", device->device_name, device->dev_unit_num);
3291 ata_print_ident(ident_buf);
3292 camxferrate(device);
3295 if (action == ATA_SECURITY_ACTION_PRINT) {
3296 atasecurity_print(ident_buf);
3302 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3303 warnx("Security not supported");
3309 /* default timeout 15 seconds the same as linux hdparm */
3310 timeout = timeout ? timeout : 15 * 1000;
3312 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3314 /* first set the password if requested */
3316 /* confirm we can erase before setting the password if erasing */
3318 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3319 action == ATA_SECURITY_ACTION_ERASE) &&
3320 atasecurity_erase_confirm(device, ident_buf) == 0) {
3326 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3327 pwd.revision = ident_buf->master_passwd_revision;
3328 if (pwd.revision != 0 && pwd.revision != 0xfff &&
3329 --pwd.revision == 0) {
3330 pwd.revision = 0xfffe;
3333 error = atasecurity_set_password(device, ccb, retry_count,
3334 timeout, &pwd, quiet);
3340 security_enabled = 1;
3344 case ATA_SECURITY_ACTION_FREEZE:
3345 error = atasecurity_freeze(device, ccb, retry_count,
3349 case ATA_SECURITY_ACTION_UNLOCK:
3350 if (security_enabled) {
3351 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3352 error = atasecurity_unlock(device, ccb,
3353 retry_count, timeout, &pwd, quiet);
3355 warnx("Can't unlock, drive is not locked");
3359 warnx("Can't unlock, security is disabled");
3364 case ATA_SECURITY_ACTION_DISABLE:
3365 if (security_enabled) {
3366 /* First unlock the drive if its locked */
3367 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3368 error = atasecurity_unlock(device, ccb,
3376 error = atasecurity_disable(device,
3384 warnx("Can't disable security (already disabled)");
3389 case ATA_SECURITY_ACTION_ERASE:
3390 if (security_enabled) {
3391 if (erase_timeout == 0) {
3392 erase_timeout = atasecurity_erase_timeout_msecs(
3393 ident_buf->erase_time);
3396 error = atasecurity_erase(device, ccb, retry_count,
3397 timeout, erase_timeout, &pwd, quiet);
3399 warnx("Can't secure erase (security is disabled)");
3404 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3405 if (security_enabled) {
3406 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3407 if (erase_timeout == 0) {
3409 atasecurity_erase_timeout_msecs(
3410 ident_buf->enhanced_erase_time);
3413 error = atasecurity_erase(device, ccb,
3414 retry_count, timeout,
3415 erase_timeout, &pwd,
3418 warnx("Enhanced erase is not supported");
3422 warnx("Can't secure erase (enhanced), "
3423 "(security is disabled)");
3434 #endif /* MINIMALISTIC */
3437 * Convert periph name into a bus, target and lun.
3439 * Returns the number of parsed components, or 0.
3442 parse_btl_name(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3443 cam_argmask *arglst)
3448 bzero(&ccb, sizeof(ccb));
3449 ccb.ccb_h.func_code = XPT_GDEVLIST;
3450 if (cam_get_device(tstr, ccb.cgdl.periph_name,
3451 sizeof(ccb.cgdl.periph_name), &ccb.cgdl.unit_number) == -1) {
3452 warnx("%s", cam_errbuf);
3457 * Attempt to get the passthrough device. This ioctl will
3458 * fail if the device name is null, if the device doesn't
3459 * exist, or if the passthrough driver isn't in the kernel.
3461 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3462 warn("Unable to open %s", XPT_DEVICE);
3465 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3466 warn("Unable to find bus:target:lun for device %s%d",
3467 ccb.cgdl.periph_name, ccb.cgdl.unit_number);
3472 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3473 const struct cam_status_entry *entry;
3475 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3476 warnx("Unable to find bus:target_lun for device %s%d, "
3477 "CAM status: %s (%#x)",
3478 ccb.cgdl.periph_name, ccb.cgdl.unit_number,
3479 entry ? entry->status_text : "Unknown",
3485 * The kernel fills in the bus/target/lun. We don't
3486 * need the passthrough device name and unit number since
3487 * we aren't going to open it.
3489 *bus = ccb.ccb_h.path_id;
3490 *target = ccb.ccb_h.target_id;
3491 *lun = ccb.ccb_h.target_lun;
3492 *arglst |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3497 * Parse out a bus, or a bus, target and lun in the following
3503 * Returns the number of parsed components, or 0.
3506 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3507 cam_argmask *arglst)
3512 *bus = CAM_BUS_WILDCARD;
3513 *target = CAM_TARGET_WILDCARD;
3514 *lun = CAM_LUN_WILDCARD;
3516 while (isspace(*tstr) && (*tstr != '\0'))
3519 if (strncasecmp(tstr, "all", strlen("all")) == 0) {
3520 arglist |= CAM_ARG_BUS;
3524 if (!isdigit(*tstr))
3525 return (parse_btl_name(tstr, bus, target, lun, arglst));
3527 tmpstr = strsep(&tstr, ":");
3528 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3529 *bus = strtol(tmpstr, &end, 0);
3532 *arglst |= CAM_ARG_BUS;
3534 tmpstr = strsep(&tstr, ":");
3535 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3536 *target = strtol(tmpstr, &end, 0);
3539 *arglst |= CAM_ARG_TARGET;
3541 tmpstr = strsep(&tstr, ":");
3542 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3543 *lun = strtoll(tmpstr, &end, 0);
3546 *arglst |= CAM_ARG_LUN;
3556 dorescan_or_reset(int argc, char **argv, int rescan)
3558 static const char must[] =
3559 "you must specify \"all\", a bus, a bus:target:lun or periph to %s";
3561 path_id_t bus = CAM_BUS_WILDCARD;
3562 target_id_t target = CAM_TARGET_WILDCARD;
3563 lun_id_t lun = CAM_LUN_WILDCARD;
3567 warnx(must, rescan? "rescan" : "reset");
3571 tstr = argv[optind];
3572 while (isspace(*tstr) && (*tstr != '\0'))
3574 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3575 arglist |= CAM_ARG_BUS;
3577 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3578 if (rv != 1 && rv != 3) {
3579 warnx(must, rescan ? "rescan" : "reset");
3584 if (arglist & CAM_ARG_LUN)
3585 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3587 error = rescan_or_reset_bus(bus, rescan);
3593 rescan_or_reset_bus(path_id_t bus, int rescan)
3595 union ccb *ccb = NULL, *matchccb = NULL;
3596 int fd = -1, retval;
3601 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3602 warnx("error opening transport layer device %s", XPT_DEVICE);
3603 warn("%s", XPT_DEVICE);
3607 ccb = malloc(sizeof(*ccb));
3609 warn("failed to allocate CCB");
3613 bzero(ccb, sizeof(*ccb));
3615 if (bus != CAM_BUS_WILDCARD) {
3616 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3617 ccb->ccb_h.path_id = bus;
3618 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3619 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3620 ccb->crcn.flags = CAM_FLAG_NONE;
3622 /* run this at a low priority */
3623 ccb->ccb_h.pinfo.priority = 5;
3625 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3626 warn("CAMIOCOMMAND ioctl failed");
3631 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3632 fprintf(stdout, "%s of bus %d was successful\n",
3633 rescan ? "Re-scan" : "Reset", bus);
3635 fprintf(stdout, "%s of bus %d returned error %#x\n",
3636 rescan ? "Re-scan" : "Reset", bus,
3637 ccb->ccb_h.status & CAM_STATUS_MASK);
3646 * The right way to handle this is to modify the xpt so that it can
3647 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3648 * that isn't implemented, so instead we enumerate the buses and
3649 * send the rescan or reset to those buses in the case where the
3650 * given bus is -1 (wildcard). We don't send a rescan or reset
3651 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3652 * no-op, sending a rescan to the xpt bus would result in a status of
3655 matchccb = malloc(sizeof(*matchccb));
3656 if (matchccb == NULL) {
3657 warn("failed to allocate CCB");
3661 bzero(matchccb, sizeof(*matchccb));
3662 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3663 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3664 bufsize = sizeof(struct dev_match_result) * 20;
3665 matchccb->cdm.match_buf_len = bufsize;
3666 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3667 if (matchccb->cdm.matches == NULL) {
3668 warnx("can't malloc memory for matches");
3672 matchccb->cdm.num_matches = 0;
3674 matchccb->cdm.num_patterns = 1;
3675 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3677 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3678 matchccb->cdm.pattern_buf_len);
3679 if (matchccb->cdm.patterns == NULL) {
3680 warnx("can't malloc memory for patterns");
3684 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3685 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3690 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3691 warn("CAMIOCOMMAND ioctl failed");
3696 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3697 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3698 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3699 warnx("got CAM error %#x, CDM error %d\n",
3700 matchccb->ccb_h.status, matchccb->cdm.status);
3705 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3706 struct bus_match_result *bus_result;
3708 /* This shouldn't happen. */
3709 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3712 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3715 * We don't want to rescan or reset the xpt bus.
3718 if (bus_result->path_id == CAM_XPT_PATH_ID)
3721 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3723 ccb->ccb_h.path_id = bus_result->path_id;
3724 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3725 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3726 ccb->crcn.flags = CAM_FLAG_NONE;
3728 /* run this at a low priority */
3729 ccb->ccb_h.pinfo.priority = 5;
3731 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3732 warn("CAMIOCOMMAND ioctl failed");
3737 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3738 fprintf(stdout, "%s of bus %d was successful\n",
3739 rescan? "Re-scan" : "Reset",
3740 bus_result->path_id);
3743 * Don't bail out just yet, maybe the other
3744 * rescan or reset commands will complete
3747 fprintf(stderr, "%s of bus %d returned error "
3748 "%#x\n", rescan? "Re-scan" : "Reset",
3749 bus_result->path_id,
3750 ccb->ccb_h.status & CAM_STATUS_MASK);
3754 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3755 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3762 if (matchccb != NULL) {
3763 free(matchccb->cdm.patterns);
3764 free(matchccb->cdm.matches);
3773 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3776 struct cam_device *device;
3781 if (bus == CAM_BUS_WILDCARD) {
3782 warnx("invalid bus number %d", bus);
3786 if (target == CAM_TARGET_WILDCARD) {
3787 warnx("invalid target number %d", target);
3791 if (lun == CAM_LUN_WILDCARD) {
3792 warnx("invalid lun number %jx", (uintmax_t)lun);
3798 bzero(&ccb, sizeof(union ccb));
3801 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3802 warnx("error opening transport layer device %s\n",
3804 warn("%s", XPT_DEVICE);
3808 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3809 if (device == NULL) {
3810 warnx("%s", cam_errbuf);
3815 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3816 ccb.ccb_h.path_id = bus;
3817 ccb.ccb_h.target_id = target;
3818 ccb.ccb_h.target_lun = lun;
3819 ccb.ccb_h.timeout = 5000;
3820 ccb.crcn.flags = CAM_FLAG_NONE;
3822 /* run this at a low priority */
3823 ccb.ccb_h.pinfo.priority = 5;
3826 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3827 warn("CAMIOCOMMAND ioctl failed");
3832 if (cam_send_ccb(device, &ccb) < 0) {
3833 warn("error sending XPT_RESET_DEV CCB");
3834 cam_close_device(device);
3842 cam_close_device(device);
3845 * An error code of CAM_BDR_SENT is normal for a BDR request.
3847 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3849 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3850 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3851 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3854 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3855 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3856 ccb.ccb_h.status & CAM_STATUS_MASK);
3861 #ifndef MINIMALISTIC
3863 static struct scsi_nv defect_list_type_map[] = {
3864 { "block", SRDD10_BLOCK_FORMAT },
3865 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3866 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3867 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3868 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3869 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3873 readdefects(struct cam_device *device, int argc, char **argv,
3874 char *combinedopt, int task_attr, int retry_count, int timeout)
3876 union ccb *ccb = NULL;
3877 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3878 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3879 size_t hdr_size = 0, entry_size = 0;
3882 u_int8_t *defect_list = NULL;
3883 u_int8_t list_format = 0;
3884 int list_type_set = 0;
3885 u_int32_t dlist_length = 0;
3886 u_int32_t returned_length = 0, valid_len = 0;
3887 u_int32_t num_returned = 0, num_valid = 0;
3888 u_int32_t max_possible_size = 0, hdr_max = 0;
3889 u_int32_t starting_offset = 0;
3890 u_int8_t returned_format, returned_type;
3892 int summary = 0, quiet = 0;
3894 int lists_specified = 0;
3895 int get_length = 1, first_pass = 1;
3898 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3902 scsi_nv_status status;
3905 status = scsi_get_nv(defect_list_type_map,
3906 sizeof(defect_list_type_map) /
3907 sizeof(defect_list_type_map[0]), optarg,
3908 &entry_num, SCSI_NV_FLAG_IG_CASE);
3910 if (status == SCSI_NV_FOUND) {
3911 list_format = defect_list_type_map[
3915 warnx("%s: %s %s option %s", __func__,
3916 (status == SCSI_NV_AMBIGUOUS) ?
3917 "ambiguous" : "invalid", "defect list type",
3920 goto defect_bailout;
3925 arglist |= CAM_ARG_GLIST;
3928 arglist |= CAM_ARG_PLIST;
3939 starting_offset = strtoul(optarg, &endptr, 0);
3940 if (*endptr != '\0') {
3942 warnx("invalid starting offset %s", optarg);
3943 goto defect_bailout;
3955 if (list_type_set == 0) {
3957 warnx("no defect list format specified");
3958 goto defect_bailout;
3961 if (arglist & CAM_ARG_PLIST) {
3962 list_format |= SRDD10_PLIST;
3966 if (arglist & CAM_ARG_GLIST) {
3967 list_format |= SRDD10_GLIST;
3972 * This implies a summary, and was the previous behavior.
3974 if (lists_specified == 0)
3977 ccb = cam_getccb(device);
3982 * We start off asking for just the header to determine how much
3983 * defect data is available. Some Hitachi drives return an error
3984 * if you ask for more data than the drive has. Once we know the
3985 * length, we retry the command with the returned length.
3987 if (use_12byte == 0)
3988 dlist_length = sizeof(*hdr10);
3990 dlist_length = sizeof(*hdr12);
3993 if (defect_list != NULL) {
3997 defect_list = malloc(dlist_length);
3998 if (defect_list == NULL) {
3999 warnx("can't malloc memory for defect list");
4001 goto defect_bailout;
4005 bzero(defect_list, dlist_length);
4008 * cam_getccb() zeros the CCB header only. So we need to zero the
4009 * payload portion of the ccb.
4011 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4013 scsi_read_defects(&ccb->csio,
4014 /*retries*/ retry_count,
4016 /*tag_action*/ task_attr,
4017 /*list_format*/ list_format,
4018 /*addr_desc_index*/ starting_offset,
4019 /*data_ptr*/ defect_list,
4020 /*dxfer_len*/ dlist_length,
4021 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
4022 /*sense_len*/ SSD_FULL_SIZE,
4023 /*timeout*/ timeout ? timeout : 5000);
4025 /* Disable freezing the device queue */
4026 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4028 if (cam_send_ccb(device, ccb) < 0) {
4029 warn("error sending READ DEFECT DATA command");
4031 goto defect_bailout;
4034 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
4036 if (use_12byte == 0) {
4037 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
4038 hdr_size = sizeof(*hdr10);
4039 hdr_max = SRDDH10_MAX_LENGTH;
4041 if (valid_len >= hdr_size) {
4042 returned_length = scsi_2btoul(hdr10->length);
4043 returned_format = hdr10->format;
4045 returned_length = 0;
4046 returned_format = 0;
4049 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
4050 hdr_size = sizeof(*hdr12);
4051 hdr_max = SRDDH12_MAX_LENGTH;
4053 if (valid_len >= hdr_size) {
4054 returned_length = scsi_4btoul(hdr12->length);
4055 returned_format = hdr12->format;
4057 returned_length = 0;
4058 returned_format = 0;
4062 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
4063 switch (returned_type) {
4064 case SRDD10_BLOCK_FORMAT:
4065 entry_size = sizeof(struct scsi_defect_desc_block);
4067 case SRDD10_LONG_BLOCK_FORMAT:
4068 entry_size = sizeof(struct scsi_defect_desc_long_block);
4070 case SRDD10_EXT_PHYS_FORMAT:
4071 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4072 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
4074 case SRDD10_EXT_BFI_FORMAT:
4075 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4076 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
4079 warnx("Unknown defect format 0x%x\n", returned_type);
4081 goto defect_bailout;
4085 max_possible_size = (hdr_max / entry_size) * entry_size;
4086 num_returned = returned_length / entry_size;
4087 num_valid = min(returned_length, valid_len - hdr_size);
4088 num_valid /= entry_size;
4090 if (get_length != 0) {
4093 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
4094 CAM_SCSI_STATUS_ERROR) {
4095 struct scsi_sense_data *sense;
4096 int error_code, sense_key, asc, ascq;
4098 sense = &ccb->csio.sense_data;
4099 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4100 ccb->csio.sense_resid, &error_code, &sense_key,
4101 &asc, &ascq, /*show_errors*/ 1);
4104 * If the drive is reporting that it just doesn't
4105 * support the defect list format, go ahead and use
4106 * the length it reported. Otherwise, the length
4107 * may not be valid, so use the maximum.
4109 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4110 && (asc == 0x1c) && (ascq == 0x00)
4111 && (returned_length > 0)) {
4112 if ((use_12byte == 0)
4113 && (returned_length >= max_possible_size)) {
4118 dlist_length = returned_length + hdr_size;
4119 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4120 && (asc == 0x1f) && (ascq == 0x00)
4121 && (returned_length > 0)) {
4122 /* Partial defect list transfer */
4124 * Hitachi drives return this error
4125 * along with a partial defect list if they
4126 * have more defects than the 10 byte
4127 * command can support. Retry with the 12
4130 if (use_12byte == 0) {
4135 dlist_length = returned_length + hdr_size;
4136 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
4137 && (asc == 0x24) && (ascq == 0x00)) {
4138 /* Invalid field in CDB */
4140 * SBC-3 says that if the drive has more
4141 * defects than can be reported with the
4142 * 10 byte command, it should return this
4143 * error and no data. Retry with the 12
4146 if (use_12byte == 0) {
4151 dlist_length = returned_length + hdr_size;
4154 * If we got a SCSI error and no valid length,
4155 * just use the 10 byte maximum. The 12
4156 * byte maximum is too large.
4158 if (returned_length == 0)
4159 dlist_length = SRDD10_MAX_LENGTH;
4161 if ((use_12byte == 0)
4162 && (returned_length >=
4163 max_possible_size)) {
4168 dlist_length = returned_length +
4172 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4175 warnx("Error reading defect header");
4176 if (arglist & CAM_ARG_VERBOSE)
4177 cam_error_print(device, ccb, CAM_ESF_ALL,
4178 CAM_EPF_ALL, stderr);
4179 goto defect_bailout;
4181 if ((use_12byte == 0)
4182 && (returned_length >= max_possible_size)) {
4187 dlist_length = returned_length + hdr_size;
4190 fprintf(stdout, "%u", num_returned);
4192 fprintf(stdout, " defect%s",
4193 (num_returned != 1) ? "s" : "");
4195 fprintf(stdout, "\n");
4197 goto defect_bailout;
4201 * We always limit the list length to the 10-byte maximum
4202 * length (0xffff). The reason is that some controllers
4203 * can't handle larger I/Os, and we can transfer the entire
4204 * 10 byte list in one shot. For drives that support the 12
4205 * byte read defects command, we'll step through the list
4206 * by specifying a starting offset. For drives that don't
4207 * support the 12 byte command's starting offset, we'll
4208 * just display the first 64K.
4210 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4216 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4217 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4218 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4219 struct scsi_sense_data *sense;
4220 int error_code, sense_key, asc, ascq;
4222 sense = &ccb->csio.sense_data;
4223 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4224 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4225 &ascq, /*show_errors*/ 1);
4228 * According to the SCSI spec, if the disk doesn't support
4229 * the requested format, it will generally return a sense
4230 * key of RECOVERED ERROR, and an additional sense code
4231 * of "DEFECT LIST NOT FOUND". HGST drives also return
4232 * Primary/Grown defect list not found errors. So just
4233 * check for an ASC of 0x1c.
4235 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4237 const char *format_str;
4239 format_str = scsi_nv_to_str(defect_list_type_map,
4240 sizeof(defect_list_type_map) /
4241 sizeof(defect_list_type_map[0]),
4242 list_format & SRDD10_DLIST_FORMAT_MASK);
4243 warnx("requested defect format %s not available",
4244 format_str ? format_str : "unknown");
4246 format_str = scsi_nv_to_str(defect_list_type_map,
4247 sizeof(defect_list_type_map) /
4248 sizeof(defect_list_type_map[0]), returned_type);
4249 if (format_str != NULL) {
4250 warnx("Device returned %s format",
4254 warnx("Device returned unknown defect"
4255 " data format %#x", returned_type);
4256 goto defect_bailout;
4260 warnx("Error returned from read defect data command");
4261 if (arglist & CAM_ARG_VERBOSE)
4262 cam_error_print(device, ccb, CAM_ESF_ALL,
4263 CAM_EPF_ALL, stderr);
4264 goto defect_bailout;
4266 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4268 warnx("Error returned from read defect data command");
4269 if (arglist & CAM_ARG_VERBOSE)
4270 cam_error_print(device, ccb, CAM_ESF_ALL,
4271 CAM_EPF_ALL, stderr);
4272 goto defect_bailout;
4275 if (first_pass != 0) {
4276 fprintf(stderr, "Got %d defect", num_returned);
4278 if ((lists_specified == 0) || (num_returned == 0)) {
4279 fprintf(stderr, "s.\n");
4280 goto defect_bailout;
4281 } else if (num_returned == 1)
4282 fprintf(stderr, ":\n");
4284 fprintf(stderr, "s:\n");
4290 * XXX KDM I should probably clean up the printout format for the
4293 switch (returned_type) {
4294 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4295 case SRDD10_EXT_PHYS_FORMAT:
4297 struct scsi_defect_desc_phys_sector *dlist;
4299 dlist = (struct scsi_defect_desc_phys_sector *)
4300 (defect_list + hdr_size);
4302 for (i = 0; i < num_valid; i++) {
4305 sector = scsi_4btoul(dlist[i].sector);
4306 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4307 mads = (sector & SDD_EXT_PHYS_MADS) ?
4309 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4311 if (hex_format == 0)
4312 fprintf(stdout, "%d:%d:%d%s",
4313 scsi_3btoul(dlist[i].cylinder),
4315 scsi_4btoul(dlist[i].sector),
4316 mads ? " - " : "\n");
4318 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4319 scsi_3btoul(dlist[i].cylinder),
4321 scsi_4btoul(dlist[i].sector),
4322 mads ? " - " : "\n");
4325 if (num_valid < num_returned) {
4326 starting_offset += num_valid;
4331 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4332 case SRDD10_EXT_BFI_FORMAT:
4334 struct scsi_defect_desc_bytes_from_index *dlist;
4336 dlist = (struct scsi_defect_desc_bytes_from_index *)
4337 (defect_list + hdr_size);
4339 for (i = 0; i < num_valid; i++) {
4342 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4343 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4344 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4345 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4347 if (hex_format == 0)
4348 fprintf(stdout, "%d:%d:%d%s",
4349 scsi_3btoul(dlist[i].cylinder),
4351 scsi_4btoul(dlist[i].bytes_from_index),
4352 mads ? " - " : "\n");
4354 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4355 scsi_3btoul(dlist[i].cylinder),
4357 scsi_4btoul(dlist[i].bytes_from_index),
4358 mads ? " - " : "\n");
4362 if (num_valid < num_returned) {
4363 starting_offset += num_valid;
4368 case SRDDH10_BLOCK_FORMAT:
4370 struct scsi_defect_desc_block *dlist;
4372 dlist = (struct scsi_defect_desc_block *)
4373 (defect_list + hdr_size);
4375 for (i = 0; i < num_valid; i++) {
4376 if (hex_format == 0)
4377 fprintf(stdout, "%u\n",
4378 scsi_4btoul(dlist[i].address));
4380 fprintf(stdout, "0x%x\n",
4381 scsi_4btoul(dlist[i].address));
4384 if (num_valid < num_returned) {
4385 starting_offset += num_valid;
4391 case SRDD10_LONG_BLOCK_FORMAT:
4393 struct scsi_defect_desc_long_block *dlist;
4395 dlist = (struct scsi_defect_desc_long_block *)
4396 (defect_list + hdr_size);
4398 for (i = 0; i < num_valid; i++) {
4399 if (hex_format == 0)
4400 fprintf(stdout, "%ju\n",
4401 (uintmax_t)scsi_8btou64(
4404 fprintf(stdout, "0x%jx\n",
4405 (uintmax_t)scsi_8btou64(
4409 if (num_valid < num_returned) {
4410 starting_offset += num_valid;
4416 fprintf(stderr, "Unknown defect format 0x%x\n",
4423 if (defect_list != NULL)
4431 #endif /* MINIMALISTIC */
4435 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4439 ccb = cam_getccb(device);
4445 #ifndef MINIMALISTIC
4447 mode_sense(struct cam_device *device, int *cdb_len, int dbd, int llbaa, int pc,
4448 int page, int subpage, int task_attr, int retry_count, int timeout,
4449 u_int8_t *data, int datalen)
4452 int error_code, sense_key, asc, ascq;
4454 ccb = cam_getccb(device);
4456 errx(1, "mode_sense: couldn't allocate CCB");
4460 * MODE SENSE(6) can't handle more then 255 bytes. If there are more,
4461 * device must return error, so we should not get trucated data.
4463 if (*cdb_len == 6 && datalen > 255)
4466 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4468 scsi_mode_sense_subpage(&ccb->csio,
4469 /* retries */ retry_count,
4471 /* tag_action */ task_attr,
4475 /* subpage */ subpage,
4476 /* param_buf */ data,
4477 /* param_len */ datalen,
4478 /* minimum_cmd_size */ *cdb_len,
4479 /* sense_len */ SSD_FULL_SIZE,
4480 /* timeout */ timeout ? timeout : 5000);
4481 if (llbaa && ccb->csio.cdb_len == 10) {
4482 struct scsi_mode_sense_10 *cdb =
4483 (struct scsi_mode_sense_10 *)ccb->csio.cdb_io.cdb_bytes;
4484 cdb->byte2 |= SMS10_LLBAA;
4487 /* Record what CDB size the above function really set. */
4488 *cdb_len = ccb->csio.cdb_len;
4490 if (arglist & CAM_ARG_ERR_RECOVER)
4491 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4493 /* Disable freezing the device queue */
4494 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4496 if (cam_send_ccb(device, ccb) < 0)
4497 err(1, "error sending mode sense command");
4499 /* In case of ILLEGEL REQUEST try to fall back to 6-byte command. */
4500 if (*cdb_len != 6 &&
4501 ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID ||
4502 (scsi_extract_sense_ccb(ccb, &error_code, &sense_key, &asc, &ascq)
4503 && sense_key == SSD_KEY_ILLEGAL_REQUEST))) {
4508 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4509 if (arglist & CAM_ARG_VERBOSE) {
4510 cam_error_print(device, ccb, CAM_ESF_ALL,
4511 CAM_EPF_ALL, stderr);
4514 cam_close_device(device);
4515 errx(1, "mode sense command returned error");
4522 mode_select(struct cam_device *device, int cdb_len, int save_pages,
4523 int task_attr, int retry_count, int timeout, u_int8_t *data, int datalen)
4528 ccb = cam_getccb(device);
4531 errx(1, "mode_select: couldn't allocate CCB");
4533 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4535 scsi_mode_select_len(&ccb->csio,
4536 /* retries */ retry_count,
4538 /* tag_action */ task_attr,
4539 /* scsi_page_fmt */ 1,
4540 /* save_pages */ save_pages,
4541 /* param_buf */ data,
4542 /* param_len */ datalen,
4543 /* minimum_cmd_size */ cdb_len,
4544 /* sense_len */ SSD_FULL_SIZE,
4545 /* timeout */ timeout ? timeout : 5000);
4547 if (arglist & CAM_ARG_ERR_RECOVER)
4548 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4550 /* Disable freezing the device queue */
4551 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4553 if (((retval = cam_send_ccb(device, ccb)) < 0)
4554 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4555 if (arglist & CAM_ARG_VERBOSE) {
4556 cam_error_print(device, ccb, CAM_ESF_ALL,
4557 CAM_EPF_ALL, stderr);
4560 cam_close_device(device);
4563 err(1, "error sending mode select command");
4565 errx(1, "error sending mode select command");
4573 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4574 int task_attr, int retry_count, int timeout)
4577 int c, page = -1, subpage = -1, pc = 0, llbaa = 0;
4578 int binary = 0, cdb_len = 10, dbd = 0, desc = 0, edit = 0, list = 0;
4580 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4598 str_subpage = optarg;
4599 strsep(&str_subpage, ",");
4600 page = strtol(optarg, NULL, 0);
4602 subpage = strtol(str_subpage, NULL, 0);
4606 errx(1, "invalid mode page %d", page);
4608 errx(1, "invalid mode subpage %d", subpage);
4617 pc = strtol(optarg, NULL, 0);
4618 if ((pc < 0) || (pc > 3))
4619 errx(1, "invalid page control field %d", pc);
4626 if (page == -1 && desc == 0 && list == 0)
4627 errx(1, "you must specify a mode page!");
4630 errx(1, "-d and -D are incompatible!");
4632 if (llbaa && cdb_len != 10)
4633 errx(1, "LLBAA bit is not present in MODE SENSE(6)!");
4636 mode_list(device, cdb_len, dbd, pc, list > 1, task_attr,
4637 retry_count, timeout);
4639 mode_edit(device, cdb_len, desc, dbd, llbaa, pc, page, subpage,
4640 edit, binary, task_attr, retry_count, timeout);
4645 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4646 int task_attr, int retry_count, int timeout)
4649 u_int32_t flags = CAM_DIR_NONE;
4650 u_int8_t *data_ptr = NULL;
4652 u_int8_t atacmd[12];
4653 struct get_hook hook;
4654 int c, data_bytes = 0, valid_bytes;
4660 char *datastr = NULL, *tstr, *resstr = NULL;
4662 int fd_data = 0, fd_res = 0;
4665 ccb = cam_getccb(device);
4668 warnx("scsicmd: error allocating ccb");
4672 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4674 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4678 while (isspace(*tstr) && (*tstr != '\0'))
4680 hook.argc = argc - optind;
4681 hook.argv = argv + optind;
4683 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4686 * Increment optind by the number of arguments the
4687 * encoding routine processed. After each call to
4688 * getopt(3), optind points to the argument that
4689 * getopt should process _next_. In this case,
4690 * that means it points to the first command string
4691 * argument, if there is one. Once we increment
4692 * this, it should point to either the next command
4693 * line argument, or it should be past the end of
4700 while (isspace(*tstr) && (*tstr != '\0'))
4702 hook.argc = argc - optind;
4703 hook.argv = argv + optind;
4705 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4708 * Increment optind by the number of arguments the
4709 * encoding routine processed. After each call to
4710 * getopt(3), optind points to the argument that
4711 * getopt should process _next_. In this case,
4712 * that means it points to the first command string
4713 * argument, if there is one. Once we increment
4714 * this, it should point to either the next command
4715 * line argument, or it should be past the end of
4727 if (arglist & CAM_ARG_CMD_OUT) {
4728 warnx("command must either be "
4729 "read or write, not both");
4731 goto scsicmd_bailout;
4733 arglist |= CAM_ARG_CMD_IN;
4735 data_bytes = strtol(optarg, NULL, 0);
4736 if (data_bytes <= 0) {
4737 warnx("invalid number of input bytes %d",
4740 goto scsicmd_bailout;
4742 hook.argc = argc - optind;
4743 hook.argv = argv + optind;
4746 datastr = cget(&hook, NULL);
4748 * If the user supplied "-" instead of a format, he
4749 * wants the data to be written to stdout.
4751 if ((datastr != NULL)
4752 && (datastr[0] == '-'))
4755 data_ptr = (u_int8_t *)malloc(data_bytes);
4756 if (data_ptr == NULL) {
4757 warnx("can't malloc memory for data_ptr");
4759 goto scsicmd_bailout;
4763 if (arglist & CAM_ARG_CMD_IN) {
4764 warnx("command must either be "
4765 "read or write, not both");
4767 goto scsicmd_bailout;
4769 arglist |= CAM_ARG_CMD_OUT;
4770 flags = CAM_DIR_OUT;
4771 data_bytes = strtol(optarg, NULL, 0);
4772 if (data_bytes <= 0) {
4773 warnx("invalid number of output bytes %d",
4776 goto scsicmd_bailout;
4778 hook.argc = argc - optind;
4779 hook.argv = argv + optind;
4781 datastr = cget(&hook, NULL);
4782 data_ptr = (u_int8_t *)malloc(data_bytes);
4783 if (data_ptr == NULL) {
4784 warnx("can't malloc memory for data_ptr");
4786 goto scsicmd_bailout;
4788 bzero(data_ptr, data_bytes);
4790 * If the user supplied "-" instead of a format, he
4791 * wants the data to be read from stdin.
4793 if ((datastr != NULL)
4794 && (datastr[0] == '-'))
4797 buff_encode_visit(data_ptr, data_bytes, datastr,
4803 hook.argc = argc - optind;
4804 hook.argv = argv + optind;
4806 resstr = cget(&hook, NULL);
4807 if ((resstr != NULL) && (resstr[0] == '-'))
4817 * If fd_data is set, and we're writing to the device, we need to
4818 * read the data the user wants written from stdin.
4820 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4822 int amt_to_read = data_bytes;
4823 u_int8_t *buf_ptr = data_ptr;
4825 for (amt_read = 0; amt_to_read > 0;
4826 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4827 if (amt_read == -1) {
4828 warn("error reading data from stdin");
4830 goto scsicmd_bailout;
4832 amt_to_read -= amt_read;
4833 buf_ptr += amt_read;
4837 if (arglist & CAM_ARG_ERR_RECOVER)
4838 flags |= CAM_PASS_ERR_RECOVER;
4840 /* Disable freezing the device queue */
4841 flags |= CAM_DEV_QFRZDIS;
4845 * This is taken from the SCSI-3 draft spec.
4846 * (T10/1157D revision 0.3)
4847 * The top 3 bits of an opcode are the group code.
4848 * The next 5 bits are the command code.
4849 * Group 0: six byte commands
4850 * Group 1: ten byte commands
4851 * Group 2: ten byte commands
4853 * Group 4: sixteen byte commands
4854 * Group 5: twelve byte commands
4855 * Group 6: vendor specific
4856 * Group 7: vendor specific
4858 switch((cdb[0] >> 5) & 0x7) {
4869 /* computed by buff_encode_visit */
4880 * We should probably use csio_build_visit or something like that
4881 * here, but it's easier to encode arguments as you go. The
4882 * alternative would be skipping the CDB argument and then encoding
4883 * it here, since we've got the data buffer argument by now.
4885 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4887 cam_fill_csio(&ccb->csio,
4888 /*retries*/ retry_count,
4891 /*tag_action*/ task_attr,
4892 /*data_ptr*/ data_ptr,
4893 /*dxfer_len*/ data_bytes,
4894 /*sense_len*/ SSD_FULL_SIZE,
4895 /*cdb_len*/ cdb_len,
4896 /*timeout*/ timeout ? timeout : 5000);
4899 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4901 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4903 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4905 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4907 cam_fill_ataio(&ccb->ataio,
4908 /*retries*/ retry_count,
4912 /*data_ptr*/ data_ptr,
4913 /*dxfer_len*/ data_bytes,
4914 /*timeout*/ timeout ? timeout : 5000);
4917 if (((retval = cam_send_ccb(device, ccb)) < 0)
4918 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4919 const char warnstr[] = "error sending command";
4926 if (arglist & CAM_ARG_VERBOSE) {
4927 cam_error_print(device, ccb, CAM_ESF_ALL,
4928 CAM_EPF_ALL, stderr);
4932 goto scsicmd_bailout;
4935 if (atacmd_len && need_res) {
4937 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4939 fprintf(stdout, "\n");
4942 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4943 ccb->ataio.res.status,
4944 ccb->ataio.res.error,
4945 ccb->ataio.res.lba_low,
4946 ccb->ataio.res.lba_mid,
4947 ccb->ataio.res.lba_high,
4948 ccb->ataio.res.device,
4949 ccb->ataio.res.lba_low_exp,
4950 ccb->ataio.res.lba_mid_exp,
4951 ccb->ataio.res.lba_high_exp,
4952 ccb->ataio.res.sector_count,
4953 ccb->ataio.res.sector_count_exp);
4959 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4961 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4962 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4963 && (arglist & CAM_ARG_CMD_IN)
4964 && (valid_bytes > 0)) {
4966 buff_decode_visit(data_ptr, valid_bytes, datastr,
4968 fprintf(stdout, "\n");
4970 ssize_t amt_written;
4971 int amt_to_write = valid_bytes;
4972 u_int8_t *buf_ptr = data_ptr;
4974 for (amt_written = 0; (amt_to_write > 0) &&
4975 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4976 amt_to_write -= amt_written;
4977 buf_ptr += amt_written;
4979 if (amt_written == -1) {
4980 warn("error writing data to stdout");
4982 goto scsicmd_bailout;
4983 } else if ((amt_written == 0)
4984 && (amt_to_write > 0)) {
4985 warnx("only wrote %u bytes out of %u",
4986 valid_bytes - amt_to_write, valid_bytes);
4993 if ((data_bytes > 0) && (data_ptr != NULL))
5002 camdebug(int argc, char **argv, char *combinedopt)
5005 path_id_t bus = CAM_BUS_WILDCARD;
5006 target_id_t target = CAM_TARGET_WILDCARD;
5007 lun_id_t lun = CAM_LUN_WILDCARD;
5012 bzero(&ccb, sizeof(union ccb));
5014 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5017 arglist |= CAM_ARG_DEBUG_INFO;
5018 ccb.cdbg.flags |= CAM_DEBUG_INFO;
5021 arglist |= CAM_ARG_DEBUG_PERIPH;
5022 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
5025 arglist |= CAM_ARG_DEBUG_SUBTRACE;
5026 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
5029 arglist |= CAM_ARG_DEBUG_TRACE;
5030 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
5033 arglist |= CAM_ARG_DEBUG_XPT;
5034 ccb.cdbg.flags |= CAM_DEBUG_XPT;
5037 arglist |= CAM_ARG_DEBUG_CDB;
5038 ccb.cdbg.flags |= CAM_DEBUG_CDB;
5041 arglist |= CAM_ARG_DEBUG_PROBE;
5042 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
5053 warnx("you must specify \"off\", \"all\" or a bus,");
5054 warnx("bus:target, bus:target:lun or periph");
5059 while (isspace(*tstr) && (*tstr != '\0'))
5062 if (strncmp(tstr, "off", 3) == 0) {
5063 ccb.cdbg.flags = CAM_DEBUG_NONE;
5064 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
5065 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
5066 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
5068 rv = parse_btl(tstr, &bus, &target, &lun, &arglist);
5070 warnx("you must specify \"all\", \"off\", or a bus,");
5071 warnx("bus:target, bus:target:lun or periph to debug");
5076 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
5077 warnx("error opening transport layer device %s", XPT_DEVICE);
5078 warn("%s", XPT_DEVICE);
5082 ccb.ccb_h.func_code = XPT_DEBUG;
5083 ccb.ccb_h.path_id = bus;
5084 ccb.ccb_h.target_id = target;
5085 ccb.ccb_h.target_lun = lun;
5087 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
5088 warn("CAMIOCOMMAND ioctl failed");
5091 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
5092 CAM_FUNC_NOTAVAIL) {
5093 warnx("CAM debugging not available");
5094 warnx("you need to put options CAMDEBUG in"
5095 " your kernel config file!");
5097 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
5099 warnx("XPT_DEBUG CCB failed with status %#x",
5103 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
5105 "Debugging turned off\n");
5108 "Debugging enabled for "
5110 bus, target, (uintmax_t)lun);
5120 tagcontrol(struct cam_device *device, int argc, char **argv,
5130 ccb = cam_getccb(device);
5133 warnx("tagcontrol: error allocating ccb");
5137 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5140 numtags = strtol(optarg, NULL, 0);
5142 warnx("tag count %d is < 0", numtags);
5144 goto tagcontrol_bailout;
5155 cam_path_string(device, pathstr, sizeof(pathstr));
5158 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
5159 ccb->ccb_h.func_code = XPT_REL_SIMQ;
5160 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5161 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5162 ccb->crs.openings = numtags;
5165 if (cam_send_ccb(device, ccb) < 0) {
5166 warn("error sending XPT_REL_SIMQ CCB");
5168 goto tagcontrol_bailout;
5171 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5172 warnx("XPT_REL_SIMQ CCB failed");
5173 cam_error_print(device, ccb, CAM_ESF_ALL,
5174 CAM_EPF_ALL, stderr);
5176 goto tagcontrol_bailout;
5181 fprintf(stdout, "%stagged openings now %d\n",
5182 pathstr, ccb->crs.openings);
5185 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5187 ccb->ccb_h.func_code = XPT_GDEV_STATS;
5189 if (cam_send_ccb(device, ccb) < 0) {
5190 warn("error sending XPT_GDEV_STATS CCB");
5192 goto tagcontrol_bailout;
5195 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5196 warnx("XPT_GDEV_STATS CCB failed");
5197 cam_error_print(device, ccb, CAM_ESF_ALL,
5198 CAM_EPF_ALL, stderr);
5200 goto tagcontrol_bailout;
5203 if (arglist & CAM_ARG_VERBOSE) {
5204 fprintf(stdout, "%s", pathstr);
5205 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5206 fprintf(stdout, "%s", pathstr);
5207 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5208 fprintf(stdout, "%s", pathstr);
5209 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5210 fprintf(stdout, "%s", pathstr);
5211 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5212 fprintf(stdout, "%s", pathstr);
5213 fprintf(stdout, "held %d\n", ccb->cgds.held);
5214 fprintf(stdout, "%s", pathstr);
5215 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5216 fprintf(stdout, "%s", pathstr);
5217 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5220 fprintf(stdout, "%s", pathstr);
5221 fprintf(stdout, "device openings: ");
5223 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5224 ccb->cgds.dev_active);
5234 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5238 cam_path_string(device, pathstr, sizeof(pathstr));
5240 if (cts->transport == XPORT_SPI) {
5241 struct ccb_trans_settings_spi *spi =
5242 &cts->xport_specific.spi;
5244 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5246 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5249 if (spi->sync_offset != 0) {
5252 freq = scsi_calc_syncsrate(spi->sync_period);
5253 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5254 pathstr, freq / 1000, freq % 1000);
5258 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5259 fprintf(stdout, "%soffset: %d\n", pathstr,
5263 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5264 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5265 (0x01 << spi->bus_width) * 8);
5268 if (spi->valid & CTS_SPI_VALID_DISC) {
5269 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5270 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5271 "enabled" : "disabled");
5274 if (cts->transport == XPORT_FC) {
5275 struct ccb_trans_settings_fc *fc =
5276 &cts->xport_specific.fc;
5278 if (fc->valid & CTS_FC_VALID_WWNN)
5279 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5280 (long long) fc->wwnn);
5281 if (fc->valid & CTS_FC_VALID_WWPN)
5282 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5283 (long long) fc->wwpn);
5284 if (fc->valid & CTS_FC_VALID_PORT)
5285 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5286 if (fc->valid & CTS_FC_VALID_SPEED)
5287 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5288 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5290 if (cts->transport == XPORT_SAS) {
5291 struct ccb_trans_settings_sas *sas =
5292 &cts->xport_specific.sas;
5294 if (sas->valid & CTS_SAS_VALID_SPEED)
5295 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5296 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5298 if (cts->transport == XPORT_ATA) {
5299 struct ccb_trans_settings_pata *pata =
5300 &cts->xport_specific.ata;
5302 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5303 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5304 ata_mode2string(pata->mode));
5306 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5307 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5310 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5311 fprintf(stdout, "%sPIO transaction length: %d\n",
5312 pathstr, pata->bytecount);
5315 if (cts->transport == XPORT_SATA) {
5316 struct ccb_trans_settings_sata *sata =
5317 &cts->xport_specific.sata;
5319 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5320 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5323 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5324 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5325 ata_mode2string(sata->mode));
5327 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5328 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5331 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5332 fprintf(stdout, "%sPIO transaction length: %d\n",
5333 pathstr, sata->bytecount);
5335 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5336 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5339 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5340 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5343 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5344 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5348 if (cts->protocol == PROTO_ATA) {
5349 struct ccb_trans_settings_ata *ata=
5350 &cts->proto_specific.ata;
5352 if (ata->valid & CTS_ATA_VALID_TQ) {
5353 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5354 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5355 "enabled" : "disabled");
5358 if (cts->protocol == PROTO_SCSI) {
5359 struct ccb_trans_settings_scsi *scsi=
5360 &cts->proto_specific.scsi;
5362 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5363 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5364 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5365 "enabled" : "disabled");
5369 if (cts->protocol == PROTO_NVME) {
5370 struct ccb_trans_settings_nvme *nvmex =
5371 &cts->xport_specific.nvme;
5373 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5374 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5375 NVME_MAJOR(nvmex->spec),
5376 NVME_MINOR(nvmex->spec));
5378 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5379 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5380 nvmex->lanes, nvmex->max_lanes);
5381 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5382 nvmex->speed, nvmex->max_speed);
5389 * Get a path inquiry CCB for the specified device.
5392 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5397 ccb = cam_getccb(device);
5399 warnx("get_cpi: couldn't allocate CCB");
5402 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5403 ccb->ccb_h.func_code = XPT_PATH_INQ;
5404 if (cam_send_ccb(device, ccb) < 0) {
5405 warn("get_cpi: error sending Path Inquiry CCB");
5407 goto get_cpi_bailout;
5409 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5410 if (arglist & CAM_ARG_VERBOSE)
5411 cam_error_print(device, ccb, CAM_ESF_ALL,
5412 CAM_EPF_ALL, stderr);
5414 goto get_cpi_bailout;
5416 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5424 * Get a get device CCB for the specified device.
5427 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5432 ccb = cam_getccb(device);
5434 warnx("get_cgd: couldn't allocate CCB");
5437 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5438 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5439 if (cam_send_ccb(device, ccb) < 0) {
5440 warn("get_cgd: error sending Get type information CCB");
5442 goto get_cgd_bailout;
5444 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5445 if (arglist & CAM_ARG_VERBOSE)
5446 cam_error_print(device, ccb, CAM_ESF_ALL,
5447 CAM_EPF_ALL, stderr);
5449 goto get_cgd_bailout;
5451 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5459 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5463 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5464 int timeout, int verbosemode)
5466 union ccb *ccb = NULL;
5467 struct scsi_vpd_supported_page_list sup_pages;
5471 ccb = cam_getccb(dev);
5473 warn("Unable to allocate CCB");
5478 /* cam_getccb cleans up the header, caller has to zero the payload */
5479 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5481 bzero(&sup_pages, sizeof(sup_pages));
5483 scsi_inquiry(&ccb->csio,
5484 /*retries*/ retry_count,
5486 /* tag_action */ MSG_SIMPLE_Q_TAG,
5487 /* inq_buf */ (u_int8_t *)&sup_pages,
5488 /* inq_len */ sizeof(sup_pages),
5490 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5491 /* sense_len */ SSD_FULL_SIZE,
5492 /* timeout */ timeout ? timeout : 5000);
5494 /* Disable freezing the device queue */
5495 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5497 if (retry_count != 0)
5498 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5500 if (cam_send_ccb(dev, ccb) < 0) {
5507 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5508 if (verbosemode != 0)
5509 cam_error_print(dev, ccb, CAM_ESF_ALL,
5510 CAM_EPF_ALL, stderr);
5515 for (i = 0; i < sup_pages.length; i++) {
5516 if (sup_pages.list[i] == page_id) {
5529 * devtype is filled in with the type of device.
5530 * Returns 0 for success, non-zero for failure.
5533 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5534 int verbosemode, camcontrol_devtype *devtype)
5536 struct ccb_getdev cgd;
5539 retval = get_cgd(dev, &cgd);
5543 switch (cgd.protocol) {
5549 *devtype = CC_DT_ATA;
5551 break; /*NOTREACHED*/
5553 *devtype = CC_DT_NVME;
5555 break; /*NOTREACHED*/
5557 *devtype = CC_DT_MMCSD;
5559 break; /*NOTREACHED*/
5561 *devtype = CC_DT_UNKNOWN;
5563 break; /*NOTREACHED*/
5566 if (retry_count == -1) {
5568 * For a retry count of -1, used only the cached data to avoid
5569 * I/O to the drive. Sending the identify command to the drive
5570 * can cause issues for SATL attachaed drives since identify is
5571 * not an NCQ command.
5573 if (cgd.ident_data.config != 0)
5574 *devtype = CC_DT_SATL;
5576 *devtype = CC_DT_SCSI;
5579 * Check for the ATA Information VPD page (0x89). If this is an
5580 * ATA device behind a SCSI to ATA translation layer (SATL),
5581 * this VPD page should be present.
5583 * If that VPD page isn't present, or we get an error back from
5584 * the INQUIRY command, we'll just treat it as a normal SCSI
5587 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5588 timeout, verbosemode);
5590 *devtype = CC_DT_SATL;
5592 *devtype = CC_DT_SCSI;
5601 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5602 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5603 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5604 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5605 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5606 int is48bit, camcontrol_devtype devtype)
5610 if (devtype == CC_DT_ATA) {
5611 cam_fill_ataio(&ccb->ataio,
5612 /*retries*/ retry_count,
5615 /*tag_action*/ tag_action,
5616 /*data_ptr*/ data_ptr,
5617 /*dxfer_len*/ dxfer_len,
5618 /*timeout*/ timeout);
5619 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5620 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5623 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5626 if (auxiliary != 0) {
5627 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5628 ccb->ataio.aux = auxiliary;
5631 if (ata_flags & AP_FLAG_CHK_COND)
5632 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5634 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5635 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5636 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5637 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5639 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5640 protocol |= AP_EXTEND;
5642 retval = scsi_ata_pass(&ccb->csio,
5643 /*retries*/ retry_count,
5646 /*tag_action*/ tag_action,
5647 /*protocol*/ protocol,
5648 /*ata_flags*/ ata_flags,
5649 /*features*/ features,
5650 /*sector_count*/ sector_count,
5652 /*command*/ command,
5655 /*auxiliary*/ auxiliary,
5657 /*data_ptr*/ data_ptr,
5658 /*dxfer_len*/ dxfer_len,
5659 /*cdb_storage*/ cdb_storage,
5660 /*cdb_storage_len*/ cdb_storage_len,
5661 /*minimum_cmd_size*/ 0,
5662 /*sense_len*/ sense_len,
5663 /*timeout*/ timeout);
5670 * Returns: 0 -- success, 1 -- error, 2 -- lba truncated,
5671 * 4 -- count truncated, 6 -- lba and count truncated.
5674 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5675 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5679 switch (ccb->ccb_h.func_code) {
5682 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5686 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5687 * or 16 byte, and need to see what
5689 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5690 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5692 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5693 if ((opcode != ATA_PASS_12)
5694 && (opcode != ATA_PASS_16)) {
5695 warnx("%s: unsupported opcode %02x", __func__, opcode);
5699 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5701 /* Note: the _ccb() variant returns 0 for an error */
5705 sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
5706 switch (error_code) {
5707 case SSD_DESC_CURRENT_ERROR:
5708 case SSD_DESC_DEFERRED_ERROR: {
5709 struct scsi_sense_data_desc *sense;
5710 struct scsi_sense_ata_ret_desc *desc;
5713 sense = (struct scsi_sense_data_desc *)
5714 &ccb->csio.sense_data;
5716 desc_ptr = scsi_find_desc(sense, sense_len,
5718 if (desc_ptr == NULL) {
5719 cam_error_print(dev, ccb, CAM_ESF_ALL,
5720 CAM_EPF_ALL, stderr);
5723 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5725 *error = desc->error;
5726 *count = (desc->count_15_8 << 8) |
5728 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5729 ((uint64_t)desc->lba_39_32 << 32) |
5730 ((uint64_t)desc->lba_31_24 << 24) |
5731 (desc->lba_23_16 << 16) |
5732 (desc->lba_15_8 << 8) |
5734 *device = desc->device;
5735 *status = desc->status;
5738 * If the extend bit isn't set, the result is for a
5739 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5740 * command without the extend bit set. This means
5741 * that the device is supposed to return 28-bit
5742 * status. The count field is only 8 bits, and the
5743 * LBA field is only 8 bits.
5745 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5751 case SSD_CURRENT_ERROR:
5752 case SSD_DEFERRED_ERROR: {
5756 * In my understanding of SAT-5 specification, saying:
5757 * "without interpreting the contents of the STATUS",
5758 * this should not happen if CK_COND was set, but it
5759 * does at least for some devices, so try to revert.
5761 if ((sense_key == SSD_KEY_ABORTED_COMMAND) &&
5762 (asc == 0) && (ascq == 0)) {
5763 *status = ATA_STATUS_ERROR;
5764 *error = ATA_ERROR_ABORT;
5771 if ((sense_key != SSD_KEY_RECOVERED_ERROR) ||
5772 (asc != 0x00) || (ascq != 0x1d))
5776 scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5777 SSD_DESC_INFO, &val, NULL);
5778 *error = (val >> 24) & 0xff;
5779 *status = (val >> 16) & 0xff;
5780 *device = (val >> 8) & 0xff;
5781 *count = val & 0xff;
5784 scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5785 SSD_DESC_COMMAND, &val, NULL);
5786 *lba = ((val >> 16) & 0xff) | (val & 0xff00) |
5787 ((val & 0xff) << 16);
5789 /* Report UPPER NONZERO bits as errors 2, 4 and 6. */
5790 return ((val >> 28) & 0x06);
5799 struct ata_res *res;
5801 /* Only some statuses return ATA result register set. */
5802 if (cam_ccb_status(ccb) != CAM_REQ_CMP &&
5803 cam_ccb_status(ccb) != CAM_ATA_STATUS_ERROR)
5806 res = &ccb->ataio.res;
5807 *error = res->error;
5808 *status = res->status;
5809 *device = res->device;
5810 *count = res->sector_count;
5811 *lba = (res->lba_high << 16) |
5812 (res->lba_mid << 8) |
5814 if (ccb->ataio.cmd.flags & CAM_ATAIO_48BIT) {
5815 *count |= (res->sector_count_exp << 8);
5816 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5817 ((uint64_t)res->lba_mid_exp << 32) |
5818 ((uint64_t)res->lba_high_exp << 40);
5820 *lba |= (res->device & 0xf) << 24;
5831 cpi_print(struct ccb_pathinq *cpi)
5833 char adapter_str[1024];
5836 snprintf(adapter_str, sizeof(adapter_str),
5837 "%s%d:", cpi->dev_name, cpi->unit_number);
5839 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5842 for (i = 1; i < UINT8_MAX; i = i << 1) {
5845 if ((i & cpi->hba_inquiry) == 0)
5848 fprintf(stdout, "%s supports ", adapter_str);
5852 str = "MDP message";
5855 str = "32 bit wide SCSI";
5858 str = "16 bit wide SCSI";
5861 str = "SDTR message";
5864 str = "linked CDBs";
5867 str = "tag queue messages";
5870 str = "soft reset alternative";
5873 str = "SATA Port Multiplier";
5876 str = "unknown PI bit set";
5879 fprintf(stdout, "%s\n", str);
5882 for (i = 1; i < UINT32_MAX; i = i << 1) {
5885 if ((i & cpi->hba_misc) == 0)
5888 fprintf(stdout, "%s ", adapter_str);
5892 str = "can understand ata_ext requests";
5895 str = "64bit extended LUNs supported";
5898 str = "bus scans from high ID to low ID";
5901 str = "removable devices not included in scan";
5903 case PIM_NOINITIATOR:
5904 str = "initiator role not supported";
5906 case PIM_NOBUSRESET:
5907 str = "user has disabled initial BUS RESET or"
5908 " controller is in target/mixed mode";
5911 str = "do not send 6-byte commands";
5914 str = "scan bus sequentially";
5917 str = "unmapped I/O supported";
5920 str = "does its own scanning";
5923 str = "unknown PIM bit set";
5926 fprintf(stdout, "%s\n", str);
5929 for (i = 1; i < UINT16_MAX; i = i << 1) {
5932 if ((i & cpi->target_sprt) == 0)
5935 fprintf(stdout, "%s supports ", adapter_str);
5938 str = "target mode processor mode";
5941 str = "target mode phase cog. mode";
5943 case PIT_DISCONNECT:
5944 str = "disconnects in target mode";
5947 str = "terminate I/O message in target mode";
5950 str = "group 6 commands in target mode";
5953 str = "group 7 commands in target mode";
5956 str = "unknown PIT bit set";
5960 fprintf(stdout, "%s\n", str);
5962 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5964 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5966 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5968 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5969 adapter_str, cpi->hpath_id);
5970 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5972 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5973 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5974 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5975 adapter_str, cpi->hba_vendor);
5976 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5977 adapter_str, cpi->hba_device);
5978 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5979 adapter_str, cpi->hba_subvendor);
5980 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5981 adapter_str, cpi->hba_subdevice);
5982 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5983 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5984 if (cpi->base_transfer_speed > 1000)
5985 fprintf(stdout, "%d.%03dMB/sec\n",
5986 cpi->base_transfer_speed / 1000,
5987 cpi->base_transfer_speed % 1000);
5989 fprintf(stdout, "%dKB/sec\n",
5990 (cpi->base_transfer_speed % 1000) * 1000);
5991 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5992 adapter_str, cpi->maxio);
5996 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5997 struct ccb_trans_settings *cts)
6003 ccb = cam_getccb(device);
6006 warnx("get_print_cts: error allocating ccb");
6010 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
6012 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
6014 if (user_settings == 0)
6015 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
6017 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
6019 if (cam_send_ccb(device, ccb) < 0) {
6020 warn("error sending XPT_GET_TRAN_SETTINGS CCB");
6022 goto get_print_cts_bailout;
6025 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6026 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
6027 if (arglist & CAM_ARG_VERBOSE)
6028 cam_error_print(device, ccb, CAM_ESF_ALL,
6029 CAM_EPF_ALL, stderr);
6031 goto get_print_cts_bailout;
6035 cts_print(device, &ccb->cts);
6038 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
6040 get_print_cts_bailout:
6048 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
6049 int timeout, int argc, char **argv, char *combinedopt)
6053 int user_settings = 0;
6055 int disc_enable = -1, tag_enable = -1;
6058 double syncrate = -1;
6061 int change_settings = 0, send_tur = 0;
6062 struct ccb_pathinq cpi;
6064 ccb = cam_getccb(device);
6066 warnx("ratecontrol: error allocating ccb");
6069 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6078 if (strncasecmp(optarg, "enable", 6) == 0)
6080 else if (strncasecmp(optarg, "disable", 7) == 0)
6083 warnx("-D argument \"%s\" is unknown", optarg);
6085 goto ratecontrol_bailout;
6087 change_settings = 1;
6090 mode = ata_string2mode(optarg);
6092 warnx("unknown mode '%s'", optarg);
6094 goto ratecontrol_bailout;
6096 change_settings = 1;
6099 offset = strtol(optarg, NULL, 0);
6101 warnx("offset value %d is < 0", offset);
6103 goto ratecontrol_bailout;
6105 change_settings = 1;
6111 syncrate = atof(optarg);
6113 warnx("sync rate %f is < 0", syncrate);
6115 goto ratecontrol_bailout;
6117 change_settings = 1;
6120 if (strncasecmp(optarg, "enable", 6) == 0)
6122 else if (strncasecmp(optarg, "disable", 7) == 0)
6125 warnx("-T argument \"%s\" is unknown", optarg);
6127 goto ratecontrol_bailout;
6129 change_settings = 1;
6135 bus_width = strtol(optarg, NULL, 0);
6136 if (bus_width < 0) {
6137 warnx("bus width %d is < 0", bus_width);
6139 goto ratecontrol_bailout;
6141 change_settings = 1;
6148 * Grab path inquiry information, so we can determine whether
6149 * or not the initiator is capable of the things that the user
6152 if ((retval = get_cpi(device, &cpi)) != 0)
6153 goto ratecontrol_bailout;
6154 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
6156 fprintf(stdout, "%s parameters:\n",
6157 user_settings ? "User" : "Current");
6159 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
6161 goto ratecontrol_bailout;
6163 if (arglist & CAM_ARG_VERBOSE)
6166 if (change_settings) {
6167 int didsettings = 0;
6168 struct ccb_trans_settings_spi *spi = NULL;
6169 struct ccb_trans_settings_pata *pata = NULL;
6170 struct ccb_trans_settings_sata *sata = NULL;
6171 struct ccb_trans_settings_ata *ata = NULL;
6172 struct ccb_trans_settings_scsi *scsi = NULL;
6174 if (ccb->cts.transport == XPORT_SPI)
6175 spi = &ccb->cts.xport_specific.spi;
6176 if (ccb->cts.transport == XPORT_ATA)
6177 pata = &ccb->cts.xport_specific.ata;
6178 if (ccb->cts.transport == XPORT_SATA)
6179 sata = &ccb->cts.xport_specific.sata;
6180 if (ccb->cts.protocol == PROTO_ATA)
6181 ata = &ccb->cts.proto_specific.ata;
6182 if (ccb->cts.protocol == PROTO_SCSI)
6183 scsi = &ccb->cts.proto_specific.scsi;
6184 ccb->cts.xport_specific.valid = 0;
6185 ccb->cts.proto_specific.valid = 0;
6186 if (spi && disc_enable != -1) {
6187 spi->valid |= CTS_SPI_VALID_DISC;
6188 if (disc_enable == 0)
6189 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6191 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6194 if (tag_enable != -1) {
6195 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6196 warnx("HBA does not support tagged queueing, "
6197 "so you cannot modify tag settings");
6199 goto ratecontrol_bailout;
6202 ata->valid |= CTS_SCSI_VALID_TQ;
6203 if (tag_enable == 0)
6204 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6206 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6209 scsi->valid |= CTS_SCSI_VALID_TQ;
6210 if (tag_enable == 0)
6211 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6213 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6217 if (spi && offset != -1) {
6218 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6219 warnx("HBA is not capable of changing offset");
6221 goto ratecontrol_bailout;
6223 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6224 spi->sync_offset = offset;
6227 if (spi && syncrate != -1) {
6228 int prelim_sync_period;
6230 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6231 warnx("HBA is not capable of changing "
6234 goto ratecontrol_bailout;
6236 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6238 * The sync rate the user gives us is in MHz.
6239 * We need to translate it into KHz for this
6244 * Next, we calculate a "preliminary" sync period
6245 * in tenths of a nanosecond.
6248 prelim_sync_period = 0;
6250 prelim_sync_period = 10000000 / syncrate;
6252 scsi_calc_syncparam(prelim_sync_period);
6255 if (sata && syncrate != -1) {
6256 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6257 warnx("HBA is not capable of changing "
6260 goto ratecontrol_bailout;
6262 if (!user_settings) {
6263 warnx("You can modify only user rate "
6264 "settings for SATA");
6266 goto ratecontrol_bailout;
6268 sata->revision = ata_speed2revision(syncrate * 100);
6269 if (sata->revision < 0) {
6270 warnx("Invalid rate %f", syncrate);
6272 goto ratecontrol_bailout;
6274 sata->valid |= CTS_SATA_VALID_REVISION;
6277 if ((pata || sata) && mode != -1) {
6278 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6279 warnx("HBA is not capable of changing "
6282 goto ratecontrol_bailout;
6284 if (!user_settings) {
6285 warnx("You can modify only user mode "
6286 "settings for ATA/SATA");
6288 goto ratecontrol_bailout;
6292 pata->valid |= CTS_ATA_VALID_MODE;
6295 sata->valid |= CTS_SATA_VALID_MODE;
6300 * The bus_width argument goes like this:
6304 * Therefore, if you shift the number of bits given on the
6305 * command line right by 4, you should get the correct
6308 if (spi && bus_width != -1) {
6310 * We might as well validate things here with a
6311 * decipherable error message, rather than what
6312 * will probably be an indecipherable error message
6313 * by the time it gets back to us.
6315 if ((bus_width == 16)
6316 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6317 warnx("HBA does not support 16 bit bus width");
6319 goto ratecontrol_bailout;
6320 } else if ((bus_width == 32)
6321 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6322 warnx("HBA does not support 32 bit bus width");
6324 goto ratecontrol_bailout;
6325 } else if ((bus_width != 8)
6326 && (bus_width != 16)
6327 && (bus_width != 32)) {
6328 warnx("Invalid bus width %d", bus_width);
6330 goto ratecontrol_bailout;
6332 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6333 spi->bus_width = bus_width >> 4;
6336 if (didsettings == 0) {
6337 goto ratecontrol_bailout;
6339 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6340 if (cam_send_ccb(device, ccb) < 0) {
6341 warn("error sending XPT_SET_TRAN_SETTINGS CCB");
6343 goto ratecontrol_bailout;
6345 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6346 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6347 if (arglist & CAM_ARG_VERBOSE) {
6348 cam_error_print(device, ccb, CAM_ESF_ALL,
6349 CAM_EPF_ALL, stderr);
6352 goto ratecontrol_bailout;
6356 retval = testunitready(device, task_attr, retry_count, timeout,
6357 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6359 * If the TUR didn't succeed, just bail.
6363 fprintf(stderr, "Test Unit Ready failed\n");
6364 goto ratecontrol_bailout;
6367 if ((change_settings || send_tur) && !quiet &&
6368 (ccb->cts.transport == XPORT_ATA ||
6369 ccb->cts.transport == XPORT_SATA || send_tur)) {
6370 fprintf(stdout, "New parameters:\n");
6371 retval = get_print_cts(device, user_settings, 0, NULL);
6374 ratecontrol_bailout:
6380 scsiformat(struct cam_device *device, int argc, char **argv,
6381 char *combinedopt, int task_attr, int retry_count, int timeout)
6385 int ycount = 0, quiet = 0;
6386 int error = 0, retval = 0;
6387 int use_timeout = 10800 * 1000;
6389 struct format_defect_list_header fh;
6390 u_int8_t *data_ptr = NULL;
6391 u_int32_t dxfer_len = 0;
6393 int num_warnings = 0;
6396 ccb = cam_getccb(device);
6399 warnx("scsiformat: error allocating ccb");
6403 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6405 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6425 if (quiet == 0 && ycount == 0) {
6426 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6427 "following device:\n");
6429 error = scsidoinquiry(device, argc, argv, combinedopt,
6430 task_attr, retry_count, timeout);
6433 warnx("scsiformat: error sending inquiry");
6434 goto scsiformat_bailout;
6439 if (!get_confirmation()) {
6441 goto scsiformat_bailout;
6446 use_timeout = timeout;
6449 fprintf(stdout, "Current format timeout is %d seconds\n",
6450 use_timeout / 1000);
6454 * If the user hasn't disabled questions and didn't specify a
6455 * timeout on the command line, ask them if they want the current
6459 && (timeout == 0)) {
6461 int new_timeout = 0;
6463 fprintf(stdout, "Enter new timeout in seconds or press\n"
6464 "return to keep the current timeout [%d] ",
6465 use_timeout / 1000);
6467 if (fgets(str, sizeof(str), stdin) != NULL) {
6469 new_timeout = atoi(str);
6472 if (new_timeout != 0) {
6473 use_timeout = new_timeout * 1000;
6474 fprintf(stdout, "Using new timeout value %d\n",
6475 use_timeout / 1000);
6480 * Keep this outside the if block below to silence any unused
6481 * variable warnings.
6483 bzero(&fh, sizeof(fh));
6486 * If we're in immediate mode, we've got to include the format
6489 if (immediate != 0) {
6490 fh.byte2 = FU_DLH_IMMED;
6491 data_ptr = (u_int8_t *)&fh;
6492 dxfer_len = sizeof(fh);
6493 byte2 = FU_FMT_DATA;
6494 } else if (quiet == 0) {
6495 fprintf(stdout, "Formatting...");
6499 scsi_format_unit(&ccb->csio,
6500 /* retries */ retry_count,
6502 /* tag_action */ task_attr,
6505 /* data_ptr */ data_ptr,
6506 /* dxfer_len */ dxfer_len,
6507 /* sense_len */ SSD_FULL_SIZE,
6508 /* timeout */ use_timeout);
6510 /* Disable freezing the device queue */
6511 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6513 if (arglist & CAM_ARG_ERR_RECOVER)
6514 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6516 if (((retval = cam_send_ccb(device, ccb)) < 0)
6517 || ((immediate == 0)
6518 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6519 const char errstr[] = "error sending format command";
6526 if (arglist & CAM_ARG_VERBOSE) {
6527 cam_error_print(device, ccb, CAM_ESF_ALL,
6528 CAM_EPF_ALL, stderr);
6531 goto scsiformat_bailout;
6535 * If we ran in non-immediate mode, we already checked for errors
6536 * above and printed out any necessary information. If we're in
6537 * immediate mode, we need to loop through and get status
6538 * information periodically.
6540 if (immediate == 0) {
6542 fprintf(stdout, "Format Complete\n");
6544 goto scsiformat_bailout;
6551 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6554 * There's really no need to do error recovery or
6555 * retries here, since we're just going to sit in a
6556 * loop and wait for the device to finish formatting.
6558 scsi_test_unit_ready(&ccb->csio,
6561 /* tag_action */ task_attr,
6562 /* sense_len */ SSD_FULL_SIZE,
6563 /* timeout */ 5000);
6565 /* Disable freezing the device queue */
6566 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6568 retval = cam_send_ccb(device, ccb);
6571 * If we get an error from the ioctl, bail out. SCSI
6572 * errors are expected.
6575 warn("error sending TEST UNIT READY command");
6577 goto scsiformat_bailout;
6580 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6582 if ((status != CAM_REQ_CMP)
6583 && (status == CAM_SCSI_STATUS_ERROR)
6584 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6585 struct scsi_sense_data *sense;
6586 int error_code, sense_key, asc, ascq;
6588 sense = &ccb->csio.sense_data;
6589 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6590 ccb->csio.sense_resid, &error_code, &sense_key,
6591 &asc, &ascq, /*show_errors*/ 1);
6594 * According to the SCSI-2 and SCSI-3 specs, a
6595 * drive that is in the middle of a format should
6596 * return NOT READY with an ASC of "logical unit
6597 * not ready, format in progress". The sense key
6598 * specific bytes will then be a progress indicator.
6600 if ((sense_key == SSD_KEY_NOT_READY)
6601 && (asc == 0x04) && (ascq == 0x04)) {
6604 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6605 ccb->csio.sense_resid, sks) == 0)
6608 u_int64_t percentage;
6610 val = scsi_2btoul(&sks[1]);
6611 percentage = 10000ull * val;
6614 "\rFormatting: %ju.%02u %% "
6616 (uintmax_t)(percentage /
6618 (unsigned)((percentage /
6622 } else if ((quiet == 0)
6623 && (++num_warnings <= 1)) {
6624 warnx("Unexpected SCSI Sense Key "
6625 "Specific value returned "
6627 scsi_sense_print(device, &ccb->csio,
6629 warnx("Unable to print status "
6630 "information, but format will "
6632 warnx("will exit when format is "
6637 warnx("Unexpected SCSI error during format");
6638 cam_error_print(device, ccb, CAM_ESF_ALL,
6639 CAM_EPF_ALL, stderr);
6641 goto scsiformat_bailout;
6644 } else if (status != CAM_REQ_CMP) {
6645 warnx("Unexpected CAM status %#x", status);
6646 if (arglist & CAM_ARG_VERBOSE)
6647 cam_error_print(device, ccb, CAM_ESF_ALL,
6648 CAM_EPF_ALL, stderr);
6650 goto scsiformat_bailout;
6653 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6656 fprintf(stdout, "\nFormat Complete\n");
6666 sanitize_wait_ata(struct cam_device *device, union ccb *ccb, int quiet,
6667 camcontrol_devtype devtype)
6670 uint8_t error = 0, ata_device = 0, status = 0;
6676 retval = build_ata_cmd(ccb,
6678 /*flags*/ CAM_DIR_NONE,
6679 /*tag_action*/ MSG_SIMPLE_Q_TAG,
6680 /*protocol*/ AP_PROTO_NON_DATA,
6681 /*ata_flags*/ AP_FLAG_CHK_COND,
6682 /*features*/ 0x00, /* SANITIZE STATUS EXT */
6685 /*command*/ ATA_SANITIZE,
6689 /*cdb_storage*/ NULL,
6690 /*cdb_storage_len*/ 0,
6691 /*sense_len*/ SSD_FULL_SIZE,
6694 /*devtype*/ devtype);
6696 warnx("%s: build_ata_cmd() failed, likely "
6697 "programmer error", __func__);
6701 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6702 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6703 retval = cam_send_ccb(device, ccb);
6705 warn("error sending SANITIZE STATUS EXT command");
6709 retval = get_ata_status(device, ccb, &error, &count, &lba,
6710 &ata_device, &status);
6712 warnx("Can't get SANITIZE STATUS EXT status, "
6713 "sanitize may still run.");
6716 if (status & ATA_STATUS_ERROR) {
6717 warnx("SANITIZE STATUS EXT failed, "
6718 "sanitize may still run.");
6721 if (count & 0x4000) {
6726 "Sanitizing: %u.%02u%% (%d/%d)\r",
6727 (perc / (0x10000 * 100)),
6728 ((perc / 0x10000) % 100),
6733 } else if ((count & 0x8000) == 0) {
6734 warnx("Sanitize complete with an error. ");
6743 sanitize_wait_scsi(struct cam_device *device, union ccb *ccb, int task_attr, int quiet)
6745 int warnings = 0, retval;
6750 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6753 * There's really no need to do error recovery or
6754 * retries here, since we're just going to sit in a
6755 * loop and wait for the device to finish sanitizing.
6757 scsi_test_unit_ready(&ccb->csio,
6760 /* tag_action */ task_attr,
6761 /* sense_len */ SSD_FULL_SIZE,
6762 /* timeout */ 5000);
6764 /* Disable freezing the device queue */
6765 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6767 retval = cam_send_ccb(device, ccb);
6770 * If we get an error from the ioctl, bail out. SCSI
6771 * errors are expected.
6774 warn("error sending TEST UNIT READY command");
6778 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6779 if ((status == CAM_SCSI_STATUS_ERROR) &&
6780 ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6781 struct scsi_sense_data *sense;
6782 int error_code, sense_key, asc, ascq;
6784 sense = &ccb->csio.sense_data;
6785 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6786 ccb->csio.sense_resid, &error_code, &sense_key,
6787 &asc, &ascq, /*show_errors*/ 1);
6790 * According to the SCSI-3 spec, a drive that is in the
6791 * middle of a sanitize should return NOT READY with an
6792 * ASC of "logical unit not ready, sanitize in
6793 * progress". The sense key specific bytes will then
6794 * be a progress indicator.
6796 if ((sense_key == SSD_KEY_NOT_READY)
6797 && (asc == 0x04) && (ascq == 0x1b)) {
6800 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6801 ccb->csio.sense_resid, sks) == 0)
6803 val = scsi_2btoul(&sks[1]);
6806 "Sanitizing: %u.%02u%% (%d/%d)\r",
6807 (perc / (0x10000 * 100)),
6808 ((perc / 0x10000) % 100),
6811 } else if ((quiet == 0) && (++warnings <= 1)) {
6812 warnx("Unexpected SCSI Sense Key "
6813 "Specific value returned "
6814 "during sanitize:");
6815 scsi_sense_print(device, &ccb->csio,
6817 warnx("Unable to print status "
6818 "information, but sanitze will "
6820 warnx("will exit when sanitize is "
6825 warnx("Unexpected SCSI error during sanitize");
6826 cam_error_print(device, ccb, CAM_ESF_ALL,
6827 CAM_EPF_ALL, stderr);
6831 } else if (status != CAM_REQ_CMP && status != CAM_REQUEUE_REQ) {
6832 warnx("Unexpected CAM status %#x", status);
6833 if (arglist & CAM_ARG_VERBOSE)
6834 cam_error_print(device, ccb, CAM_ESF_ALL,
6835 CAM_EPF_ALL, stderr);
6838 } while ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6843 sanitize(struct cam_device *device, int argc, char **argv,
6844 char *combinedopt, int task_attr, int retry_count, int timeout)
6847 u_int8_t action = 0;
6849 int ycount = 0, quiet = 0;
6857 const char *pattern = NULL;
6858 u_int8_t *data_ptr = NULL;
6859 u_int32_t dxfer_len = 0;
6861 uint16_t feature, count;
6864 camcontrol_devtype dt;
6867 * Get the device type, request no I/O be done to do this.
6869 error = get_device_type(device, -1, 0, 0, &dt);
6870 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
6871 warnx("sanitize: can't get device type");
6875 ccb = cam_getccb(device);
6878 warnx("sanitize: error allocating ccb");
6882 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6884 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6887 if (strcasecmp(optarg, "overwrite") == 0)
6888 action = SSZ_SERVICE_ACTION_OVERWRITE;
6889 else if (strcasecmp(optarg, "block") == 0)
6890 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6891 else if (strcasecmp(optarg, "crypto") == 0)
6892 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6893 else if (strcasecmp(optarg, "exitfailure") == 0)
6894 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6896 warnx("invalid service operation \"%s\"",
6899 goto sanitize_bailout;
6903 passes = strtol(optarg, NULL, 0);
6904 if (passes < 1 || passes > 31) {
6905 warnx("invalid passes value %d", passes);
6907 goto sanitize_bailout;
6926 /* ATA supports only immediate commands. */
6927 if (dt == CC_DT_SCSI)
6940 warnx("an action is required");
6942 goto sanitize_bailout;
6943 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6944 struct scsi_sanitize_parameter_list *pl;
6948 if (pattern == NULL) {
6949 warnx("overwrite action requires -P argument");
6951 goto sanitize_bailout;
6953 fd = open(pattern, O_RDONLY);
6955 warn("cannot open pattern file %s", pattern);
6957 goto sanitize_bailout;
6959 if (fstat(fd, &sb) < 0) {
6960 warn("cannot stat pattern file %s", pattern);
6962 goto sanitize_bailout;
6965 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6966 warnx("pattern file size exceeds maximum value %d",
6967 SSZPL_MAX_PATTERN_LENGTH);
6969 goto sanitize_bailout;
6971 dxfer_len = sizeof(*pl) + sz;
6972 data_ptr = calloc(1, dxfer_len);
6973 if (data_ptr == NULL) {
6974 warnx("cannot allocate parameter list buffer");
6976 goto sanitize_bailout;
6979 amt = read(fd, data_ptr + sizeof(*pl), sz);
6981 warn("cannot read pattern file");
6983 goto sanitize_bailout;
6984 } else if (amt != sz) {
6985 warnx("short pattern file read");
6987 goto sanitize_bailout;
6990 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6996 pl->byte1 |= SSZPL_INVERT;
6997 scsi_ulto2b(sz, pl->length);
7003 else if (invert != 0)
7005 else if (pattern != NULL)
7010 warnx("%s argument only valid with overwrite "
7013 goto sanitize_bailout;
7017 if (quiet == 0 && ycount == 0) {
7018 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
7019 "following device:\n");
7021 if (dt == CC_DT_SCSI) {
7022 error = scsidoinquiry(device, argc, argv, combinedopt,
7023 task_attr, retry_count, timeout);
7024 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7025 struct ata_params *ident_buf;
7026 error = ata_do_identify(device, retry_count, timeout,
7029 printf("%s%d: ", device->device_name,
7030 device->dev_unit_num);
7031 ata_print_ident(ident_buf);
7038 warnx("sanitize: error sending inquiry");
7039 goto sanitize_bailout;
7044 if (!get_confirmation()) {
7046 goto sanitize_bailout;
7051 use_timeout = timeout;
7053 use_timeout = (immediate ? 10 : 10800) * 1000;
7055 if (immediate == 0 && quiet == 0) {
7056 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
7057 use_timeout / 1000);
7061 * If the user hasn't disabled questions and didn't specify a
7062 * timeout on the command line, ask them if they want the current
7065 if (immediate == 0 && ycount == 0 && timeout == 0) {
7067 int new_timeout = 0;
7069 fprintf(stdout, "Enter new timeout in seconds or press\n"
7070 "return to keep the current timeout [%d] ",
7071 use_timeout / 1000);
7073 if (fgets(str, sizeof(str), stdin) != NULL) {
7075 new_timeout = atoi(str);
7078 if (new_timeout != 0) {
7079 use_timeout = new_timeout * 1000;
7080 fprintf(stdout, "Using new timeout value %d\n",
7081 use_timeout / 1000);
7085 if (dt == CC_DT_SCSI) {
7088 byte2 |= SSZ_UNRESTRICTED_EXIT;
7091 scsi_sanitize(&ccb->csio,
7092 /* retries */ retry_count,
7094 /* tag_action */ task_attr,
7097 /* data_ptr */ data_ptr,
7098 /* dxfer_len */ dxfer_len,
7099 /* sense_len */ SSD_FULL_SIZE,
7100 /* timeout */ use_timeout);
7102 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7103 if (arglist & CAM_ARG_ERR_RECOVER)
7104 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7105 if (cam_send_ccb(device, ccb) < 0) {
7106 warn("error sending sanitize command");
7108 goto sanitize_bailout;
7110 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7111 if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
7112 feature = 0x14; /* OVERWRITE EXT */
7113 lba = 0x4F5700000000 | scsi_4btoul(data_ptr + 4);
7114 count = (passes == 0) ? 1 : (passes >= 16) ? 0 : passes;
7116 count |= 0x80; /* INVERT PATTERN */
7118 count |= 0x10; /* FAILURE MODE */
7119 } else if (action == SSZ_SERVICE_ACTION_BLOCK_ERASE) {
7120 feature = 0x12; /* BLOCK ERASE EXT */
7121 lba = 0x0000426B4572;
7124 count |= 0x10; /* FAILURE MODE */
7125 } else if (action == SSZ_SERVICE_ACTION_CRYPTO_ERASE) {
7126 feature = 0x11; /* CRYPTO SCRAMBLE EXT */
7127 lba = 0x000043727970;
7130 count |= 0x10; /* FAILURE MODE */
7131 } else if (action == SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE) {
7132 feature = 0x00; /* SANITIZE STATUS EXT */
7134 count = 1; /* CLEAR SANITIZE OPERATION FAILED */
7137 goto sanitize_bailout;
7140 error = ata_do_cmd(device,
7143 /*flags*/CAM_DIR_NONE,
7144 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
7146 /*tag_action*/MSG_SIMPLE_Q_TAG,
7147 /*command*/ATA_SANITIZE,
7148 /*features*/feature,
7150 /*sector_count*/count,
7153 /*timeout*/ use_timeout,
7157 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7158 struct scsi_sense_data *sense;
7159 int error_code, sense_key, asc, ascq;
7161 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
7162 CAM_SCSI_STATUS_ERROR) {
7163 sense = &ccb->csio.sense_data;
7164 scsi_extract_sense_len(sense, ccb->csio.sense_len -
7165 ccb->csio.sense_resid, &error_code, &sense_key,
7166 &asc, &ascq, /*show_errors*/ 1);
7168 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
7169 asc == 0x20 && ascq == 0x00)
7170 warnx("sanitize is not supported by "
7173 warnx("error sanitizing this device");
7175 warnx("error sanitizing this device");
7177 if (arglist & CAM_ARG_VERBOSE) {
7178 cam_error_print(device, ccb, CAM_ESF_ALL,
7179 CAM_EPF_ALL, stderr);
7182 goto sanitize_bailout;
7186 * If we ran in non-immediate mode, we already checked for errors
7187 * above and printed out any necessary information. If we're in
7188 * immediate mode, we need to loop through and get status
7189 * information periodically.
7191 if (immediate == 0) {
7193 fprintf(stdout, "Sanitize Complete\n");
7195 goto sanitize_bailout;
7199 if (dt == CC_DT_SCSI) {
7200 error = sanitize_wait_scsi(device, ccb, task_attr, quiet);
7201 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7202 error = sanitize_wait_ata(device, ccb, quiet, dt);
7205 if (error == 0 && quiet == 0)
7206 fprintf(stdout, "Sanitize Complete \n");
7211 if (data_ptr != NULL)
7219 scsireportluns(struct cam_device *device, int argc, char **argv,
7220 char *combinedopt, int task_attr, int retry_count, int timeout)
7223 int c, countonly, lunsonly;
7224 struct scsi_report_luns_data *lundata;
7226 uint8_t report_type;
7227 uint32_t list_len, i, j;
7232 report_type = RPL_REPORT_DEFAULT;
7233 ccb = cam_getccb(device);
7236 warnx("%s: error allocating ccb", __func__);
7240 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7245 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7254 if (strcasecmp(optarg, "default") == 0)
7255 report_type = RPL_REPORT_DEFAULT;
7256 else if (strcasecmp(optarg, "wellknown") == 0)
7257 report_type = RPL_REPORT_WELLKNOWN;
7258 else if (strcasecmp(optarg, "all") == 0)
7259 report_type = RPL_REPORT_ALL;
7261 warnx("%s: invalid report type \"%s\"",
7272 if ((countonly != 0)
7273 && (lunsonly != 0)) {
7274 warnx("%s: you can only specify one of -c or -l", __func__);
7279 * According to SPC-4, the allocation length must be at least 16
7280 * bytes -- enough for the header and one LUN.
7282 alloc_len = sizeof(*lundata) + 8;
7286 lundata = malloc(alloc_len);
7288 if (lundata == NULL) {
7289 warn("%s: error mallocing %d bytes", __func__, alloc_len);
7294 scsi_report_luns(&ccb->csio,
7295 /*retries*/ retry_count,
7297 /*tag_action*/ task_attr,
7298 /*select_report*/ report_type,
7299 /*rpl_buf*/ lundata,
7300 /*alloc_len*/ alloc_len,
7301 /*sense_len*/ SSD_FULL_SIZE,
7302 /*timeout*/ timeout ? timeout : 5000);
7304 /* Disable freezing the device queue */
7305 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7307 if (arglist & CAM_ARG_ERR_RECOVER)
7308 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7310 if (cam_send_ccb(device, ccb) < 0) {
7311 warn("error sending REPORT LUNS command");
7316 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7317 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7323 list_len = scsi_4btoul(lundata->length);
7326 * If we need to list the LUNs, and our allocation
7327 * length was too short, reallocate and retry.
7329 if ((countonly == 0)
7330 && (list_len > (alloc_len - sizeof(*lundata)))) {
7331 alloc_len = list_len + sizeof(*lundata);
7337 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7338 ((list_len / 8) > 1) ? "s" : "");
7343 for (i = 0; i < (list_len / 8); i++) {
7347 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7349 fprintf(stdout, ",");
7350 switch (lundata->luns[i].lundata[j] &
7351 RPL_LUNDATA_ATYP_MASK) {
7352 case RPL_LUNDATA_ATYP_PERIPH:
7353 if ((lundata->luns[i].lundata[j] &
7354 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7355 fprintf(stdout, "%d:",
7356 lundata->luns[i].lundata[j] &
7357 RPL_LUNDATA_PERIPH_BUS_MASK);
7359 && ((lundata->luns[i].lundata[j+2] &
7360 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7363 fprintf(stdout, "%d",
7364 lundata->luns[i].lundata[j+1]);
7366 case RPL_LUNDATA_ATYP_FLAT: {
7368 tmplun[0] = lundata->luns[i].lundata[j] &
7369 RPL_LUNDATA_FLAT_LUN_MASK;
7370 tmplun[1] = lundata->luns[i].lundata[j+1];
7372 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7376 case RPL_LUNDATA_ATYP_LUN:
7377 fprintf(stdout, "%d:%d:%d",
7378 (lundata->luns[i].lundata[j+1] &
7379 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7380 lundata->luns[i].lundata[j] &
7381 RPL_LUNDATA_LUN_TARG_MASK,
7382 lundata->luns[i].lundata[j+1] &
7383 RPL_LUNDATA_LUN_LUN_MASK);
7385 case RPL_LUNDATA_ATYP_EXTLUN: {
7386 int field_len_code, eam_code;
7388 eam_code = lundata->luns[i].lundata[j] &
7389 RPL_LUNDATA_EXT_EAM_MASK;
7390 field_len_code = (lundata->luns[i].lundata[j] &
7391 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7393 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7394 && (field_len_code == 0x00)) {
7395 fprintf(stdout, "%d",
7396 lundata->luns[i].lundata[j+1]);
7397 } else if ((eam_code ==
7398 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7399 && (field_len_code == 0x03)) {
7403 * This format takes up all 8 bytes.
7404 * If we aren't starting at offset 0,
7408 fprintf(stdout, "Invalid "
7411 "specified format", j);
7415 bzero(tmp_lun, sizeof(tmp_lun));
7416 bcopy(&lundata->luns[i].lundata[j+1],
7417 &tmp_lun[1], sizeof(tmp_lun) - 1);
7418 fprintf(stdout, "%#jx",
7419 (intmax_t)scsi_8btou64(tmp_lun));
7422 fprintf(stderr, "Unknown Extended LUN"
7423 "Address method %#x, length "
7424 "code %#x", eam_code,
7431 fprintf(stderr, "Unknown LUN address method "
7432 "%#x\n", lundata->luns[i].lundata[0] &
7433 RPL_LUNDATA_ATYP_MASK);
7437 * For the flat addressing method, there are no
7438 * other levels after it.
7443 fprintf(stdout, "\n");
7456 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7457 char *combinedopt, int task_attr, int retry_count, int timeout)
7460 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7461 struct scsi_read_capacity_data rcap;
7462 struct scsi_read_capacity_data_long rcaplong;
7477 ccb = cam_getccb(device);
7480 warnx("%s: error allocating ccb", __func__);
7484 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7486 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7516 if ((blocksizeonly != 0)
7517 && (numblocks != 0)) {
7518 warnx("%s: you can only specify one of -b or -N", __func__);
7523 if ((blocksizeonly != 0)
7524 && (sizeonly != 0)) {
7525 warnx("%s: you can only specify one of -b or -s", __func__);
7532 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7538 && (blocksizeonly != 0)) {
7539 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7547 scsi_read_capacity(&ccb->csio,
7548 /*retries*/ retry_count,
7550 /*tag_action*/ task_attr,
7553 /*timeout*/ timeout ? timeout : 5000);
7555 /* Disable freezing the device queue */
7556 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7558 if (arglist & CAM_ARG_ERR_RECOVER)
7559 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7561 if (cam_send_ccb(device, ccb) < 0) {
7562 warn("error sending READ CAPACITY command");
7567 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7568 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7573 maxsector = scsi_4btoul(rcap.addr);
7574 block_len = scsi_4btoul(rcap.length);
7577 * A last block of 2^32-1 means that the true capacity is over 2TB,
7578 * and we need to issue the long READ CAPACITY to get the real
7579 * capacity. Otherwise, we're all set.
7581 if (maxsector != 0xffffffff)
7585 scsi_read_capacity_16(&ccb->csio,
7586 /*retries*/ retry_count,
7588 /*tag_action*/ task_attr,
7592 /*rcap_buf*/ (uint8_t *)&rcaplong,
7593 /*rcap_buf_len*/ sizeof(rcaplong),
7594 /*sense_len*/ SSD_FULL_SIZE,
7595 /*timeout*/ timeout ? timeout : 5000);
7597 /* Disable freezing the device queue */
7598 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7600 if (arglist & CAM_ARG_ERR_RECOVER)
7601 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7603 if (cam_send_ccb(device, ccb) < 0) {
7604 warn("error sending READ CAPACITY (16) command");
7609 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7610 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7615 maxsector = scsi_8btou64(rcaplong.addr);
7616 block_len = scsi_4btoul(rcaplong.length);
7619 if (blocksizeonly == 0) {
7621 * Humanize implies !quiet, and also implies numblocks.
7623 if (humanize != 0) {
7628 tmpbytes = (maxsector + 1) * block_len;
7629 ret = humanize_number(tmpstr, sizeof(tmpstr),
7630 tmpbytes, "", HN_AUTOSCALE,
7633 HN_DIVISOR_1000 : 0));
7635 warnx("%s: humanize_number failed!", __func__);
7639 fprintf(stdout, "Device Size: %s%s", tmpstr,
7640 (sizeonly == 0) ? ", " : "\n");
7641 } else if (numblocks != 0) {
7642 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7643 "Blocks: " : "", (uintmax_t)maxsector + 1,
7644 (sizeonly == 0) ? ", " : "\n");
7646 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7647 "Last Block: " : "", (uintmax_t)maxsector,
7648 (sizeonly == 0) ? ", " : "\n");
7652 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7653 "Block Length: " : "", block_len, (quiet == 0) ?
7662 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7663 int retry_count, int timeout)
7667 uint8_t *smp_request = NULL, *smp_response = NULL;
7668 int request_size = 0, response_size = 0;
7669 int fd_request = 0, fd_response = 0;
7670 char *datastr = NULL;
7671 struct get_hook hook;
7676 * Note that at the moment we don't support sending SMP CCBs to
7677 * devices that aren't probed by CAM.
7679 ccb = cam_getccb(device);
7681 warnx("%s: error allocating CCB", __func__);
7685 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7687 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7690 arglist |= CAM_ARG_CMD_IN;
7691 response_size = strtol(optarg, NULL, 0);
7692 if (response_size <= 0) {
7693 warnx("invalid number of response bytes %d",
7696 goto smpcmd_bailout;
7698 hook.argc = argc - optind;
7699 hook.argv = argv + optind;
7702 datastr = cget(&hook, NULL);
7704 * If the user supplied "-" instead of a format, he
7705 * wants the data to be written to stdout.
7707 if ((datastr != NULL)
7708 && (datastr[0] == '-'))
7711 smp_response = (u_int8_t *)malloc(response_size);
7712 if (smp_response == NULL) {
7713 warn("can't malloc memory for SMP response");
7715 goto smpcmd_bailout;
7719 arglist |= CAM_ARG_CMD_OUT;
7720 request_size = strtol(optarg, NULL, 0);
7721 if (request_size <= 0) {
7722 warnx("invalid number of request bytes %d",
7725 goto smpcmd_bailout;
7727 hook.argc = argc - optind;
7728 hook.argv = argv + optind;
7730 datastr = cget(&hook, NULL);
7731 smp_request = (u_int8_t *)malloc(request_size);
7732 if (smp_request == NULL) {
7733 warn("can't malloc memory for SMP request");
7735 goto smpcmd_bailout;
7737 bzero(smp_request, request_size);
7739 * If the user supplied "-" instead of a format, he
7740 * wants the data to be read from stdin.
7742 if ((datastr != NULL)
7743 && (datastr[0] == '-'))
7746 buff_encode_visit(smp_request, request_size,
7757 * If fd_data is set, and we're writing to the device, we need to
7758 * read the data the user wants written from stdin.
7760 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7762 int amt_to_read = request_size;
7763 u_int8_t *buf_ptr = smp_request;
7765 for (amt_read = 0; amt_to_read > 0;
7766 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7767 if (amt_read == -1) {
7768 warn("error reading data from stdin");
7770 goto smpcmd_bailout;
7772 amt_to_read -= amt_read;
7773 buf_ptr += amt_read;
7777 if (((arglist & CAM_ARG_CMD_IN) == 0)
7778 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7779 warnx("%s: need both the request (-r) and response (-R) "
7780 "arguments", __func__);
7782 goto smpcmd_bailout;
7785 flags |= CAM_DEV_QFRZDIS;
7787 cam_fill_smpio(&ccb->smpio,
7788 /*retries*/ retry_count,
7791 /*smp_request*/ smp_request,
7792 /*smp_request_len*/ request_size,
7793 /*smp_response*/ smp_response,
7794 /*smp_response_len*/ response_size,
7795 /*timeout*/ timeout ? timeout : 5000);
7797 ccb->smpio.flags = SMP_FLAG_NONE;
7799 if (((retval = cam_send_ccb(device, ccb)) < 0)
7800 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7801 const char warnstr[] = "error sending command";
7808 if (arglist & CAM_ARG_VERBOSE) {
7809 cam_error_print(device, ccb, CAM_ESF_ALL,
7810 CAM_EPF_ALL, stderr);
7814 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7815 && (response_size > 0)) {
7816 if (fd_response == 0) {
7817 buff_decode_visit(smp_response, response_size,
7818 datastr, arg_put, NULL);
7819 fprintf(stdout, "\n");
7821 ssize_t amt_written;
7822 int amt_to_write = response_size;
7823 u_int8_t *buf_ptr = smp_response;
7825 for (amt_written = 0; (amt_to_write > 0) &&
7826 (amt_written = write(STDOUT_FILENO, buf_ptr,
7827 amt_to_write)) > 0;){
7828 amt_to_write -= amt_written;
7829 buf_ptr += amt_written;
7831 if (amt_written == -1) {
7832 warn("error writing data to stdout");
7834 goto smpcmd_bailout;
7835 } else if ((amt_written == 0)
7836 && (amt_to_write > 0)) {
7837 warnx("only wrote %u bytes out of %u",
7838 response_size - amt_to_write,
7847 if (smp_request != NULL)
7850 if (smp_response != NULL)
7857 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7858 int retry_count, int timeout)
7862 int32_t mmc_opcode = 0, mmc_arg = 0;
7863 int32_t mmc_flags = -1;
7866 int is_bw_4 = 0, is_bw_1 = 0;
7867 int is_highspeed = 0, is_stdspeed = 0;
7868 int is_info_request = 0;
7870 uint8_t mmc_data_byte = 0;
7872 /* For IO_RW_EXTENDED command */
7873 uint8_t *mmc_data = NULL;
7874 struct mmc_data mmc_d;
7875 int mmc_data_len = 0;
7878 * Note that at the moment we don't support sending SMP CCBs to
7879 * devices that aren't probed by CAM.
7881 ccb = cam_getccb(device);
7883 warnx("%s: error allocating CCB", __func__);
7887 bzero(&(&ccb->ccb_h)[1],
7888 sizeof(union ccb) - sizeof(struct ccb_hdr));
7890 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7899 if (!strcmp(optarg, "high"))
7905 is_info_request = 1;
7908 mmc_opcode = strtol(optarg, NULL, 0);
7909 if (mmc_opcode < 0) {
7910 warnx("invalid MMC opcode %d",
7913 goto mmccmd_bailout;
7917 mmc_arg = strtol(optarg, NULL, 0);
7919 warnx("invalid MMC arg %d",
7922 goto mmccmd_bailout;
7926 mmc_flags = strtol(optarg, NULL, 0);
7927 if (mmc_flags < 0) {
7928 warnx("invalid MMC flags %d",
7931 goto mmccmd_bailout;
7935 mmc_data_len = strtol(optarg, NULL, 0);
7936 if (mmc_data_len <= 0) {
7937 warnx("invalid MMC data len %d",
7940 goto mmccmd_bailout;
7947 mmc_data_byte = strtol(optarg, NULL, 0);
7953 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7955 /* If flags are left default, supply the right flags */
7957 switch (mmc_opcode) {
7958 case MMC_GO_IDLE_STATE:
7959 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7961 case IO_SEND_OP_COND:
7962 mmc_flags = MMC_RSP_R4;
7964 case SD_SEND_RELATIVE_ADDR:
7965 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7967 case MMC_SELECT_CARD:
7968 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7969 mmc_arg = mmc_arg << 16;
7971 case SD_IO_RW_DIRECT:
7972 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7973 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7975 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7977 case SD_IO_RW_EXTENDED:
7978 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7979 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7980 int len_arg = mmc_data_len;
7981 if (mmc_data_len == 512)
7985 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7987 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7990 mmc_flags = MMC_RSP_R1;
7994 // Switch bus width instead of sending IO command
7995 if (is_bw_4 || is_bw_1) {
7996 struct ccb_trans_settings_mmc *cts;
7997 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7998 ccb->ccb_h.flags = 0;
7999 cts = &ccb->cts.proto_specific.mmc;
8000 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
8001 cts->ios_valid = MMC_BW;
8002 if (((retval = cam_send_ccb(device, ccb)) < 0)
8003 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8004 warn("Error sending command");
8006 printf("Parameters set OK\n");
8012 // Switch bus speed instead of sending IO command
8013 if (is_stdspeed || is_highspeed) {
8014 struct ccb_trans_settings_mmc *cts;
8015 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
8016 ccb->ccb_h.flags = 0;
8017 cts = &ccb->cts.proto_specific.mmc;
8018 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
8019 cts->ios_valid = MMC_BT;
8020 if (((retval = cam_send_ccb(device, ccb)) < 0)
8021 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8022 warn("Error sending command");
8024 printf("Speed set OK (HS: %d)\n", is_highspeed);
8030 // Get information about controller and its settings
8031 if (is_info_request) {
8032 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
8033 ccb->ccb_h.flags = 0;
8034 struct ccb_trans_settings_mmc *cts;
8035 cts = &ccb->cts.proto_specific.mmc;
8036 if (((retval = cam_send_ccb(device, ccb)) < 0)
8037 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8038 warn("Error sending command");
8041 printf("Host controller information\n");
8042 printf("Host OCR: 0x%x\n", cts->host_ocr);
8043 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
8044 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
8045 printf("Supported bus width: ");
8046 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
8048 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
8050 printf("\nCurrent settings:\n");
8051 printf("Bus width: ");
8052 switch (cts->ios.bus_width) {
8063 printf("Freq: %d.%03d MHz%s\n",
8064 cts->ios.clock / 1000000,
8065 (cts->ios.clock / 1000) % 1000,
8066 cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : "");
8070 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
8072 if (mmc_data_len > 0) {
8073 flags |= CAM_DIR_IN;
8074 mmc_data = malloc(mmc_data_len);
8075 memset(mmc_data, 0, mmc_data_len);
8076 mmc_d.len = mmc_data_len;
8077 mmc_d.data = mmc_data;
8078 mmc_d.flags = MMC_DATA_READ;
8079 } else flags |= CAM_DIR_NONE;
8081 cam_fill_mmcio(&ccb->mmcio,
8082 /*retries*/ retry_count,
8085 /*mmc_opcode*/ mmc_opcode,
8086 /*mmc_arg*/ mmc_arg,
8087 /*mmc_flags*/ mmc_flags,
8088 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
8089 /*timeout*/ timeout ? timeout : 5000);
8091 if (((retval = cam_send_ccb(device, ccb)) < 0)
8092 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8093 const char warnstr[] = "error sending command";
8100 if (arglist & CAM_ARG_VERBOSE) {
8101 cam_error_print(device, ccb, CAM_ESF_ALL,
8102 CAM_EPF_ALL, stderr);
8106 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
8107 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
8108 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
8109 ccb->mmcio.cmd.resp[1],
8110 ccb->mmcio.cmd.resp[2],
8111 ccb->mmcio.cmd.resp[3]);
8113 switch (mmc_opcode) {
8114 case SD_IO_RW_DIRECT:
8115 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
8116 SD_R5_DATA(ccb->mmcio.cmd.resp),
8117 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
8119 case SD_IO_RW_EXTENDED:
8120 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
8121 hexdump(mmc_data, mmc_data_len, NULL, 0);
8123 case SD_SEND_RELATIVE_ADDR:
8124 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
8127 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
8134 if (mmc_data_len > 0 && mmc_data != NULL)
8141 smpreportgeneral(struct cam_device *device, int argc, char **argv,
8142 char *combinedopt, int retry_count, int timeout)
8145 struct smp_report_general_request *request = NULL;
8146 struct smp_report_general_response *response = NULL;
8147 struct sbuf *sb = NULL;
8149 int c, long_response = 0;
8153 * Note that at the moment we don't support sending SMP CCBs to
8154 * devices that aren't probed by CAM.
8156 ccb = cam_getccb(device);
8158 warnx("%s: error allocating CCB", __func__);
8162 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8164 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8173 request = malloc(sizeof(*request));
8174 if (request == NULL) {
8175 warn("%s: unable to allocate %zd bytes", __func__,
8181 response = malloc(sizeof(*response));
8182 if (response == NULL) {
8183 warn("%s: unable to allocate %zd bytes", __func__,
8190 smp_report_general(&ccb->smpio,
8194 /*request_len*/ sizeof(*request),
8195 (uint8_t *)response,
8196 /*response_len*/ sizeof(*response),
8197 /*long_response*/ long_response,
8200 if (((retval = cam_send_ccb(device, ccb)) < 0)
8201 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8202 const char warnstr[] = "error sending command";
8209 if (arglist & CAM_ARG_VERBOSE) {
8210 cam_error_print(device, ccb, CAM_ESF_ALL,
8211 CAM_EPF_ALL, stderr);
8218 * If the device supports the long response bit, try again and see
8219 * if we can get all of the data.
8221 if ((response->long_response & SMP_RG_LONG_RESPONSE)
8222 && (long_response == 0)) {
8223 ccb->ccb_h.status = CAM_REQ_INPROG;
8224 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8230 * XXX KDM detect and decode SMP errors here.
8232 sb = sbuf_new_auto();
8234 warnx("%s: error allocating sbuf", __func__);
8238 smp_report_general_sbuf(response, sizeof(*response), sb);
8240 if (sbuf_finish(sb) != 0) {
8241 warnx("%s: sbuf_finish", __func__);
8245 printf("%s", sbuf_data(sb));
8251 if (request != NULL)
8254 if (response != NULL)
8263 static struct camcontrol_opts phy_ops[] = {
8264 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
8265 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
8266 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
8267 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
8268 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
8269 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
8270 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
8271 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
8272 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
8277 smpphycontrol(struct cam_device *device, int argc, char **argv,
8278 char *combinedopt, int retry_count, int timeout)
8281 struct smp_phy_control_request *request = NULL;
8282 struct smp_phy_control_response *response = NULL;
8283 int long_response = 0;
8286 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
8288 uint64_t attached_dev_name = 0;
8289 int dev_name_set = 0;
8290 uint32_t min_plr = 0, max_plr = 0;
8291 uint32_t pp_timeout_val = 0;
8292 int slumber_partial = 0;
8293 int set_pp_timeout_val = 0;
8297 * Note that at the moment we don't support sending SMP CCBs to
8298 * devices that aren't probed by CAM.
8300 ccb = cam_getccb(device);
8302 warnx("%s: error allocating CCB", __func__);
8306 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8308 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8316 if (strcasecmp(optarg, "enable") == 0)
8318 else if (strcasecmp(optarg, "disable") == 0)
8321 warnx("%s: Invalid argument %s", __func__,
8328 slumber_partial |= enable <<
8329 SMP_PC_SAS_SLUMBER_SHIFT;
8332 slumber_partial |= enable <<
8333 SMP_PC_SAS_PARTIAL_SHIFT;
8336 slumber_partial |= enable <<
8337 SMP_PC_SATA_SLUMBER_SHIFT;
8340 slumber_partial |= enable <<
8341 SMP_PC_SATA_PARTIAL_SHIFT;
8344 warnx("%s: programmer error", __func__);
8347 break; /*NOTREACHED*/
8352 attached_dev_name = (uintmax_t)strtoumax(optarg,
8361 * We don't do extensive checking here, so this
8362 * will continue to work when new speeds come out.
8364 min_plr = strtoul(optarg, NULL, 0);
8366 || (min_plr > 0xf)) {
8367 warnx("%s: invalid link rate %x",
8375 * We don't do extensive checking here, so this
8376 * will continue to work when new speeds come out.
8378 max_plr = strtoul(optarg, NULL, 0);
8380 || (max_plr > 0xf)) {
8381 warnx("%s: invalid link rate %x",
8388 camcontrol_optret optreturn;
8389 cam_argmask argnums;
8392 if (phy_op_set != 0) {
8393 warnx("%s: only one phy operation argument "
8394 "(-o) allowed", __func__);
8402 * Allow the user to specify the phy operation
8403 * numerically, as well as with a name. This will
8404 * future-proof it a bit, so options that are added
8405 * in future specs can be used.
8407 if (isdigit(optarg[0])) {
8408 phy_operation = strtoul(optarg, NULL, 0);
8409 if ((phy_operation == 0)
8410 || (phy_operation > 0xff)) {
8411 warnx("%s: invalid phy operation %#x",
8412 __func__, phy_operation);
8418 optreturn = getoption(phy_ops, optarg, &phy_operation,
8421 if (optreturn == CC_OR_AMBIGUOUS) {
8422 warnx("%s: ambiguous option %s", __func__,
8427 } else if (optreturn == CC_OR_NOT_FOUND) {
8428 warnx("%s: option %s not found", __func__,
8440 pp_timeout_val = strtoul(optarg, NULL, 0);
8441 if (pp_timeout_val > 15) {
8442 warnx("%s: invalid partial pathway timeout "
8443 "value %u, need a value less than 16",
8444 __func__, pp_timeout_val);
8448 set_pp_timeout_val = 1;
8456 warnx("%s: a PHY (-p phy) argument is required",__func__);
8461 if (((dev_name_set != 0)
8462 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8463 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8464 && (dev_name_set == 0))) {
8465 warnx("%s: -d name and -o setdevname arguments both "
8466 "required to set device name", __func__);
8471 request = malloc(sizeof(*request));
8472 if (request == NULL) {
8473 warn("%s: unable to allocate %zd bytes", __func__,
8479 response = malloc(sizeof(*response));
8480 if (response == NULL) {
8481 warn("%s: unable to allocate %zd bytes", __func__,
8487 smp_phy_control(&ccb->smpio,
8492 (uint8_t *)response,
8495 /*expected_exp_change_count*/ 0,
8498 (set_pp_timeout_val != 0) ? 1 : 0,
8506 if (((retval = cam_send_ccb(device, ccb)) < 0)
8507 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8508 const char warnstr[] = "error sending command";
8515 if (arglist & CAM_ARG_VERBOSE) {
8517 * Use CAM_EPF_NORMAL so we only get one line of
8518 * SMP command decoding.
8520 cam_error_print(device, ccb, CAM_ESF_ALL,
8521 CAM_EPF_NORMAL, stderr);
8527 /* XXX KDM print out something here for success? */
8532 if (request != NULL)
8535 if (response != NULL)
8542 smpmaninfo(struct cam_device *device, int argc, char **argv,
8543 char *combinedopt, int retry_count, int timeout)
8546 struct smp_report_manuf_info_request request;
8547 struct smp_report_manuf_info_response response;
8548 struct sbuf *sb = NULL;
8549 int long_response = 0;
8554 * Note that at the moment we don't support sending SMP CCBs to
8555 * devices that aren't probed by CAM.
8557 ccb = cam_getccb(device);
8559 warnx("%s: error allocating CCB", __func__);
8563 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8565 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8574 bzero(&request, sizeof(request));
8575 bzero(&response, sizeof(response));
8577 smp_report_manuf_info(&ccb->smpio,
8582 (uint8_t *)&response,
8587 if (((retval = cam_send_ccb(device, ccb)) < 0)
8588 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8589 const char warnstr[] = "error sending command";
8596 if (arglist & CAM_ARG_VERBOSE) {
8597 cam_error_print(device, ccb, CAM_ESF_ALL,
8598 CAM_EPF_ALL, stderr);
8604 sb = sbuf_new_auto();
8606 warnx("%s: error allocating sbuf", __func__);
8610 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8612 if (sbuf_finish(sb) != 0) {
8613 warnx("%s: sbuf_finish", __func__);
8617 printf("%s", sbuf_data(sb));
8631 getdevid(struct cam_devitem *item)
8634 union ccb *ccb = NULL;
8636 struct cam_device *dev;
8638 dev = cam_open_btl(item->dev_match.path_id,
8639 item->dev_match.target_id,
8640 item->dev_match.target_lun, O_RDWR, NULL);
8643 warnx("%s", cam_errbuf);
8648 item->device_id_len = 0;
8650 ccb = cam_getccb(dev);
8652 warnx("%s: error allocating CCB", __func__);
8657 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8660 * On the first try, we just probe for the size of the data, and
8661 * then allocate that much memory and try again.
8664 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8665 ccb->ccb_h.flags = CAM_DIR_IN;
8666 ccb->cdai.flags = CDAI_FLAG_NONE;
8667 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8668 ccb->cdai.bufsiz = item->device_id_len;
8669 if (item->device_id_len != 0)
8670 ccb->cdai.buf = (uint8_t *)item->device_id;
8672 if (cam_send_ccb(dev, ccb) < 0) {
8673 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8678 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8679 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8684 if (item->device_id_len == 0) {
8686 * This is our first time through. Allocate the buffer,
8687 * and then go back to get the data.
8689 if (ccb->cdai.provsiz == 0) {
8690 warnx("%s: invalid .provsiz field returned with "
8691 "XPT_GDEV_ADVINFO CCB", __func__);
8695 item->device_id_len = ccb->cdai.provsiz;
8696 item->device_id = malloc(item->device_id_len);
8697 if (item->device_id == NULL) {
8698 warn("%s: unable to allocate %d bytes", __func__,
8699 item->device_id_len);
8703 ccb->ccb_h.status = CAM_REQ_INPROG;
8709 cam_close_device(dev);
8718 * XXX KDM merge this code with getdevtree()?
8721 buildbusdevlist(struct cam_devlist *devlist)
8724 int bufsize, fd = -1;
8725 struct dev_match_pattern *patterns;
8726 struct cam_devitem *item = NULL;
8727 int skip_device = 0;
8730 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8731 warn("couldn't open %s", XPT_DEVICE);
8735 bzero(&ccb, sizeof(union ccb));
8737 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8738 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8739 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8741 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8742 bufsize = sizeof(struct dev_match_result) * 100;
8743 ccb.cdm.match_buf_len = bufsize;
8744 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8745 if (ccb.cdm.matches == NULL) {
8746 warnx("can't malloc memory for matches");
8750 ccb.cdm.num_matches = 0;
8751 ccb.cdm.num_patterns = 2;
8752 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8753 ccb.cdm.num_patterns;
8755 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8756 if (patterns == NULL) {
8757 warnx("can't malloc memory for patterns");
8762 ccb.cdm.patterns = patterns;
8763 bzero(patterns, ccb.cdm.pattern_buf_len);
8765 patterns[0].type = DEV_MATCH_DEVICE;
8766 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8767 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8768 patterns[1].type = DEV_MATCH_PERIPH;
8769 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8770 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8773 * We do the ioctl multiple times if necessary, in case there are
8774 * more than 100 nodes in the EDT.
8779 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8780 warn("error sending CAMIOCOMMAND ioctl");
8785 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8786 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8787 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8788 warnx("got CAM error %#x, CDM error %d\n",
8789 ccb.ccb_h.status, ccb.cdm.status);
8794 for (i = 0; i < ccb.cdm.num_matches; i++) {
8795 switch (ccb.cdm.matches[i].type) {
8796 case DEV_MATCH_DEVICE: {
8797 struct device_match_result *dev_result;
8800 &ccb.cdm.matches[i].result.device_result;
8802 if (dev_result->flags &
8803 DEV_RESULT_UNCONFIGURED) {
8809 item = malloc(sizeof(*item));
8811 warn("%s: unable to allocate %zd bytes",
8812 __func__, sizeof(*item));
8816 bzero(item, sizeof(*item));
8817 bcopy(dev_result, &item->dev_match,
8818 sizeof(*dev_result));
8819 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8822 if (getdevid(item) != 0) {
8828 case DEV_MATCH_PERIPH: {
8829 struct periph_match_result *periph_result;
8832 &ccb.cdm.matches[i].result.periph_result;
8834 if (skip_device != 0)
8836 item->num_periphs++;
8837 item->periph_matches = realloc(
8838 item->periph_matches,
8840 sizeof(struct periph_match_result));
8841 if (item->periph_matches == NULL) {
8842 warn("%s: error allocating periph "
8847 bcopy(periph_result, &item->periph_matches[
8848 item->num_periphs - 1],
8849 sizeof(*periph_result));
8853 fprintf(stderr, "%s: unexpected match "
8854 "type %d\n", __func__,
8855 ccb.cdm.matches[i].type);
8858 break; /*NOTREACHED*/
8861 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8862 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8870 free(ccb.cdm.matches);
8873 freebusdevlist(devlist);
8879 freebusdevlist(struct cam_devlist *devlist)
8881 struct cam_devitem *item, *item2;
8883 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8884 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8886 free(item->device_id);
8887 free(item->periph_matches);
8892 static struct cam_devitem *
8893 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8895 struct cam_devitem *item;
8897 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8898 struct scsi_vpd_id_descriptor *idd;
8901 * XXX KDM look for LUN IDs as well?
8903 idd = scsi_get_devid(item->device_id,
8904 item->device_id_len,
8905 scsi_devid_is_sas_target);
8909 if (scsi_8btou64(idd->identifier) == sasaddr)
8917 smpphylist(struct cam_device *device, int argc, char **argv,
8918 char *combinedopt, int retry_count, int timeout)
8920 struct smp_report_general_request *rgrequest = NULL;
8921 struct smp_report_general_response *rgresponse = NULL;
8922 struct smp_discover_request *disrequest = NULL;
8923 struct smp_discover_response *disresponse = NULL;
8924 struct cam_devlist devlist;
8926 int long_response = 0;
8933 * Note that at the moment we don't support sending SMP CCBs to
8934 * devices that aren't probed by CAM.
8936 ccb = cam_getccb(device);
8938 warnx("%s: error allocating CCB", __func__);
8942 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8943 STAILQ_INIT(&devlist.dev_queue);
8945 rgrequest = malloc(sizeof(*rgrequest));
8946 if (rgrequest == NULL) {
8947 warn("%s: unable to allocate %zd bytes", __func__,
8948 sizeof(*rgrequest));
8953 rgresponse = malloc(sizeof(*rgresponse));
8954 if (rgresponse == NULL) {
8955 warn("%s: unable to allocate %zd bytes", __func__,
8956 sizeof(*rgresponse));
8961 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8974 smp_report_general(&ccb->smpio,
8978 /*request_len*/ sizeof(*rgrequest),
8979 (uint8_t *)rgresponse,
8980 /*response_len*/ sizeof(*rgresponse),
8981 /*long_response*/ long_response,
8984 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8986 if (((retval = cam_send_ccb(device, ccb)) < 0)
8987 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8988 const char warnstr[] = "error sending command";
8995 if (arglist & CAM_ARG_VERBOSE) {
8996 cam_error_print(device, ccb, CAM_ESF_ALL,
8997 CAM_EPF_ALL, stderr);
9003 num_phys = rgresponse->num_phys;
9005 if (num_phys == 0) {
9007 fprintf(stdout, "%s: No Phys reported\n", __func__);
9012 devlist.path_id = device->path_id;
9014 retval = buildbusdevlist(&devlist);
9019 fprintf(stdout, "%d PHYs:\n", num_phys);
9020 fprintf(stdout, "PHY Attached SAS Address\n");
9023 disrequest = malloc(sizeof(*disrequest));
9024 if (disrequest == NULL) {
9025 warn("%s: unable to allocate %zd bytes", __func__,
9026 sizeof(*disrequest));
9031 disresponse = malloc(sizeof(*disresponse));
9032 if (disresponse == NULL) {
9033 warn("%s: unable to allocate %zd bytes", __func__,
9034 sizeof(*disresponse));
9039 for (i = 0; i < num_phys; i++) {
9040 struct cam_devitem *item;
9041 struct device_match_result *dev_match;
9042 char vendor[16], product[48], revision[16];
9046 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
9048 ccb->ccb_h.status = CAM_REQ_INPROG;
9049 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9051 smp_discover(&ccb->smpio,
9055 sizeof(*disrequest),
9056 (uint8_t *)disresponse,
9057 sizeof(*disresponse),
9059 /*ignore_zone_group*/ 0,
9063 if (((retval = cam_send_ccb(device, ccb)) < 0)
9064 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
9065 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
9066 const char warnstr[] = "error sending command";
9073 if (arglist & CAM_ARG_VERBOSE) {
9074 cam_error_print(device, ccb, CAM_ESF_ALL,
9075 CAM_EPF_ALL, stderr);
9081 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
9083 fprintf(stdout, "%3d <vacant>\n", i);
9087 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
9090 item = findsasdevice(&devlist,
9091 scsi_8btou64(disresponse->attached_sas_address));
9095 || (item != NULL)) {
9096 fprintf(stdout, "%3d 0x%016jx", i,
9097 (uintmax_t)scsi_8btou64(
9098 disresponse->attached_sas_address));
9100 fprintf(stdout, "\n");
9103 } else if (quiet != 0)
9106 dev_match = &item->dev_match;
9108 if (dev_match->protocol == PROTO_SCSI) {
9109 cam_strvis(vendor, dev_match->inq_data.vendor,
9110 sizeof(dev_match->inq_data.vendor),
9112 cam_strvis(product, dev_match->inq_data.product,
9113 sizeof(dev_match->inq_data.product),
9115 cam_strvis(revision, dev_match->inq_data.revision,
9116 sizeof(dev_match->inq_data.revision),
9118 sprintf(tmpstr, "<%s %s %s>", vendor, product,
9120 } else if ((dev_match->protocol == PROTO_ATA)
9121 || (dev_match->protocol == PROTO_SATAPM)) {
9122 cam_strvis(product, dev_match->ident_data.model,
9123 sizeof(dev_match->ident_data.model),
9125 cam_strvis(revision, dev_match->ident_data.revision,
9126 sizeof(dev_match->ident_data.revision),
9128 sprintf(tmpstr, "<%s %s>", product, revision);
9130 sprintf(tmpstr, "<>");
9132 fprintf(stdout, " %-33s ", tmpstr);
9135 * If we have 0 periphs, that's a bug...
9137 if (item->num_periphs == 0) {
9138 fprintf(stdout, "\n");
9142 fprintf(stdout, "(");
9143 for (j = 0; j < item->num_periphs; j++) {
9145 fprintf(stdout, ",");
9147 fprintf(stdout, "%s%d",
9148 item->periph_matches[j].periph_name,
9149 item->periph_matches[j].unit_number);
9152 fprintf(stdout, ")\n");
9166 freebusdevlist(&devlist);
9172 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
9174 uint8_t error = 0, ata_device = 0, status = 0;
9179 retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
9182 if (arglist & CAM_ARG_VERBOSE) {
9183 cam_error_print(device, ccb, CAM_ESF_ALL,
9184 CAM_EPF_ALL, stderr);
9186 warnx("Can't get ATA command status");
9190 if (status & ATA_STATUS_ERROR) {
9191 cam_error_print(device, ccb, CAM_ESF_ALL,
9192 CAM_EPF_ALL, stderr);
9196 printf("%s%d: ", device->device_name, device->dev_unit_num);
9199 printf("Standby mode\n");
9202 printf("Standby_y mode\n");
9205 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
9208 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
9211 printf("Idle mode\n");
9214 printf("Idle_a mode\n");
9217 printf("Idle_b mode\n");
9220 printf("Idle_c mode\n");
9223 printf("Active or Idle mode\n");
9226 printf("Unknown mode 0x%02x\n", count);
9234 atapm(struct cam_device *device, int argc, char **argv,
9235 char *combinedopt, int retry_count, int timeout)
9241 u_int8_t ata_flags = 0;
9244 ccb = cam_getccb(device);
9247 warnx("%s: error allocating ccb", __func__);
9251 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9260 if (strcmp(argv[1], "idle") == 0) {
9262 cmd = ATA_IDLE_IMMEDIATE;
9265 } else if (strcmp(argv[1], "standby") == 0) {
9267 cmd = ATA_STANDBY_IMMEDIATE;
9269 cmd = ATA_STANDBY_CMD;
9270 } else if (strcmp(argv[1], "powermode") == 0) {
9271 cmd = ATA_CHECK_POWER_MODE;
9272 ata_flags = AP_FLAG_CHK_COND;
9281 else if (t <= (240 * 5))
9283 else if (t <= (252 * 5))
9284 /* special encoding for 21 minutes */
9286 else if (t <= (11 * 30 * 60))
9287 sc = (t - 1) / (30 * 60) + 241;
9291 retval = ata_do_cmd(device,
9293 /*retries*/retry_count,
9294 /*flags*/CAM_DIR_NONE,
9295 /*protocol*/AP_PROTO_NON_DATA,
9296 /*ata_flags*/ata_flags,
9297 /*tag_action*/MSG_SIMPLE_Q_TAG,
9304 /*timeout*/timeout ? timeout : 30 * 1000,
9309 if (retval || cmd != ATA_CHECK_POWER_MODE)
9312 return (atapm_proc_resp(device, ccb));
9316 ataaxm(struct cam_device *device, int argc, char **argv,
9317 char *combinedopt, int retry_count, int timeout)
9325 ccb = cam_getccb(device);
9328 warnx("%s: error allocating ccb", __func__);
9332 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9342 if (strcmp(argv[1], "apm") == 0) {
9358 retval = ata_do_cmd(device,
9360 /*retries*/retry_count,
9361 /*flags*/CAM_DIR_NONE,
9362 /*protocol*/AP_PROTO_NON_DATA,
9364 /*tag_action*/MSG_SIMPLE_Q_TAG,
9365 /*command*/ATA_SETFEATURES,
9371 /*timeout*/timeout ? timeout : 30 * 1000,
9379 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9380 int show_sa_errors, int sa_set, int service_action,
9381 int timeout_desc, int task_attr, int retry_count, int timeout,
9382 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9384 union ccb *ccb = NULL;
9385 uint8_t *buf = NULL;
9386 uint32_t alloc_len = 0, num_opcodes;
9387 uint32_t valid_len = 0;
9388 uint32_t avail_len = 0;
9389 struct scsi_report_supported_opcodes_all *all_hdr;
9390 struct scsi_report_supported_opcodes_one *one;
9395 * Make it clear that we haven't yet allocated or filled anything.
9400 ccb = cam_getccb(device);
9402 warnx("couldn't allocate CCB");
9407 /* cam_getccb cleans up the header, caller has to zero the payload */
9408 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9410 if (opcode_set != 0) {
9411 options |= RSO_OPTIONS_OC;
9413 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9416 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9417 sizeof(struct scsi_report_supported_opcodes_descr));
9420 if (timeout_desc != 0) {
9421 options |= RSO_RCTD;
9422 alloc_len += num_opcodes *
9423 sizeof(struct scsi_report_supported_opcodes_timeout);
9427 options |= RSO_OPTIONS_OC_SA;
9428 if (show_sa_errors != 0)
9429 options &= ~RSO_OPTIONS_OC;
9438 buf = malloc(alloc_len);
9440 warn("Unable to allocate %u bytes", alloc_len);
9444 bzero(buf, alloc_len);
9446 scsi_report_supported_opcodes(&ccb->csio,
9447 /*retries*/ retry_count,
9449 /*tag_action*/ task_attr,
9450 /*options*/ options,
9451 /*req_opcode*/ opcode,
9452 /*req_service_action*/ service_action,
9454 /*dxfer_len*/ alloc_len,
9455 /*sense_len*/ SSD_FULL_SIZE,
9456 /*timeout*/ timeout ? timeout : 10000);
9458 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9460 if (retry_count != 0)
9461 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9463 if (cam_send_ccb(device, ccb) < 0) {
9464 warn("error sending REPORT SUPPORTED OPERATION CODES command");
9469 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9470 if (verbosemode != 0)
9471 cam_error_print(device, ccb, CAM_ESF_ALL,
9472 CAM_EPF_ALL, stderr);
9477 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9479 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9480 && (valid_len >= sizeof(*all_hdr))) {
9481 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9482 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9483 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9484 && (valid_len >= sizeof(*one))) {
9485 uint32_t cdb_length;
9487 one = (struct scsi_report_supported_opcodes_one *)buf;
9488 cdb_length = scsi_2btoul(one->cdb_length);
9489 avail_len = sizeof(*one) + cdb_length;
9490 if (one->support & RSO_ONE_CTDP) {
9491 struct scsi_report_supported_opcodes_timeout *td;
9493 td = (struct scsi_report_supported_opcodes_timeout *)
9495 if (valid_len >= (avail_len + sizeof(td->length))) {
9496 avail_len += scsi_2btoul(td->length) +
9499 avail_len += sizeof(*td);
9505 * avail_len could be zero if we didn't get enough data back from
9506 * thet target to determine
9508 if ((avail_len != 0)
9509 && (avail_len > valid_len)) {
9510 alloc_len = avail_len;
9514 *fill_len = valid_len;
9526 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9527 int req_sa, uint8_t *buf, uint32_t valid_len)
9529 struct scsi_report_supported_opcodes_one *one;
9530 struct scsi_report_supported_opcodes_timeout *td;
9531 uint32_t cdb_len = 0, td_len = 0;
9532 const char *op_desc = NULL;
9536 one = (struct scsi_report_supported_opcodes_one *)buf;
9539 * If we don't have the full single opcode descriptor, no point in
9542 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9544 warnx("Only %u bytes returned, not enough to verify support",
9550 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9552 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9555 printf(", SA 0x%x", req_sa);
9558 switch (one->support & RSO_ONE_SUP_MASK) {
9559 case RSO_ONE_SUP_UNAVAIL:
9560 printf("No command support information currently available\n");
9562 case RSO_ONE_SUP_NOT_SUP:
9563 printf("Command not supported\n");
9566 break; /*NOTREACHED*/
9567 case RSO_ONE_SUP_AVAIL:
9568 printf("Command is supported, complies with a SCSI standard\n");
9570 case RSO_ONE_SUP_VENDOR:
9571 printf("Command is supported, vendor-specific "
9572 "implementation\n");
9575 printf("Unknown command support flags 0x%#x\n",
9576 one->support & RSO_ONE_SUP_MASK);
9581 * If we don't have the CDB length, it isn't exactly an error, the
9582 * command probably isn't supported.
9584 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9588 cdb_len = scsi_2btoul(one->cdb_length);
9591 * If our valid data doesn't include the full reported length,
9592 * return. The caller should have detected this and adjusted his
9593 * allocation length to get all of the available data.
9595 if (valid_len < sizeof(*one) + cdb_len) {
9601 * If all we have is the opcode, there is no point in printing out
9609 printf("CDB usage bitmap:");
9610 for (i = 0; i < cdb_len; i++) {
9611 printf(" %02x", one->cdb_usage[i]);
9616 * If we don't have a timeout descriptor, we're done.
9618 if ((one->support & RSO_ONE_CTDP) == 0)
9622 * If we don't have enough valid length to include the timeout
9623 * descriptor length, we're done.
9625 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9628 td = (struct scsi_report_supported_opcodes_timeout *)
9629 &buf[sizeof(*one) + cdb_len];
9630 td_len = scsi_2btoul(td->length);
9631 td_len += sizeof(td->length);
9634 * If we don't have the full timeout descriptor, we're done.
9636 if (td_len < sizeof(*td))
9640 * If we don't have enough valid length to contain the full timeout
9641 * descriptor, we're done.
9643 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9646 printf("Timeout information:\n");
9647 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9648 printf("Nominal timeout: %u seconds\n",
9649 scsi_4btoul(td->nominal_time));
9650 printf("Recommended timeout: %u seconds\n",
9651 scsi_4btoul(td->recommended_time));
9658 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9661 struct scsi_report_supported_opcodes_all *hdr;
9662 struct scsi_report_supported_opcodes_descr *desc;
9663 uint32_t avail_len = 0, used_len = 0;
9667 if (valid_len < sizeof(*hdr)) {
9668 warnx("%s: not enough returned data (%u bytes) opcode list",
9669 __func__, valid_len);
9673 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9674 avail_len = scsi_4btoul(hdr->length);
9675 avail_len += sizeof(hdr->length);
9677 * Take the lesser of the amount of data the drive claims is
9678 * available, and the amount of data the HBA says was returned.
9680 avail_len = MIN(avail_len, valid_len);
9682 used_len = sizeof(hdr->length);
9684 printf("%-6s %4s %8s ",
9685 "Opcode", "SA", "CDB len" );
9688 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9689 printf(" Description\n");
9691 while ((avail_len - used_len) > sizeof(*desc)) {
9692 struct scsi_report_supported_opcodes_timeout *td;
9694 const char *op_desc = NULL;
9696 cur_ptr = &buf[used_len];
9697 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9699 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9700 if (op_desc == NULL)
9701 op_desc = "UNKNOWN";
9703 printf("0x%02x %#4x %8u ", desc->opcode,
9704 scsi_2btoul(desc->service_action),
9705 scsi_2btoul(desc->cdb_length));
9707 used_len += sizeof(*desc);
9709 if ((desc->flags & RSO_CTDP) == 0) {
9710 printf(" %s\n", op_desc);
9715 * If we don't have enough space to fit a timeout
9716 * descriptor, then we're done.
9718 if (avail_len - used_len < sizeof(*td)) {
9719 used_len = avail_len;
9720 printf(" %s\n", op_desc);
9723 cur_ptr = &buf[used_len];
9724 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9725 td_len = scsi_2btoul(td->length);
9726 td_len += sizeof(td->length);
9730 * If the given timeout descriptor length is less than what
9731 * we understand, skip it.
9733 if (td_len < sizeof(*td)) {
9734 printf(" %s\n", op_desc);
9738 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9739 scsi_4btoul(td->nominal_time),
9740 scsi_4btoul(td->recommended_time), op_desc);
9747 scsiopcodes(struct cam_device *device, int argc, char **argv,
9748 char *combinedopt, int task_attr, int retry_count, int timeout,
9752 uint32_t opcode = 0, service_action = 0;
9753 int td_set = 0, opcode_set = 0, sa_set = 0;
9754 int show_sa_errors = 1;
9755 uint32_t valid_len = 0;
9756 uint8_t *buf = NULL;
9760 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9766 opcode = strtoul(optarg, &endptr, 0);
9767 if (*endptr != '\0') {
9768 warnx("Invalid opcode \"%s\", must be a number",
9773 if (opcode > 0xff) {
9774 warnx("Invalid opcode 0x%#x, must be between"
9775 "0 and 0xff inclusive", opcode);
9782 service_action = strtoul(optarg, &endptr, 0);
9783 if (*endptr != '\0') {
9784 warnx("Invalid service action \"%s\", must "
9785 "be a number", optarg);
9789 if (service_action > 0xffff) {
9790 warnx("Invalid service action 0x%#x, must "
9791 "be between 0 and 0xffff inclusive",
9806 && (opcode_set == 0)) {
9807 warnx("You must specify an opcode with -o if a service "
9812 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9813 sa_set, service_action, td_set, task_attr,
9814 retry_count, timeout, verbosemode, &valid_len,
9819 if ((opcode_set != 0)
9821 retval = scsiprintoneopcode(device, opcode, sa_set,
9822 service_action, buf, valid_len);
9824 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9833 #endif /* MINIMALISTIC */
9836 reprobe(struct cam_device *device)
9841 ccb = cam_getccb(device);
9844 warnx("%s: error allocating ccb", __func__);
9848 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
9850 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9852 if (cam_send_ccb(device, ccb) < 0) {
9853 warn("error sending XPT_REPROBE_LUN CCB");
9858 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9859 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9871 usage(int printlong)
9874 fprintf(printlong ? stdout : stderr,
9875 "usage: camcontrol <command> [device id][generic args][command args]\n"
9876 " camcontrol devlist [-b] [-v]\n"
9877 #ifndef MINIMALISTIC
9878 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9879 " camcontrol tur [dev_id][generic args]\n"
9880 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9881 " camcontrol identify [dev_id][generic args] [-v]\n"
9882 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9883 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9885 " camcontrol start [dev_id][generic args]\n"
9886 " camcontrol stop [dev_id][generic args]\n"
9887 " camcontrol load [dev_id][generic args]\n"
9888 " camcontrol eject [dev_id][generic args]\n"
9889 " camcontrol reprobe [dev_id][generic args]\n"
9890 #endif /* MINIMALISTIC */
9891 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9892 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9893 #ifndef MINIMALISTIC
9894 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9895 " [-q][-s][-S offset][-X]\n"
9896 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9897 " [-P pagectl][-e | -b][-d]\n"
9898 " camcontrol cmd [dev_id][generic args]\n"
9899 " <-a cmd [args] | -c cmd [args]>\n"
9900 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9901 " camcontrol smpcmd [dev_id][generic args]\n"
9902 " <-r len fmt [args]> <-R len fmt [args]>\n"
9903 " camcontrol smprg [dev_id][generic args][-l]\n"
9904 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9905 " [-o operation][-d name][-m rate][-M rate]\n"
9906 " [-T pp_timeout][-a enable|disable]\n"
9907 " [-A enable|disable][-s enable|disable]\n"
9908 " [-S enable|disable]\n"
9909 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9910 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9911 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9912 " <all|dev_id|bus[:target[:lun]]|off>\n"
9913 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9914 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9915 " [-D <enable|disable>][-M mode][-O offset]\n"
9916 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9917 " [-U][-W bus_width]\n"
9918 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9919 " camcontrol sanitize [dev_id][generic args]\n"
9920 " [-a overwrite|block|crypto|exitfailure]\n"
9921 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9923 " camcontrol idle [dev_id][generic args][-t time]\n"
9924 " camcontrol standby [dev_id][generic args][-t time]\n"
9925 " camcontrol sleep [dev_id][generic args]\n"
9926 " camcontrol powermode [dev_id][generic args]\n"
9927 " camcontrol apm [dev_id][generic args][-l level]\n"
9928 " camcontrol aam [dev_id][generic args][-l level]\n"
9929 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9931 " camcontrol security [dev_id][generic args]\n"
9932 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9933 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9934 " [-U <user|master>] [-y]\n"
9935 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9936 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9937 " camcontrol ama [dev_id][generic args] [-f] [-q] [-s max_sectors]\n"
9938 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9939 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9940 " [-s scope][-S][-T type][-U]\n"
9941 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9942 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9943 " [-p part][-s start][-T type][-V vol]\n"
9944 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9946 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9947 " [-o rep_opts] [-P print_opts]\n"
9948 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9949 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9950 " [-S power_src] [-T timer]\n"
9951 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9952 " <-s <-f format -T time | -U >>\n"
9953 " camcontrol devtype [dev_id]\n"
9955 #endif /* MINIMALISTIC */
9956 " camcontrol help\n");
9959 #ifndef MINIMALISTIC
9961 "Specify one of the following options:\n"
9962 "devlist list all CAM devices\n"
9963 "periphlist list all CAM peripheral drivers attached to a device\n"
9964 "tur send a test unit ready to the named device\n"
9965 "inquiry send a SCSI inquiry command to the named device\n"
9966 "identify send a ATA identify command to the named device\n"
9967 "reportluns send a SCSI report luns command to the device\n"
9968 "readcap send a SCSI read capacity command to the device\n"
9969 "start send a Start Unit command to the device\n"
9970 "stop send a Stop Unit command to the device\n"
9971 "load send a Start Unit command to the device with the load bit set\n"
9972 "eject send a Stop Unit command to the device with the eject bit set\n"
9973 "reprobe update capacity information of the given device\n"
9974 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9975 "reset reset all buses, the given bus, bus:target:lun or device\n"
9976 "defects read the defect list of the specified device\n"
9977 "modepage display or edit (-e) the given mode page\n"
9978 "cmd send the given SCSI command, may need -i or -o as well\n"
9979 "smpcmd send the given SMP command, requires -o and -i\n"
9980 "smprg send the SMP Report General command\n"
9981 "smppc send the SMP PHY Control command, requires -p\n"
9982 "smpphylist display phys attached to a SAS expander\n"
9983 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9984 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9985 "tags report or set the number of transaction slots for a device\n"
9986 "negotiate report or set device negotiation parameters\n"
9987 "format send the SCSI FORMAT UNIT command to the named device\n"
9988 "sanitize send the SCSI SANITIZE command to the named device\n"
9989 "idle send the ATA IDLE command to the named device\n"
9990 "standby send the ATA STANDBY command to the named device\n"
9991 "sleep send the ATA SLEEP command to the named device\n"
9992 "powermode send the ATA CHECK POWER MODE command to the named device\n"
9993 "fwdownload program firmware of the named device with the given image\n"
9994 "security report or send ATA security commands to the named device\n"
9995 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9996 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9997 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9998 "zone manage Zoned Block (Shingled) devices\n"
9999 "epc send ATA Extended Power Conditions commands\n"
10000 "timestamp report or set the device's timestamp\n"
10001 "devtype report the type of device\n"
10002 "help this message\n"
10003 "Device Identifiers:\n"
10004 "bus:target specify the bus and target, lun defaults to 0\n"
10005 "bus:target:lun specify the bus, target and lun\n"
10006 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
10007 "Generic arguments:\n"
10008 "-v be verbose, print out sense information\n"
10009 "-t timeout command timeout in seconds, overrides default timeout\n"
10010 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
10011 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
10012 "-E have the kernel attempt to perform SCSI error recovery\n"
10013 "-C count specify the SCSI command retry count (needs -E to work)\n"
10014 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
10015 "modepage arguments:\n"
10016 "-l list all available mode pages\n"
10017 "-m page specify the mode page to view or edit\n"
10018 "-e edit the specified mode page\n"
10019 "-b force view to binary mode\n"
10020 "-d disable block descriptors for mode sense\n"
10021 "-P pgctl page control field 0-3\n"
10022 "defects arguments:\n"
10023 "-f format specify defect list format (block, bfi or phys)\n"
10024 "-G get the grown defect list\n"
10025 "-P get the permanent defect list\n"
10026 "inquiry arguments:\n"
10027 "-D get the standard inquiry data\n"
10028 "-S get the serial number\n"
10029 "-R get the transfer rate, etc.\n"
10030 "reportluns arguments:\n"
10031 "-c only report a count of available LUNs\n"
10032 "-l only print out luns, and not a count\n"
10033 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
10034 "readcap arguments\n"
10035 "-b only report the blocksize\n"
10036 "-h human readable device size, base 2\n"
10037 "-H human readable device size, base 10\n"
10038 "-N print the number of blocks instead of last block\n"
10039 "-q quiet, print numbers only\n"
10040 "-s only report the last block/device size\n"
10042 "-c cdb [args] specify the SCSI CDB\n"
10043 "-i len fmt specify input data and input data format\n"
10044 "-o len fmt [args] specify output data and output data fmt\n"
10045 "smpcmd arguments:\n"
10046 "-r len fmt [args] specify the SMP command to be sent\n"
10047 "-R len fmt [args] specify SMP response format\n"
10048 "smprg arguments:\n"
10049 "-l specify the long response format\n"
10050 "smppc arguments:\n"
10051 "-p phy specify the PHY to operate on\n"
10052 "-l specify the long request/response format\n"
10053 "-o operation specify the phy control operation\n"
10054 "-d name set the attached device name\n"
10055 "-m rate set the minimum physical link rate\n"
10056 "-M rate set the maximum physical link rate\n"
10057 "-T pp_timeout set the partial pathway timeout value\n"
10058 "-a enable|disable enable or disable SATA slumber\n"
10059 "-A enable|disable enable or disable SATA partial phy power\n"
10060 "-s enable|disable enable or disable SAS slumber\n"
10061 "-S enable|disable enable or disable SAS partial phy power\n"
10062 "smpphylist arguments:\n"
10063 "-l specify the long response format\n"
10064 "-q only print phys with attached devices\n"
10065 "smpmaninfo arguments:\n"
10066 "-l specify the long response format\n"
10067 "debug arguments:\n"
10068 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
10069 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
10070 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
10071 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
10072 "tags arguments:\n"
10073 "-N tags specify the number of tags to use for this device\n"
10074 "-q be quiet, don't report the number of tags\n"
10075 "-v report a number of tag-related parameters\n"
10076 "negotiate arguments:\n"
10077 "-a send a test unit ready after negotiation\n"
10078 "-c report/set current negotiation settings\n"
10079 "-D <arg> \"enable\" or \"disable\" disconnection\n"
10080 "-M mode set ATA mode\n"
10081 "-O offset set command delay offset\n"
10082 "-q be quiet, don't report anything\n"
10083 "-R syncrate synchronization rate in MHz\n"
10084 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
10085 "-U report/set user negotiation settings\n"
10086 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
10087 "-v also print a Path Inquiry CCB for the controller\n"
10088 "format arguments:\n"
10089 "-q be quiet, don't print status messages\n"
10090 "-r run in report only mode\n"
10091 "-w don't send immediate format command\n"
10092 "-y don't ask any questions\n"
10093 "sanitize arguments:\n"
10094 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
10095 "-c passes overwrite passes to perform (1 to 31)\n"
10096 "-I invert overwrite pattern after each pass\n"
10097 "-P pattern path to overwrite pattern file\n"
10098 "-q be quiet, don't print status messages\n"
10099 "-r run in report only mode\n"
10100 "-U run operation in unrestricted completion exit mode\n"
10101 "-w don't send immediate sanitize command\n"
10102 "-y don't ask any questions\n"
10103 "idle/standby arguments:\n"
10104 "-t <arg> number of seconds before respective state.\n"
10105 "fwdownload arguments:\n"
10106 "-f fw_image path to firmware image file\n"
10107 "-q don't print informational messages, only errors\n"
10108 "-s run in simulation mode\n"
10109 "-v print info for every firmware segment sent to device\n"
10110 "-y don't ask any questions\n"
10111 "security arguments:\n"
10112 "-d pwd disable security using the given password for the selected\n"
10114 "-e pwd erase the device using the given pwd for the selected user\n"
10115 "-f freeze the security configuration of the specified device\n"
10116 "-h pwd enhanced erase the device using the given pwd for the\n"
10118 "-k pwd unlock the device using the given pwd for the selected\n"
10120 "-l <high|maximum> specifies which security level to set: high or maximum\n"
10121 "-q be quiet, do not print any status messages\n"
10122 "-s pwd password the device (enable security) using the given\n"
10123 " pwd for the selected user\n"
10124 "-T timeout overrides the timeout (seconds) used for erase operation\n"
10125 "-U <user|master> specifies which user to set: user or master\n"
10126 "-y don't ask any questions\n"
10128 "-f freeze the HPA configuration of the device\n"
10129 "-l lock the HPA configuration of the device\n"
10130 "-P make the HPA max sectors persist\n"
10131 "-p pwd Set the HPA configuration password required for unlock\n"
10133 "-q be quiet, do not print any status messages\n"
10134 "-s sectors configures the maximum user accessible sectors of the\n"
10136 "-U pwd unlock the HPA configuration of the device\n"
10137 "-y don't ask any questions\n"
10139 "-f freeze the AMA configuration of the device\n"
10140 "-q be quiet, do not print any status messages\n"
10141 "-s sectors configures the maximum user accessible sectors of the\n"
10143 "persist arguments:\n"
10144 "-i action specify read_keys, read_reservation, report_cap, or\n"
10145 " read_full_status\n"
10146 "-o action specify register, register_ignore, reserve, release,\n"
10147 " clear, preempt, preempt_abort, register_move, replace_lost\n"
10148 "-a set the All Target Ports (ALL_TG_PT) bit\n"
10149 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
10150 "-k key specify the Reservation Key\n"
10151 "-K sa_key specify the Service Action Reservation Key\n"
10152 "-p set the Activate Persist Through Power Loss bit\n"
10153 "-R rtp specify the Relative Target Port\n"
10154 "-s scope specify the scope: lun, extent, element or a number\n"
10155 "-S specify Transport ID for register, requires -I\n"
10156 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
10157 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
10158 "-U unregister the current initiator for register_move\n"
10159 "attrib arguments:\n"
10160 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
10162 "-w attr specify an attribute to write, one -w argument per attr\n"
10163 "-a attr_num only display this attribute number\n"
10164 "-c get cached attributes\n"
10165 "-e elem_addr request attributes for the given element in a changer\n"
10166 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
10167 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
10168 " field_none, field_desc, field_num, field_size, field_rw\n"
10169 "-p partition request attributes for the given partition\n"
10170 "-s start_attr request attributes starting at the given number\n"
10171 "-T elem_type specify the element type (used with -e)\n"
10172 "-V logical_vol specify the logical volume ID\n"
10173 "opcodes arguments:\n"
10174 "-o opcode specify the individual opcode to list\n"
10175 "-s service_action specify the service action for the opcode\n"
10176 "-N do not return SCSI error for unsupported SA\n"
10177 "-T request nominal and recommended timeout values\n"
10178 "zone arguments:\n"
10179 "-c cmd required: rz, open, close, finish, or rwp\n"
10180 "-a apply the action to all zones\n"
10181 "-l LBA specify the zone starting LBA\n"
10182 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
10183 " closed, full, ro, offline, reset, nonseq, nonwp\n"
10184 "-P print_opt report zones printing: normal, summary, script\n"
10186 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
10187 " source, status, list\n"
10188 "-d disable power mode (timer, state)\n"
10189 "-D delayed entry (goto)\n"
10190 "-e enable power mode (timer, state)\n"
10191 "-H hold power mode (goto)\n"
10192 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
10194 "-P only display power mode (status)\n"
10195 "-r rst_src restore settings from: default, saved (restore)\n"
10196 "-s save mode (timer, state, restore)\n"
10197 "-S power_src set power source: battery, nonbattery (source)\n"
10198 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
10199 "timestamp arguments:\n"
10200 "-r report the timestamp of the device\n"
10201 "-f format report the timestamp of the device with the given\n"
10202 " strftime(3) format string\n"
10203 "-m report the timestamp of the device as milliseconds since\n"
10204 " January 1st, 1970\n"
10205 "-U report the time with UTC instead of the local time zone\n"
10206 "-s set the timestamp of the device\n"
10207 "-f format the format of the time string passed into strptime(3)\n"
10208 "-T time the time value passed into strptime(3)\n"
10209 "-U set the timestamp of the device to UTC time\n"
10211 #endif /* MINIMALISTIC */
10215 main(int argc, char **argv)
10218 char *device = NULL;
10220 struct cam_device *cam_dev = NULL;
10221 int timeout = 0, retry_count = 1;
10222 camcontrol_optret optreturn;
10224 const char *mainopt = "C:En:Q:t:u:v";
10225 const char *subopt = NULL;
10226 char combinedopt[256];
10227 int error = 0, optstart = 2;
10228 int task_attr = MSG_SIMPLE_Q_TAG;
10230 #ifndef MINIMALISTIC
10232 target_id_t target;
10234 #endif /* MINIMALISTIC */
10236 cmdlist = CAM_CMD_NONE;
10237 arglist = CAM_ARG_NONE;
10245 * Get the base option.
10247 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
10249 if (optreturn == CC_OR_AMBIGUOUS) {
10250 warnx("ambiguous option %s", argv[1]);
10253 } else if (optreturn == CC_OR_NOT_FOUND) {
10254 warnx("option %s not found", argv[1]);
10260 * Ahh, getopt(3) is a pain.
10262 * This is a gross hack. There really aren't many other good
10263 * options (excuse the pun) for parsing options in a situation like
10264 * this. getopt is kinda braindead, so you end up having to run
10265 * through the options twice, and give each invocation of getopt
10266 * the option string for the other invocation.
10268 * You would think that you could just have two groups of options.
10269 * The first group would get parsed by the first invocation of
10270 * getopt, and the second group would get parsed by the second
10271 * invocation of getopt. It doesn't quite work out that way. When
10272 * the first invocation of getopt finishes, it leaves optind pointing
10273 * to the argument _after_ the first argument in the second group.
10274 * So when the second invocation of getopt comes around, it doesn't
10275 * recognize the first argument it gets and then bails out.
10277 * A nice alternative would be to have a flag for getopt that says
10278 * "just keep parsing arguments even when you encounter an unknown
10279 * argument", but there isn't one. So there's no real clean way to
10280 * easily parse two sets of arguments without having one invocation
10281 * of getopt know about the other.
10283 * Without this hack, the first invocation of getopt would work as
10284 * long as the generic arguments are first, but the second invocation
10285 * (in the subfunction) would fail in one of two ways. In the case
10286 * where you don't set optreset, it would fail because optind may be
10287 * pointing to the argument after the one it should be pointing at.
10288 * In the case where you do set optreset, and reset optind, it would
10289 * fail because getopt would run into the first set of options, which
10290 * it doesn't understand.
10292 * All of this would "sort of" work if you could somehow figure out
10293 * whether optind had been incremented one option too far. The
10294 * mechanics of that, however, are more daunting than just giving
10295 * both invocations all of the expect options for either invocation.
10297 * Needless to say, I wouldn't mind if someone invented a better
10298 * (non-GPL!) command line parsing interface than getopt. I
10299 * wouldn't mind if someone added more knobs to getopt to make it
10300 * work better. Who knows, I may talk myself into doing it someday,
10301 * if the standards weenies let me. As it is, it just leads to
10302 * hackery like this and causes people to avoid it in some cases.
10304 * KDM, September 8th, 1998
10306 if (subopt != NULL)
10307 sprintf(combinedopt, "%s%s", mainopt, subopt);
10309 sprintf(combinedopt, "%s", mainopt);
10312 * For these options we do not parse optional device arguments and
10313 * we do not open a passthrough device.
10315 if ((cmdlist == CAM_CMD_RESCAN)
10316 || (cmdlist == CAM_CMD_RESET)
10317 || (cmdlist == CAM_CMD_DEVTREE)
10318 || (cmdlist == CAM_CMD_USAGE)
10319 || (cmdlist == CAM_CMD_DEBUG))
10322 #ifndef MINIMALISTIC
10324 && (argc > 2 && argv[2][0] != '-')) {
10328 if (isdigit(argv[2][0])) {
10329 /* device specified as bus:target[:lun] */
10330 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10332 errx(1, "numeric device specification must "
10333 "be either bus:target, or "
10335 /* default to 0 if lun was not specified */
10336 if ((arglist & CAM_ARG_LUN) == 0) {
10338 arglist |= CAM_ARG_LUN;
10342 if (cam_get_device(argv[2], name, sizeof name, &unit)
10344 errx(1, "%s", cam_errbuf);
10345 device = strdup(name);
10346 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10350 #endif /* MINIMALISTIC */
10352 * Start getopt processing at argv[2/3], since we've already
10353 * accepted argv[1..2] as the command name, and as a possible
10359 * Now we run through the argument list looking for generic
10360 * options, and ignoring options that possibly belong to
10363 while ((c = getopt(argc, argv, combinedopt))!= -1){
10366 retry_count = strtol(optarg, NULL, 0);
10367 if (retry_count < 0)
10368 errx(1, "retry count %d is < 0",
10370 arglist |= CAM_ARG_RETRIES;
10373 arglist |= CAM_ARG_ERR_RECOVER;
10376 arglist |= CAM_ARG_DEVICE;
10378 while (isspace(*tstr) && (*tstr != '\0'))
10380 device = (char *)strdup(tstr);
10384 int table_entry = 0;
10387 while (isspace(*tstr) && (*tstr != '\0'))
10389 if (isdigit(*tstr)) {
10390 task_attr = strtol(tstr, &endptr, 0);
10391 if (*endptr != '\0') {
10392 errx(1, "Invalid queue option "
10397 scsi_nv_status status;
10399 table_size = sizeof(task_attrs) /
10400 sizeof(task_attrs[0]);
10401 status = scsi_get_nv(task_attrs,
10402 table_size, tstr, &table_entry,
10403 SCSI_NV_FLAG_IG_CASE);
10404 if (status == SCSI_NV_FOUND)
10405 task_attr = task_attrs[
10406 table_entry].value;
10408 errx(1, "%s option %s",
10409 (status == SCSI_NV_AMBIGUOUS)?
10410 "ambiguous" : "invalid",
10417 timeout = strtol(optarg, NULL, 0);
10419 errx(1, "invalid timeout %d", timeout);
10420 /* Convert the timeout from seconds to ms */
10422 arglist |= CAM_ARG_TIMEOUT;
10425 arglist |= CAM_ARG_UNIT;
10426 unit = strtol(optarg, NULL, 0);
10429 arglist |= CAM_ARG_VERBOSE;
10436 #ifndef MINIMALISTIC
10438 * For most commands we'll want to open the passthrough device
10439 * associated with the specified device. In the case of the rescan
10440 * commands, we don't use a passthrough device at all, just the
10441 * transport layer device.
10443 if (devopen == 1) {
10444 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10445 && (((arglist & CAM_ARG_DEVICE) == 0)
10446 || ((arglist & CAM_ARG_UNIT) == 0))) {
10447 errx(1, "subcommand \"%s\" requires a valid device "
10448 "identifier", argv[1]);
10451 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10452 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10453 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10455 errx(1,"%s", cam_errbuf);
10457 #endif /* MINIMALISTIC */
10460 * Reset optind to 2, and reset getopt, so these routines can parse
10461 * the arguments again.
10467 #ifndef MINIMALISTIC
10468 case CAM_CMD_DEVLIST:
10469 error = getdevlist(cam_dev);
10472 error = atahpa(cam_dev, retry_count, timeout,
10473 argc, argv, combinedopt);
10476 error = ataama(cam_dev, retry_count, timeout,
10477 argc, argv, combinedopt);
10479 #endif /* MINIMALISTIC */
10480 case CAM_CMD_DEVTREE:
10481 error = getdevtree(argc, argv, combinedopt);
10483 case CAM_CMD_DEVTYPE:
10484 error = getdevtype(cam_dev);
10486 #ifndef MINIMALISTIC
10488 error = testunitready(cam_dev, task_attr, retry_count,
10491 case CAM_CMD_INQUIRY:
10492 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10493 task_attr, retry_count, timeout);
10495 case CAM_CMD_IDENTIFY:
10496 error = identify(cam_dev, retry_count, timeout);
10498 case CAM_CMD_STARTSTOP:
10499 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10500 arglist & CAM_ARG_EJECT, task_attr,
10501 retry_count, timeout);
10503 #endif /* MINIMALISTIC */
10504 case CAM_CMD_RESCAN:
10505 error = dorescan_or_reset(argc, argv, 1);
10507 case CAM_CMD_RESET:
10508 error = dorescan_or_reset(argc, argv, 0);
10510 #ifndef MINIMALISTIC
10511 case CAM_CMD_READ_DEFECTS:
10512 error = readdefects(cam_dev, argc, argv, combinedopt,
10513 task_attr, retry_count, timeout);
10515 case CAM_CMD_MODE_PAGE:
10516 modepage(cam_dev, argc, argv, combinedopt,
10517 task_attr, retry_count, timeout);
10519 case CAM_CMD_SCSI_CMD:
10520 error = scsicmd(cam_dev, argc, argv, combinedopt,
10521 task_attr, retry_count, timeout);
10523 case CAM_CMD_MMCSD_CMD:
10524 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10525 retry_count, timeout);
10527 case CAM_CMD_SMP_CMD:
10528 error = smpcmd(cam_dev, argc, argv, combinedopt,
10529 retry_count, timeout);
10531 case CAM_CMD_SMP_RG:
10532 error = smpreportgeneral(cam_dev, argc, argv,
10533 combinedopt, retry_count,
10536 case CAM_CMD_SMP_PC:
10537 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10538 retry_count, timeout);
10540 case CAM_CMD_SMP_PHYLIST:
10541 error = smpphylist(cam_dev, argc, argv, combinedopt,
10542 retry_count, timeout);
10544 case CAM_CMD_SMP_MANINFO:
10545 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10546 retry_count, timeout);
10548 case CAM_CMD_DEBUG:
10549 error = camdebug(argc, argv, combinedopt);
10552 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10555 error = ratecontrol(cam_dev, task_attr, retry_count,
10556 timeout, argc, argv, combinedopt);
10558 case CAM_CMD_FORMAT:
10559 error = scsiformat(cam_dev, argc, argv,
10560 combinedopt, task_attr, retry_count,
10563 case CAM_CMD_REPORTLUNS:
10564 error = scsireportluns(cam_dev, argc, argv,
10565 combinedopt, task_attr,
10566 retry_count, timeout);
10568 case CAM_CMD_READCAP:
10569 error = scsireadcapacity(cam_dev, argc, argv,
10570 combinedopt, task_attr,
10571 retry_count, timeout);
10574 case CAM_CMD_STANDBY:
10575 case CAM_CMD_SLEEP:
10576 case CAM_CMD_POWER_MODE:
10577 error = atapm(cam_dev, argc, argv,
10578 combinedopt, retry_count, timeout);
10582 error = ataaxm(cam_dev, argc, argv,
10583 combinedopt, retry_count, timeout);
10585 case CAM_CMD_SECURITY:
10586 error = atasecurity(cam_dev, retry_count, timeout,
10587 argc, argv, combinedopt);
10589 case CAM_CMD_DOWNLOAD_FW:
10590 error = fwdownload(cam_dev, argc, argv, combinedopt,
10591 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10594 case CAM_CMD_SANITIZE:
10595 error = sanitize(cam_dev, argc, argv, combinedopt, task_attr,
10596 retry_count, timeout);
10598 case CAM_CMD_PERSIST:
10599 error = scsipersist(cam_dev, argc, argv, combinedopt,
10600 task_attr, retry_count, timeout,
10601 arglist & CAM_ARG_VERBOSE,
10602 arglist & CAM_ARG_ERR_RECOVER);
10604 case CAM_CMD_ATTRIB:
10605 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10606 task_attr, retry_count, timeout,
10607 arglist & CAM_ARG_VERBOSE,
10608 arglist & CAM_ARG_ERR_RECOVER);
10610 case CAM_CMD_OPCODES:
10611 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10612 task_attr, retry_count, timeout,
10613 arglist & CAM_ARG_VERBOSE);
10615 case CAM_CMD_REPROBE:
10616 error = reprobe(cam_dev);
10619 error = zone(cam_dev, argc, argv, combinedopt,
10620 task_attr, retry_count, timeout,
10621 arglist & CAM_ARG_VERBOSE);
10624 error = epc(cam_dev, argc, argv, combinedopt,
10625 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10627 case CAM_CMD_TIMESTAMP:
10628 error = timestamp(cam_dev, argc, argv, combinedopt,
10629 task_attr, retry_count, timeout,
10630 arglist & CAM_ARG_VERBOSE);
10632 #endif /* MINIMALISTIC */
10633 case CAM_CMD_USAGE:
10642 if (cam_dev != NULL)
10643 cam_close_device(cam_dev);