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, "bdelm:P:"},
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 dorescan_or_reset(int argc, char **argv, int rescan);
319 static int rescan_or_reset_bus(path_id_t bus, int rescan);
320 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
321 lun_id_t lun, int scan);
323 static int readdefects(struct cam_device *device, int argc, char **argv,
324 char *combinedopt, int task_attr, int retry_count,
326 static void modepage(struct cam_device *device, int argc, char **argv,
327 char *combinedopt, int task_attr, int retry_count,
329 static int scsicmd(struct cam_device *device, int argc, char **argv,
330 char *combinedopt, int task_attr, int retry_count,
332 static int smpcmd(struct cam_device *device, int argc, char **argv,
333 char *combinedopt, int retry_count, int timeout);
334 static int mmcsdcmd(struct cam_device *device, int argc, char **argv,
335 char *combinedopt, int retry_count, int timeout);
336 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
337 char *combinedopt, int retry_count, int timeout);
338 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
339 char *combinedopt, int retry_count, int timeout);
340 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
341 char *combinedopt, int retry_count, int timeout);
342 static int getdevid(struct cam_devitem *item);
343 static int buildbusdevlist(struct cam_devlist *devlist);
344 static void freebusdevlist(struct cam_devlist *devlist);
345 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
347 static int smpphylist(struct cam_device *device, int argc, char **argv,
348 char *combinedopt, int retry_count, int timeout);
349 static int tagcontrol(struct cam_device *device, int argc, char **argv,
351 static void cts_print(struct cam_device *device,
352 struct ccb_trans_settings *cts);
353 static void cpi_print(struct ccb_pathinq *cpi);
354 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
355 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
356 static int get_print_cts(struct cam_device *device, int user_settings,
357 int quiet, struct ccb_trans_settings *cts);
358 static int ratecontrol(struct cam_device *device, int task_attr,
359 int retry_count, int timeout, int argc, char **argv,
361 static int scsiformat(struct cam_device *device, int argc, char **argv,
362 char *combinedopt, int task_attr, int retry_count,
364 static int scsisanitize(struct cam_device *device, int argc, char **argv,
365 char *combinedopt, int task_attr, int retry_count,
367 static int scsireportluns(struct cam_device *device, int argc, char **argv,
368 char *combinedopt, int task_attr, int retry_count,
370 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
371 char *combinedopt, int task_attr, int retry_count,
373 static int atapm(struct cam_device *device, int argc, char **argv,
374 char *combinedopt, int retry_count, int timeout);
375 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
376 int argc, char **argv, char *combinedopt);
377 static int atahpa(struct cam_device *device, int retry_count, int timeout,
378 int argc, char **argv, char *combinedopt);
379 static int ataama(struct cam_device *device, int retry_count, int timeout,
380 int argc, char **argv, char *combinedopt);
381 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
382 int sa_set, int req_sa, uint8_t *buf,
384 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
386 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
387 char *combinedopt, int task_attr, int retry_count,
388 int timeout, int verbose);
389 static int scsireprobe(struct cam_device *device);
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 perror("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 CAMIOCOMMAND ioctl");
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 CAMIOCOMMAND ioctl");
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 perror("error sending test unit ready");
900 if (arglist & CAM_ARG_VERBOSE) {
901 cam_error_print(device, ccb, CAM_ESF_ALL,
902 CAM_EPF_ALL, stderr);
909 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
911 fprintf(stdout, "Unit is ready\n");
914 fprintf(stdout, "Unit is not ready\n");
917 if (arglist & CAM_ARG_VERBOSE) {
918 cam_error_print(device, ccb, CAM_ESF_ALL,
919 CAM_EPF_ALL, stderr);
929 scsistart(struct cam_device *device, int startstop, int loadeject,
930 int task_attr, int retry_count, int timeout)
935 ccb = cam_getccb(device);
938 * If we're stopping, send an ordered tag so the drive in question
939 * will finish any previously queued writes before stopping. If
940 * the device isn't capable of tagged queueing, or if tagged
941 * queueing is turned off, the tag action is a no-op. We override
942 * the default simple tag, although this also has the effect of
943 * overriding the user's wishes if he wanted to specify a simple
947 && (task_attr == MSG_SIMPLE_Q_TAG))
948 task_attr = MSG_ORDERED_Q_TAG;
950 scsi_start_stop(&ccb->csio,
951 /* retries */ retry_count,
953 /* tag_action */ task_attr,
954 /* start/stop */ startstop,
955 /* load_eject */ loadeject,
957 /* sense_len */ SSD_FULL_SIZE,
958 /* timeout */ timeout ? timeout : 120000);
960 /* Disable freezing the device queue */
961 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
963 if (arglist & CAM_ARG_ERR_RECOVER)
964 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
966 if (cam_send_ccb(device, ccb) < 0) {
967 perror("error sending start unit");
969 if (arglist & CAM_ARG_VERBOSE) {
970 cam_error_print(device, ccb, CAM_ESF_ALL,
971 CAM_EPF_ALL, stderr);
978 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
980 fprintf(stdout, "Unit started successfully");
982 fprintf(stdout,", Media loaded\n");
984 fprintf(stdout,"\n");
986 fprintf(stdout, "Unit stopped successfully");
988 fprintf(stdout, ", Media ejected\n");
990 fprintf(stdout, "\n");
996 "Error received from start unit command\n");
999 "Error received from stop unit command\n");
1001 if (arglist & CAM_ARG_VERBOSE) {
1002 cam_error_print(device, ccb, CAM_ESF_ALL,
1003 CAM_EPF_ALL, stderr);
1013 scsidoinquiry(struct cam_device *device, int argc, char **argv,
1014 char *combinedopt, int task_attr, int retry_count, int timeout)
1019 while ((c = getopt(argc, argv, combinedopt)) != -1) {
1022 arglist |= CAM_ARG_GET_STDINQ;
1025 arglist |= CAM_ARG_GET_XFERRATE;
1028 arglist |= CAM_ARG_GET_SERIAL;
1036 * If the user didn't specify any inquiry options, he wants all of
1039 if ((arglist & CAM_ARG_INQ_MASK) == 0)
1040 arglist |= CAM_ARG_INQ_MASK;
1042 if (arglist & CAM_ARG_GET_STDINQ)
1043 error = scsiinquiry(device, task_attr, retry_count, timeout);
1048 if (arglist & CAM_ARG_GET_SERIAL)
1049 scsiserial(device, task_attr, retry_count, timeout);
1051 if (arglist & CAM_ARG_GET_XFERRATE)
1052 error = camxferrate(device);
1058 scsiinquiry(struct cam_device *device, int task_attr, int retry_count,
1062 struct scsi_inquiry_data *inq_buf;
1065 ccb = cam_getccb(device);
1068 warnx("couldn't allocate CCB");
1072 /* cam_getccb cleans up the header, caller has to zero the payload */
1073 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1075 inq_buf = (struct scsi_inquiry_data *)malloc(
1076 sizeof(struct scsi_inquiry_data));
1078 if (inq_buf == NULL) {
1080 warnx("can't malloc memory for inquiry\n");
1083 bzero(inq_buf, sizeof(*inq_buf));
1086 * Note that although the size of the inquiry buffer is the full
1087 * 256 bytes specified in the SCSI spec, we only tell the device
1088 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
1089 * two reasons for this:
1091 * - The SCSI spec says that when a length field is only 1 byte,
1092 * a value of 0 will be interpreted as 256. Therefore
1093 * scsi_inquiry() will convert an inq_len (which is passed in as
1094 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
1095 * to 0. Evidently, very few devices meet the spec in that
1096 * regard. Some devices, like many Seagate disks, take the 0 as
1097 * 0, and don't return any data. One Pioneer DVD-R drive
1098 * returns more data than the command asked for.
1100 * So, since there are numerous devices that just don't work
1101 * right with the full inquiry size, we don't send the full size.
1103 * - The second reason not to use the full inquiry data length is
1104 * that we don't need it here. The only reason we issue a
1105 * standard inquiry is to get the vendor name, device name,
1106 * and revision so scsi_print_inquiry() can print them.
1108 * If, at some point in the future, more inquiry data is needed for
1109 * some reason, this code should use a procedure similar to the
1110 * probe code. i.e., issue a short inquiry, and determine from
1111 * the additional length passed back from the device how much
1112 * inquiry data the device supports. Once the amount the device
1113 * supports is determined, issue an inquiry for that amount and no
1118 scsi_inquiry(&ccb->csio,
1119 /* retries */ retry_count,
1121 /* tag_action */ task_attr,
1122 /* inq_buf */ (u_int8_t *)inq_buf,
1123 /* inq_len */ SHORT_INQUIRY_LENGTH,
1126 /* sense_len */ SSD_FULL_SIZE,
1127 /* timeout */ timeout ? timeout : 5000);
1129 /* Disable freezing the device queue */
1130 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1132 if (arglist & CAM_ARG_ERR_RECOVER)
1133 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1135 if (cam_send_ccb(device, ccb) < 0) {
1136 perror("error sending SCSI inquiry");
1138 if (arglist & CAM_ARG_VERBOSE) {
1139 cam_error_print(device, ccb, CAM_ESF_ALL,
1140 CAM_EPF_ALL, stderr);
1147 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1150 if (arglist & CAM_ARG_VERBOSE) {
1151 cam_error_print(device, ccb, CAM_ESF_ALL,
1152 CAM_EPF_ALL, stderr);
1163 fprintf(stdout, "%s%d: ", device->device_name,
1164 device->dev_unit_num);
1165 scsi_print_inquiry(inq_buf);
1173 scsiserial(struct cam_device *device, int task_attr, int retry_count,
1177 struct scsi_vpd_unit_serial_number *serial_buf;
1178 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
1181 ccb = cam_getccb(device);
1184 warnx("couldn't allocate CCB");
1188 /* cam_getccb cleans up the header, caller has to zero the payload */
1189 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1191 serial_buf = (struct scsi_vpd_unit_serial_number *)
1192 malloc(sizeof(*serial_buf));
1194 if (serial_buf == NULL) {
1196 warnx("can't malloc memory for serial number");
1200 scsi_inquiry(&ccb->csio,
1201 /*retries*/ retry_count,
1203 /* tag_action */ task_attr,
1204 /* inq_buf */ (u_int8_t *)serial_buf,
1205 /* inq_len */ sizeof(*serial_buf),
1207 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
1208 /* sense_len */ SSD_FULL_SIZE,
1209 /* timeout */ timeout ? timeout : 5000);
1211 /* Disable freezing the device queue */
1212 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1214 if (arglist & CAM_ARG_ERR_RECOVER)
1215 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1217 if (cam_send_ccb(device, ccb) < 0) {
1218 warn("error getting serial number");
1220 if (arglist & CAM_ARG_VERBOSE) {
1221 cam_error_print(device, ccb, CAM_ESF_ALL,
1222 CAM_EPF_ALL, stderr);
1230 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1233 if (arglist & CAM_ARG_VERBOSE) {
1234 cam_error_print(device, ccb, CAM_ESF_ALL,
1235 CAM_EPF_ALL, stderr);
1246 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1247 serial_num[serial_buf->length] = '\0';
1249 if ((arglist & CAM_ARG_GET_STDINQ)
1250 || (arglist & CAM_ARG_GET_XFERRATE))
1251 fprintf(stdout, "%s%d: Serial Number ",
1252 device->device_name, device->dev_unit_num);
1254 fprintf(stdout, "%.60s\n", serial_num);
1262 camxferrate(struct cam_device *device)
1264 struct ccb_pathinq cpi;
1266 u_int32_t speed = 0;
1271 if ((retval = get_cpi(device, &cpi)) != 0)
1274 ccb = cam_getccb(device);
1277 warnx("couldn't allocate CCB");
1281 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
1283 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1284 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1286 if (((retval = cam_send_ccb(device, ccb)) < 0)
1287 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1288 const char error_string[] = "error getting transfer settings";
1293 warnx(error_string);
1295 if (arglist & CAM_ARG_VERBOSE)
1296 cam_error_print(device, ccb, CAM_ESF_ALL,
1297 CAM_EPF_ALL, stderr);
1301 goto xferrate_bailout;
1305 speed = cpi.base_transfer_speed;
1307 if (ccb->cts.transport == XPORT_SPI) {
1308 struct ccb_trans_settings_spi *spi =
1309 &ccb->cts.xport_specific.spi;
1311 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1312 freq = scsi_calc_syncsrate(spi->sync_period);
1315 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1316 speed *= (0x01 << spi->bus_width);
1318 } else if (ccb->cts.transport == XPORT_FC) {
1319 struct ccb_trans_settings_fc *fc =
1320 &ccb->cts.xport_specific.fc;
1322 if (fc->valid & CTS_FC_VALID_SPEED)
1323 speed = fc->bitrate;
1324 } else if (ccb->cts.transport == XPORT_SAS) {
1325 struct ccb_trans_settings_sas *sas =
1326 &ccb->cts.xport_specific.sas;
1328 if (sas->valid & CTS_SAS_VALID_SPEED)
1329 speed = sas->bitrate;
1330 } else if (ccb->cts.transport == XPORT_ATA) {
1331 struct ccb_trans_settings_pata *pata =
1332 &ccb->cts.xport_specific.ata;
1334 if (pata->valid & CTS_ATA_VALID_MODE)
1335 speed = ata_mode2speed(pata->mode);
1336 } else if (ccb->cts.transport == XPORT_SATA) {
1337 struct ccb_trans_settings_sata *sata =
1338 &ccb->cts.xport_specific.sata;
1340 if (sata->valid & CTS_SATA_VALID_REVISION)
1341 speed = ata_revision2speed(sata->revision);
1346 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1347 device->device_name, device->dev_unit_num,
1350 fprintf(stdout, "%s%d: %dKB/s transfers",
1351 device->device_name, device->dev_unit_num,
1355 if (ccb->cts.transport == XPORT_SPI) {
1356 struct ccb_trans_settings_spi *spi =
1357 &ccb->cts.xport_specific.spi;
1359 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1360 && (spi->sync_offset != 0))
1361 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1362 freq % 1000, spi->sync_offset);
1364 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1365 && (spi->bus_width > 0)) {
1366 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1367 && (spi->sync_offset != 0)) {
1368 fprintf(stdout, ", ");
1370 fprintf(stdout, " (");
1372 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1373 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1374 && (spi->sync_offset != 0)) {
1375 fprintf(stdout, ")");
1377 } else if (ccb->cts.transport == XPORT_ATA) {
1378 struct ccb_trans_settings_pata *pata =
1379 &ccb->cts.xport_specific.ata;
1382 if (pata->valid & CTS_ATA_VALID_MODE)
1383 printf("%s, ", ata_mode2string(pata->mode));
1384 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1385 printf("ATAPI %dbytes, ", pata->atapi);
1386 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1387 printf("PIO %dbytes", pata->bytecount);
1389 } else if (ccb->cts.transport == XPORT_SATA) {
1390 struct ccb_trans_settings_sata *sata =
1391 &ccb->cts.xport_specific.sata;
1394 if (sata->valid & CTS_SATA_VALID_REVISION)
1395 printf("SATA %d.x, ", sata->revision);
1398 if (sata->valid & CTS_SATA_VALID_MODE)
1399 printf("%s, ", ata_mode2string(sata->mode));
1400 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1401 printf("ATAPI %dbytes, ", sata->atapi);
1402 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1403 printf("PIO %dbytes", sata->bytecount);
1407 if (ccb->cts.protocol == PROTO_SCSI) {
1408 struct ccb_trans_settings_scsi *scsi =
1409 &ccb->cts.proto_specific.scsi;
1410 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1411 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1412 fprintf(stdout, ", Command Queueing Enabled");
1417 fprintf(stdout, "\n");
1427 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1429 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1430 ((u_int32_t)parm->lba_size_2 << 16);
1432 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1433 ((u_int64_t)parm->lba_size48_2 << 16) |
1434 ((u_int64_t)parm->lba_size48_3 << 32) |
1435 ((u_int64_t)parm->lba_size48_4 << 48);
1439 "Support Enabled Value\n");
1442 printf("Host Protected Area (HPA) ");
1443 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1444 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1445 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1448 printf("HPA - Security ");
1449 if (parm->support.command2 & ATA_SUPPORT_MAXSECURITY)
1450 printf("yes %s\n", (parm->enabled.command2 &
1451 ATA_SUPPORT_MAXSECURITY) ? "yes" : "no ");
1460 ataama_print(struct ata_params *parm, u_int64_t nativesize, int header)
1462 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1463 ((u_int32_t)parm->lba_size_2 << 16);
1465 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1466 ((u_int64_t)parm->lba_size48_2 << 16) |
1467 ((u_int64_t)parm->lba_size48_3 << 32) |
1468 ((u_int64_t)parm->lba_size48_4 << 48);
1472 "Support Enabled Value\n");
1475 printf("Accessible Max Address Config ");
1476 if (parm->support2 & ATA_SUPPORT_AMAX_ADDR) {
1477 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1478 printf("yes %s %ju/%ju\n",
1479 (nativesize > lba) ? "yes" : "no ", lba, nativesize);
1486 atasata(struct ata_params *parm)
1490 if (parm->satacapabilities != 0xffff &&
1491 parm->satacapabilities != 0x0000)
1498 atacapprint(struct ata_params *parm)
1501 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1502 ((u_int32_t)parm->lba_size_2 << 16);
1504 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1505 ((u_int64_t)parm->lba_size48_2 << 16) |
1506 ((u_int64_t)parm->lba_size48_3 << 32) |
1507 ((u_int64_t)parm->lba_size48_4 << 48);
1510 printf("protocol ");
1511 proto = (parm->config == ATA_PROTO_CFA) ? "CFA" :
1512 (parm->config & ATA_PROTO_ATAPI) ? "ATAPI" : "ATA";
1513 if (ata_version(parm->version_major) == 0) {
1514 printf("%s", proto);
1515 } else if (ata_version(parm->version_major) <= 7) {
1516 printf("%s-%d", proto,
1517 ata_version(parm->version_major));
1518 } else if (ata_version(parm->version_major) == 8) {
1519 printf("%s8-ACS", proto);
1522 ata_version(parm->version_major) - 7, proto);
1524 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1525 if (parm->satacapabilities & ATA_SATA_GEN3)
1526 printf(" SATA 3.x\n");
1527 else if (parm->satacapabilities & ATA_SATA_GEN2)
1528 printf(" SATA 2.x\n");
1529 else if (parm->satacapabilities & ATA_SATA_GEN1)
1530 printf(" SATA 1.x\n");
1536 printf("device model %.40s\n", parm->model);
1537 printf("firmware revision %.8s\n", parm->revision);
1538 printf("serial number %.20s\n", parm->serial);
1539 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1540 printf("WWN %04x%04x%04x%04x\n",
1541 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1543 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1544 printf("media serial number %.30s\n",
1545 parm->media_serial);
1548 printf("cylinders %d\n", parm->cylinders);
1549 printf("heads %d\n", parm->heads);
1550 printf("sectors/track %d\n", parm->sectors);
1551 printf("sector size logical %u, physical %lu, offset %lu\n",
1552 ata_logical_sector_size(parm),
1553 (unsigned long)ata_physical_sector_size(parm),
1554 (unsigned long)ata_logical_sector_offset(parm));
1556 if (parm->config == ATA_PROTO_CFA ||
1557 (parm->support.command2 & ATA_SUPPORT_CFA))
1558 printf("CFA supported\n");
1560 printf("LBA%ssupported ",
1561 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1563 printf("%d sectors\n", lbasize);
1567 printf("LBA48%ssupported ",
1568 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1570 printf("%ju sectors\n", (uintmax_t)lbasize48);
1574 printf("PIO supported PIO");
1575 switch (ata_max_pmode(parm)) {
1591 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1592 printf(" w/o IORDY");
1595 printf("DMA%ssupported ",
1596 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1597 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1598 if (parm->mwdmamodes & 0xff) {
1600 if (parm->mwdmamodes & 0x04)
1602 else if (parm->mwdmamodes & 0x02)
1604 else if (parm->mwdmamodes & 0x01)
1608 if ((parm->atavalid & ATA_FLAG_88) &&
1609 (parm->udmamodes & 0xff)) {
1611 if (parm->udmamodes & 0x40)
1613 else if (parm->udmamodes & 0x20)
1615 else if (parm->udmamodes & 0x10)
1617 else if (parm->udmamodes & 0x08)
1619 else if (parm->udmamodes & 0x04)
1621 else if (parm->udmamodes & 0x02)
1623 else if (parm->udmamodes & 0x01)
1630 if (parm->media_rotation_rate == 1) {
1631 printf("media RPM non-rotating\n");
1632 } else if (parm->media_rotation_rate >= 0x0401 &&
1633 parm->media_rotation_rate <= 0xFFFE) {
1634 printf("media RPM %d\n",
1635 parm->media_rotation_rate);
1638 printf("Zoned-Device Commands ");
1639 switch (parm->support3 & ATA_SUPPORT_ZONE_MASK) {
1640 case ATA_SUPPORT_ZONE_DEV_MANAGED:
1641 printf("device managed\n");
1643 case ATA_SUPPORT_ZONE_HOST_AWARE:
1644 printf("host aware\n");
1651 "Support Enabled Value Vendor\n");
1652 printf("read ahead %s %s\n",
1653 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1654 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1655 printf("write cache %s %s\n",
1656 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1657 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1658 printf("flush cache %s %s\n",
1659 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1660 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1661 printf("overlap %s\n",
1662 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1663 printf("Tagged Command Queuing (TCQ) %s %s",
1664 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1665 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1666 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1667 printf(" %d tags\n",
1668 ATA_QUEUE_LEN(parm->queue) + 1);
1671 printf("Native Command Queuing (NCQ) ");
1672 if (parm->satacapabilities != 0xffff &&
1673 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1674 printf("yes %d tags\n",
1675 ATA_QUEUE_LEN(parm->queue) + 1);
1679 printf("NCQ Queue Management %s\n", atasata(parm) &&
1680 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1682 printf("NCQ Streaming %s\n", atasata(parm) &&
1683 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1685 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1686 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1689 printf("SMART %s %s\n",
1690 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1691 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1692 printf("microcode download %s %s\n",
1693 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1694 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1695 printf("security %s %s\n",
1696 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1697 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1698 printf("power management %s %s\n",
1699 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1700 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1701 printf("advanced power management %s %s",
1702 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1703 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1704 if (parm->support.command2 & ATA_SUPPORT_APM) {
1705 printf(" %d/0x%02X\n",
1706 parm->apm_value & 0xff, parm->apm_value & 0xff);
1709 printf("automatic acoustic management %s %s",
1710 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1711 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1712 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1713 printf(" %d/0x%02X %d/0x%02X\n",
1714 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1715 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1716 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1717 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1720 printf("media status notification %s %s\n",
1721 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1722 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1723 printf("power-up in Standby %s %s\n",
1724 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1725 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1726 printf("write-read-verify %s %s",
1727 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1728 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1729 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1730 printf(" %d/0x%x\n",
1731 parm->wrv_mode, parm->wrv_mode);
1734 printf("unload %s %s\n",
1735 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1736 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1737 printf("general purpose logging %s %s\n",
1738 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1739 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1740 printf("free-fall %s %s\n",
1741 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1742 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1743 printf("Data Set Management (DSM/TRIM) ");
1744 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1746 printf("DSM - max 512byte blocks ");
1747 if (parm->max_dsm_blocks == 0x00)
1748 printf("yes not specified\n");
1751 parm->max_dsm_blocks);
1753 printf("DSM - deterministic read ");
1754 if (parm->support3 & ATA_SUPPORT_DRAT) {
1755 if (parm->support3 & ATA_SUPPORT_RZAT)
1756 printf("yes zeroed\n");
1758 printf("yes any value\n");
1768 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1770 struct ata_pass_16 *ata_pass_16;
1771 struct ata_cmd ata_cmd;
1773 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1774 ata_cmd.command = ata_pass_16->command;
1775 ata_cmd.control = ata_pass_16->control;
1776 ata_cmd.features = ata_pass_16->features;
1778 if (arglist & CAM_ARG_VERBOSE) {
1779 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1780 ata_op_string(&ata_cmd),
1781 ccb->csio.ccb_h.timeout);
1784 /* Disable freezing the device queue */
1785 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1787 if (arglist & CAM_ARG_ERR_RECOVER)
1788 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1790 if (cam_send_ccb(device, ccb) < 0) {
1791 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1792 warn("error sending ATA %s via pass_16",
1793 ata_op_string(&ata_cmd));
1796 if (arglist & CAM_ARG_VERBOSE) {
1797 cam_error_print(device, ccb, CAM_ESF_ALL,
1798 CAM_EPF_ALL, stderr);
1804 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1805 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1806 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1807 warnx("ATA %s via pass_16 failed",
1808 ata_op_string(&ata_cmd));
1810 if (arglist & CAM_ARG_VERBOSE) {
1811 cam_error_print(device, ccb, CAM_ESF_ALL,
1812 CAM_EPF_ALL, stderr);
1823 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1825 if (arglist & CAM_ARG_VERBOSE) {
1826 warnx("sending ATA %s with timeout of %u msecs",
1827 ata_op_string(&(ccb->ataio.cmd)),
1828 ccb->ataio.ccb_h.timeout);
1831 /* Disable freezing the device queue */
1832 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1834 if (arglist & CAM_ARG_ERR_RECOVER)
1835 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1837 if (cam_send_ccb(device, ccb) < 0) {
1838 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1839 warn("error sending ATA %s",
1840 ata_op_string(&(ccb->ataio.cmd)));
1843 if (arglist & CAM_ARG_VERBOSE) {
1844 cam_error_print(device, ccb, CAM_ESF_ALL,
1845 CAM_EPF_ALL, stderr);
1851 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1852 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1853 warnx("ATA %s failed: %d",
1854 ata_op_string(&(ccb->ataio.cmd)), quiet);
1857 if (arglist & CAM_ARG_VERBOSE) {
1858 cam_error_print(device, ccb, CAM_ESF_ALL,
1859 CAM_EPF_ALL, stderr);
1869 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1870 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1871 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1872 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1873 u_int16_t dxfer_len, int timeout, int quiet)
1875 if (data_ptr != NULL) {
1876 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1877 AP_FLAG_TLEN_SECT_CNT;
1878 if (flags & CAM_DIR_OUT)
1879 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1881 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1883 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1886 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1888 scsi_ata_pass_16(&ccb->csio,
1902 /*sense_len*/SSD_FULL_SIZE,
1905 return scsi_cam_pass_16_send(device, ccb, quiet);
1909 ata_try_pass_16(struct cam_device *device)
1911 struct ccb_pathinq cpi;
1913 if (get_cpi(device, &cpi) != 0) {
1914 warnx("couldn't get CPI");
1918 if (cpi.protocol == PROTO_SCSI) {
1919 /* possibly compatible with pass_16 */
1923 /* likely not compatible with pass_16 */
1928 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1929 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1930 u_int8_t command, u_int8_t features, u_int32_t lba,
1931 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1932 int timeout, int quiet)
1936 switch (ata_try_pass_16(device)) {
1940 /* Try using SCSI Passthrough */
1941 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1942 0, tag_action, command, features, lba,
1943 sector_count, data_ptr, dxfer_len,
1947 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1948 cam_fill_ataio(&ccb->ataio,
1957 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1958 return ata_cam_send(device, ccb, quiet);
1962 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1963 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1964 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1965 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1966 u_int16_t dxfer_len, int timeout, int force48bit)
1970 retval = ata_try_pass_16(device);
1977 /* Try using SCSI Passthrough */
1978 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1979 ata_flags, tag_action, command, features,
1980 lba, sector_count, data_ptr, dxfer_len,
1983 if (ata_flags & AP_FLAG_CHK_COND) {
1984 /* Decode ata_res from sense data */
1985 struct ata_res_pass16 *res_pass16;
1986 struct ata_res *res;
1990 /* sense_data is 4 byte aligned */
1991 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1992 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1993 ptr[i] = le16toh(ptr[i]);
1995 /* sense_data is 4 byte aligned */
1996 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1997 &ccb->csio.sense_data;
1998 res = &ccb->ataio.res;
1999 res->flags = res_pass16->flags;
2000 res->status = res_pass16->status;
2001 res->error = res_pass16->error;
2002 res->lba_low = res_pass16->lba_low;
2003 res->lba_mid = res_pass16->lba_mid;
2004 res->lba_high = res_pass16->lba_high;
2005 res->device = res_pass16->device;
2006 res->lba_low_exp = res_pass16->lba_low_exp;
2007 res->lba_mid_exp = res_pass16->lba_mid_exp;
2008 res->lba_high_exp = res_pass16->lba_high_exp;
2009 res->sector_count = res_pass16->sector_count;
2010 res->sector_count_exp = res_pass16->sector_count_exp;
2016 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
2017 cam_fill_ataio(&ccb->ataio,
2026 if (force48bit || lba > ATA_MAX_28BIT_LBA)
2027 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
2029 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
2031 if (ata_flags & AP_FLAG_CHK_COND)
2032 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
2034 return ata_cam_send(device, ccb, 0);
2038 dump_data(uint16_t *ptr, uint32_t len)
2042 for (i = 0; i < len / 2; i++) {
2044 printf(" %3d: ", i);
2045 printf("%04hx ", ptr[i]);
2054 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
2055 int is48bit, u_int64_t *hpasize)
2057 struct ata_res *res;
2059 res = &ccb->ataio.res;
2060 if (res->status & ATA_STATUS_ERROR) {
2061 if (arglist & CAM_ARG_VERBOSE) {
2062 cam_error_print(device, ccb, CAM_ESF_ALL,
2063 CAM_EPF_ALL, stderr);
2064 printf("error = 0x%02x, sector_count = 0x%04x, "
2065 "device = 0x%02x, status = 0x%02x\n",
2066 res->error, res->sector_count,
2067 res->device, res->status);
2070 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
2071 warnx("Max address has already been set since "
2072 "last power-on or hardware reset");
2078 if (arglist & CAM_ARG_VERBOSE) {
2079 fprintf(stdout, "%s%d: Raw native max data:\n",
2080 device->device_name, device->dev_unit_num);
2081 /* res is 4 byte aligned */
2082 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
2084 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
2085 "status = 0x%02x\n", res->error, res->sector_count,
2086 res->device, res->status);
2089 if (hpasize != NULL) {
2091 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
2092 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
2093 ((res->lba_high << 16) | (res->lba_mid << 8) |
2096 *hpasize = (((res->device & 0x0f) << 24) |
2097 (res->lba_high << 16) | (res->lba_mid << 8) |
2106 ata_read_native_max(struct cam_device *device, int retry_count,
2107 u_int32_t timeout, union ccb *ccb,
2108 struct ata_params *parm, u_int64_t *hpasize)
2114 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
2115 protocol = AP_PROTO_NON_DATA;
2118 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
2119 protocol |= AP_EXTEND;
2121 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
2124 error = ata_do_cmd(device,
2127 /*flags*/CAM_DIR_NONE,
2128 /*protocol*/protocol,
2129 /*ata_flags*/AP_FLAG_CHK_COND,
2130 /*tag_action*/MSG_SIMPLE_Q_TAG,
2137 timeout ? timeout : 5000,
2143 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
2147 atahpa_set_max(struct cam_device *device, int retry_count,
2148 u_int32_t timeout, union ccb *ccb,
2149 int is48bit, u_int64_t maxsize, int persist)
2155 protocol = AP_PROTO_NON_DATA;
2158 cmd = ATA_SET_MAX_ADDRESS48;
2159 protocol |= AP_EXTEND;
2161 cmd = ATA_SET_MAX_ADDRESS;
2164 /* lba's are zero indexed so the max lba is requested max - 1 */
2168 error = ata_do_cmd(device,
2171 /*flags*/CAM_DIR_NONE,
2172 /*protocol*/protocol,
2173 /*ata_flags*/AP_FLAG_CHK_COND,
2174 /*tag_action*/MSG_SIMPLE_Q_TAG,
2176 /*features*/ATA_HPA_FEAT_MAX_ADDR,
2178 /*sector_count*/persist,
2181 timeout ? timeout : 1000,
2187 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2191 atahpa_password(struct cam_device *device, int retry_count,
2192 u_int32_t timeout, union ccb *ccb,
2193 int is48bit, struct ata_set_max_pwd *pwd)
2199 protocol = AP_PROTO_PIO_OUT;
2200 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2202 error = ata_do_cmd(device,
2205 /*flags*/CAM_DIR_OUT,
2206 /*protocol*/protocol,
2207 /*ata_flags*/AP_FLAG_CHK_COND,
2208 /*tag_action*/MSG_SIMPLE_Q_TAG,
2210 /*features*/ATA_HPA_FEAT_SET_PWD,
2213 /*data_ptr*/(u_int8_t*)pwd,
2214 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2215 timeout ? timeout : 1000,
2221 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2225 atahpa_lock(struct cam_device *device, int retry_count,
2226 u_int32_t timeout, union ccb *ccb, int is48bit)
2232 protocol = AP_PROTO_NON_DATA;
2233 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2235 error = ata_do_cmd(device,
2238 /*flags*/CAM_DIR_NONE,
2239 /*protocol*/protocol,
2240 /*ata_flags*/AP_FLAG_CHK_COND,
2241 /*tag_action*/MSG_SIMPLE_Q_TAG,
2243 /*features*/ATA_HPA_FEAT_LOCK,
2248 timeout ? timeout : 1000,
2254 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2258 atahpa_unlock(struct cam_device *device, int retry_count,
2259 u_int32_t timeout, union ccb *ccb,
2260 int is48bit, struct ata_set_max_pwd *pwd)
2266 protocol = AP_PROTO_PIO_OUT;
2267 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2269 error = ata_do_cmd(device,
2272 /*flags*/CAM_DIR_OUT,
2273 /*protocol*/protocol,
2274 /*ata_flags*/AP_FLAG_CHK_COND,
2275 /*tag_action*/MSG_SIMPLE_Q_TAG,
2277 /*features*/ATA_HPA_FEAT_UNLOCK,
2280 /*data_ptr*/(u_int8_t*)pwd,
2281 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2282 timeout ? timeout : 1000,
2288 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2292 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2293 u_int32_t timeout, union ccb *ccb, int is48bit)
2299 protocol = AP_PROTO_NON_DATA;
2300 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2302 error = ata_do_cmd(device,
2305 /*flags*/CAM_DIR_NONE,
2306 /*protocol*/protocol,
2307 /*ata_flags*/AP_FLAG_CHK_COND,
2308 /*tag_action*/MSG_SIMPLE_Q_TAG,
2310 /*features*/ATA_HPA_FEAT_FREEZE,
2315 timeout ? timeout : 1000,
2321 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2325 ata_get_native_max(struct cam_device *device, int retry_count,
2326 u_int32_t timeout, union ccb *ccb,
2327 u_int64_t *nativesize)
2331 error = ata_do_cmd(device,
2334 /*flags*/CAM_DIR_NONE,
2335 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2336 /*ata_flags*/AP_FLAG_CHK_COND,
2337 /*tag_action*/MSG_SIMPLE_Q_TAG,
2338 /*command*/ATA_AMAX_ADDR,
2339 /*features*/ATA_AMAX_ADDR_GET,
2344 timeout ? timeout : 30 * 1000,
2350 return atahpa_proc_resp(device, ccb, /*is48bit*/1, nativesize);
2354 ataama_set(struct cam_device *device, int retry_count,
2355 u_int32_t timeout, union ccb *ccb, u_int64_t maxsize)
2359 /* lba's are zero indexed so the max lba is requested max - 1 */
2363 error = ata_do_cmd(device,
2366 /*flags*/CAM_DIR_NONE,
2367 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2368 /*ata_flags*/AP_FLAG_CHK_COND,
2369 /*tag_action*/MSG_SIMPLE_Q_TAG,
2370 /*command*/ATA_AMAX_ADDR,
2371 /*features*/ATA_AMAX_ADDR_SET,
2376 timeout ? timeout : 30 * 1000,
2382 return atahpa_proc_resp(device, ccb, /*is48bit*/1, NULL);
2386 ataama_freeze(struct cam_device *device, int retry_count,
2387 u_int32_t timeout, union ccb *ccb)
2391 error = ata_do_cmd(device,
2394 /*flags*/CAM_DIR_NONE,
2395 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
2396 /*ata_flags*/AP_FLAG_CHK_COND,
2397 /*tag_action*/MSG_SIMPLE_Q_TAG,
2398 /*command*/ATA_AMAX_ADDR,
2399 /*features*/ATA_AMAX_ADDR_FREEZE,
2404 timeout ? timeout : 30 * 1000,
2410 return atahpa_proc_resp(device, ccb, /*is48bit*/1, NULL);
2414 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2415 union ccb *ccb, struct ata_params** ident_bufp)
2417 struct ata_params *ident_buf;
2418 struct ccb_pathinq cpi;
2419 struct ccb_getdev cgd;
2422 u_int8_t command, retry_command;
2424 if (get_cpi(device, &cpi) != 0) {
2425 warnx("couldn't get CPI");
2429 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2430 if (cpi.protocol == PROTO_ATA) {
2431 if (get_cgd(device, &cgd) != 0) {
2432 warnx("couldn't get CGD");
2436 command = (cgd.protocol == PROTO_ATA) ?
2437 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2440 /* We don't know which for sure so try both */
2441 command = ATA_ATA_IDENTIFY;
2442 retry_command = ATA_ATAPI_IDENTIFY;
2445 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2447 warnx("can't calloc memory for identify\n");
2451 error = ata_do_28bit_cmd(device,
2453 /*retries*/retry_count,
2454 /*flags*/CAM_DIR_IN,
2455 /*protocol*/AP_PROTO_PIO_IN,
2456 /*tag_action*/MSG_SIMPLE_Q_TAG,
2461 /*data_ptr*/(u_int8_t *)ptr,
2462 /*dxfer_len*/sizeof(struct ata_params),
2463 /*timeout*/timeout ? timeout : 30 * 1000,
2467 if (retry_command == 0) {
2471 error = ata_do_28bit_cmd(device,
2473 /*retries*/retry_count,
2474 /*flags*/CAM_DIR_IN,
2475 /*protocol*/AP_PROTO_PIO_IN,
2476 /*tag_action*/MSG_SIMPLE_Q_TAG,
2477 /*command*/retry_command,
2481 /*data_ptr*/(u_int8_t *)ptr,
2482 /*dxfer_len*/sizeof(struct ata_params),
2483 /*timeout*/timeout ? timeout : 30 * 1000,
2492 ident_buf = (struct ata_params *)ptr;
2493 ata_param_fixup(ident_buf);
2496 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2501 if (arglist & CAM_ARG_VERBOSE) {
2502 fprintf(stdout, "%s%d: Raw identify data:\n",
2503 device->device_name, device->dev_unit_num);
2504 dump_data(ptr, sizeof(struct ata_params));
2507 /* check for invalid (all zero) response */
2509 warnx("Invalid identify response detected");
2514 *ident_bufp = ident_buf;
2521 ataidentify(struct cam_device *device, int retry_count, int timeout)
2524 struct ata_params *ident_buf;
2525 u_int64_t hpasize, nativesize;
2527 if ((ccb = cam_getccb(device)) == NULL) {
2528 warnx("couldn't allocate CCB");
2532 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2537 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2538 if (ata_read_native_max(device, retry_count, timeout, ccb,
2539 ident_buf, &hpasize) != 0) {
2546 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR) {
2547 if (ata_get_native_max(device, retry_count, timeout, ccb,
2548 &nativesize) != 0) {
2556 printf("%s%d: ", device->device_name, device->dev_unit_num);
2557 ata_print_ident(ident_buf);
2558 camxferrate(device);
2559 atacapprint(ident_buf);
2560 atahpa_print(ident_buf, hpasize, 0);
2561 ataama_print(ident_buf, nativesize, 0);
2571 nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused)
2573 struct nvme_controller_data cdata;
2575 if (nvme_get_cdata(device, &cdata))
2577 nvme_print_controller(&cdata);
2584 identify(struct cam_device *device, int retry_count, int timeout)
2587 struct ccb_pathinq cpi;
2589 if (get_cpi(device, &cpi) != 0) {
2590 warnx("couldn't get CPI");
2594 if (cpi.protocol == PROTO_NVME) {
2595 return (nvmeidentify(device, retry_count, timeout));
2598 return (ataidentify(device, retry_count, timeout));
2600 #endif /* MINIMALISTIC */
2603 #ifndef MINIMALISTIC
2605 ATA_SECURITY_ACTION_PRINT,
2606 ATA_SECURITY_ACTION_FREEZE,
2607 ATA_SECURITY_ACTION_UNLOCK,
2608 ATA_SECURITY_ACTION_DISABLE,
2609 ATA_SECURITY_ACTION_ERASE,
2610 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2611 ATA_SECURITY_ACTION_SET_PASSWORD
2615 atasecurity_print_time(u_int16_t tw)
2619 printf("unspecified");
2621 printf("> 508 min");
2623 printf("%i min", 2 * tw);
2627 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2631 return 2 * 3600 * 1000; /* default: two hours */
2632 else if (timeout > 255)
2633 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2635 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2640 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2644 bzero(&cmd, sizeof(cmd));
2645 cmd.command = command;
2646 printf("Issuing %s", ata_op_string(&cmd));
2649 char pass[sizeof(pwd->password)+1];
2651 /* pwd->password may not be null terminated */
2652 pass[sizeof(pwd->password)] = '\0';
2653 strncpy(pass, pwd->password, sizeof(pwd->password));
2654 printf(" password='%s', user='%s'",
2656 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2659 if (command == ATA_SECURITY_SET_PASSWORD) {
2660 printf(", mode='%s'",
2661 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2662 "maximum" : "high");
2670 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2671 int retry_count, u_int32_t timeout, int quiet)
2675 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2677 return ata_do_28bit_cmd(device,
2680 /*flags*/CAM_DIR_NONE,
2681 /*protocol*/AP_PROTO_NON_DATA,
2682 /*tag_action*/MSG_SIMPLE_Q_TAG,
2683 /*command*/ATA_SECURITY_FREEZE_LOCK,
2694 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2695 int retry_count, u_int32_t timeout,
2696 struct ata_security_password *pwd, int quiet)
2700 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2702 return ata_do_28bit_cmd(device,
2705 /*flags*/CAM_DIR_OUT,
2706 /*protocol*/AP_PROTO_PIO_OUT,
2707 /*tag_action*/MSG_SIMPLE_Q_TAG,
2708 /*command*/ATA_SECURITY_UNLOCK,
2712 /*data_ptr*/(u_int8_t *)pwd,
2713 /*dxfer_len*/sizeof(*pwd),
2719 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2720 int retry_count, u_int32_t timeout,
2721 struct ata_security_password *pwd, int quiet)
2725 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2726 return ata_do_28bit_cmd(device,
2729 /*flags*/CAM_DIR_OUT,
2730 /*protocol*/AP_PROTO_PIO_OUT,
2731 /*tag_action*/MSG_SIMPLE_Q_TAG,
2732 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2736 /*data_ptr*/(u_int8_t *)pwd,
2737 /*dxfer_len*/sizeof(*pwd),
2744 atasecurity_erase_confirm(struct cam_device *device,
2745 struct ata_params* ident_buf)
2748 printf("\nYou are about to ERASE ALL DATA from the following"
2749 " device:\n%s%d,%s%d: ", device->device_name,
2750 device->dev_unit_num, device->given_dev_name,
2751 device->given_unit_number);
2752 ata_print_ident(ident_buf);
2756 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2758 if (fgets(str, sizeof(str), stdin) != NULL) {
2759 if (strncasecmp(str, "yes", 3) == 0) {
2761 } else if (strncasecmp(str, "no", 2) == 0) {
2764 printf("Please answer \"yes\" or "
2775 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2776 int retry_count, u_int32_t timeout,
2777 u_int32_t erase_timeout,
2778 struct ata_security_password *pwd, int quiet)
2783 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2785 error = ata_do_28bit_cmd(device,
2788 /*flags*/CAM_DIR_NONE,
2789 /*protocol*/AP_PROTO_NON_DATA,
2790 /*tag_action*/MSG_SIMPLE_Q_TAG,
2791 /*command*/ATA_SECURITY_ERASE_PREPARE,
2804 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2806 error = ata_do_28bit_cmd(device,
2809 /*flags*/CAM_DIR_OUT,
2810 /*protocol*/AP_PROTO_PIO_OUT,
2811 /*tag_action*/MSG_SIMPLE_Q_TAG,
2812 /*command*/ATA_SECURITY_ERASE_UNIT,
2816 /*data_ptr*/(u_int8_t *)pwd,
2817 /*dxfer_len*/sizeof(*pwd),
2818 /*timeout*/erase_timeout,
2821 if (error == 0 && quiet == 0)
2822 printf("\nErase Complete\n");
2828 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2829 int retry_count, u_int32_t timeout,
2830 struct ata_security_password *pwd, int quiet)
2834 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2836 return ata_do_28bit_cmd(device,
2839 /*flags*/CAM_DIR_OUT,
2840 /*protocol*/AP_PROTO_PIO_OUT,
2841 /*tag_action*/MSG_SIMPLE_Q_TAG,
2842 /*command*/ATA_SECURITY_SET_PASSWORD,
2846 /*data_ptr*/(u_int8_t *)pwd,
2847 /*dxfer_len*/sizeof(*pwd),
2853 atasecurity_print(struct ata_params *parm)
2856 printf("\nSecurity Option Value\n");
2857 if (arglist & CAM_ARG_VERBOSE) {
2858 printf("status %04x\n",
2859 parm->security_status);
2861 printf("supported %s\n",
2862 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2863 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2865 printf("enabled %s\n",
2866 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2867 printf("drive locked %s\n",
2868 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2869 printf("security config frozen %s\n",
2870 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2871 printf("count expired %s\n",
2872 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2873 printf("security level %s\n",
2874 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2875 printf("enhanced erase supported %s\n",
2876 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2877 printf("erase time ");
2878 atasecurity_print_time(parm->erase_time);
2880 printf("enhanced erase time ");
2881 atasecurity_print_time(parm->enhanced_erase_time);
2883 printf("master password rev %04x%s\n",
2884 parm->master_passwd_revision,
2885 parm->master_passwd_revision == 0x0000 ||
2886 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2890 * Validates and copies the password in optarg to the passed buffer.
2891 * If the password in optarg is the same length as the buffer then
2892 * the data will still be copied but no null termination will occur.
2895 ata_getpwd(u_int8_t *passwd, int max, char opt)
2899 len = strlen(optarg);
2901 warnx("-%c password is too long", opt);
2903 } else if (len == 0) {
2904 warnx("-%c password is missing", opt);
2906 } else if (optarg[0] == '-'){
2907 warnx("-%c password starts with '-' (generic arg?)", opt);
2909 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2910 warnx("-%c password conflicts with existing password from -%c",
2915 /* Callers pass in a buffer which does NOT need to be terminated */
2916 strncpy(passwd, optarg, max);
2923 ATA_HPA_ACTION_PRINT,
2924 ATA_HPA_ACTION_SET_MAX,
2925 ATA_HPA_ACTION_SET_PWD,
2926 ATA_HPA_ACTION_LOCK,
2927 ATA_HPA_ACTION_UNLOCK,
2928 ATA_HPA_ACTION_FREEZE_LOCK
2932 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2933 u_int64_t maxsize, int persist)
2935 printf("\nYou are about to configure HPA to limit the user accessible\n"
2936 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2937 persist ? "persistently" : "temporarily",
2938 device->device_name, device->dev_unit_num,
2939 device->given_dev_name, device->given_unit_number);
2940 ata_print_ident(ident_buf);
2944 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2946 if (NULL != fgets(str, sizeof(str), stdin)) {
2947 if (0 == strncasecmp(str, "yes", 3)) {
2949 } else if (0 == strncasecmp(str, "no", 2)) {
2952 printf("Please answer \"yes\" or "
2963 atahpa(struct cam_device *device, int retry_count, int timeout,
2964 int argc, char **argv, char *combinedopt)
2967 struct ata_params *ident_buf;
2968 struct ccb_getdev cgd;
2969 struct ata_set_max_pwd pwd;
2970 int error, confirm, quiet, c, action, actions, persist;
2971 int security, is48bit, pwdsize;
2972 u_int64_t hpasize, maxsize;
2981 memset(&pwd, 0, sizeof(pwd));
2983 /* default action is to print hpa information */
2984 action = ATA_HPA_ACTION_PRINT;
2985 pwdsize = sizeof(pwd.password);
2987 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2990 action = ATA_HPA_ACTION_SET_MAX;
2991 maxsize = strtoumax(optarg, NULL, 0);
2996 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2998 action = ATA_HPA_ACTION_SET_PWD;
3004 action = ATA_HPA_ACTION_LOCK;
3010 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3012 action = ATA_HPA_ACTION_UNLOCK;
3018 action = ATA_HPA_ACTION_FREEZE_LOCK;
3038 warnx("too many hpa actions specified");
3042 if (get_cgd(device, &cgd) != 0) {
3043 warnx("couldn't get CGD");
3047 ccb = cam_getccb(device);
3049 warnx("couldn't allocate CCB");
3053 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3060 printf("%s%d: ", device->device_name, device->dev_unit_num);
3061 ata_print_ident(ident_buf);
3062 camxferrate(device);
3065 if (action == ATA_HPA_ACTION_PRINT) {
3066 error = ata_read_native_max(device, retry_count, timeout, ccb,
3067 ident_buf, &hpasize);
3069 atahpa_print(ident_buf, hpasize, 1);
3076 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
3077 warnx("HPA is not supported by this device");
3083 if (security && !(ident_buf->support.command2 & ATA_SUPPORT_MAXSECURITY)) {
3084 warnx("HPA Security is not supported by this device");
3090 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
3093 * The ATA spec requires:
3094 * 1. Read native max addr is called directly before set max addr
3095 * 2. Read native max addr is NOT called before any other set max call
3098 case ATA_HPA_ACTION_SET_MAX:
3100 atahpa_set_confirm(device, ident_buf, maxsize,
3107 error = ata_read_native_max(device, retry_count, timeout,
3108 ccb, ident_buf, &hpasize);
3110 error = atahpa_set_max(device, retry_count, timeout,
3111 ccb, is48bit, maxsize, persist);
3112 if (error == 0 && quiet == 0) {
3113 /* redo identify to get new lba values */
3114 error = ata_do_identify(device, retry_count,
3117 atahpa_print(ident_buf, hpasize, 1);
3122 case ATA_HPA_ACTION_SET_PWD:
3123 error = atahpa_password(device, retry_count, timeout,
3124 ccb, is48bit, &pwd);
3125 if (error == 0 && quiet == 0)
3126 printf("HPA password has been set\n");
3129 case ATA_HPA_ACTION_LOCK:
3130 error = atahpa_lock(device, retry_count, timeout,
3132 if (error == 0 && quiet == 0)
3133 printf("HPA has been locked\n");
3136 case ATA_HPA_ACTION_UNLOCK:
3137 error = atahpa_unlock(device, retry_count, timeout,
3138 ccb, is48bit, &pwd);
3139 if (error == 0 && quiet == 0)
3140 printf("HPA has been unlocked\n");
3143 case ATA_HPA_ACTION_FREEZE_LOCK:
3144 error = atahpa_freeze_lock(device, retry_count, timeout,
3146 if (error == 0 && quiet == 0)
3147 printf("HPA has been frozen\n");
3151 errx(1, "Option currently not supported");
3161 ATA_AMA_ACTION_PRINT,
3162 ATA_AMA_ACTION_SET_MAX,
3163 ATA_AMA_ACTION_FREEZE_LOCK
3167 ataama(struct cam_device *device, int retry_count, int timeout,
3168 int argc, char **argv, char *combinedopt)
3171 struct ata_params *ident_buf;
3172 struct ccb_getdev cgd;
3173 int error, quiet, c, action, actions;
3174 u_int64_t nativesize, maxsize;
3180 /* default action is to print AMA information */
3181 action = ATA_AMA_ACTION_PRINT;
3183 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3186 action = ATA_AMA_ACTION_SET_MAX;
3187 maxsize = strtoumax(optarg, NULL, 0);
3192 action = ATA_AMA_ACTION_FREEZE_LOCK;
3203 warnx("too many AMA actions specified");
3207 if (get_cgd(device, &cgd) != 0) {
3208 warnx("couldn't get CGD");
3212 ccb = cam_getccb(device);
3214 warnx("couldn't allocate CCB");
3218 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3225 printf("%s%d: ", device->device_name, device->dev_unit_num);
3226 ata_print_ident(ident_buf);
3227 camxferrate(device);
3230 if (action == ATA_AMA_ACTION_PRINT) {
3231 error = ata_get_native_max(device, retry_count, timeout, ccb,
3234 ataama_print(ident_buf, nativesize, 1);
3241 if (!(ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)) {
3242 warnx("Accessible Max Address is not supported by this device");
3249 case ATA_AMA_ACTION_SET_MAX:
3250 error = ata_get_native_max(device, retry_count, timeout, ccb,
3253 error = ataama_set(device, retry_count, timeout,
3255 if (error == 0 && quiet == 0) {
3256 /* redo identify to get new lba values */
3257 error = ata_do_identify(device, retry_count,
3258 timeout, ccb, &ident_buf);
3259 ataama_print(ident_buf, nativesize, 1);
3264 case ATA_AMA_ACTION_FREEZE_LOCK:
3265 error = ataama_freeze(device, retry_count, timeout,
3267 if (error == 0 && quiet == 0)
3268 printf("Accessible Max Address has been frozen\n");
3272 errx(1, "Option currently not supported");
3282 atasecurity(struct cam_device *device, int retry_count, int timeout,
3283 int argc, char **argv, char *combinedopt)
3286 struct ata_params *ident_buf;
3287 int error, confirm, quiet, c, action, actions, setpwd;
3288 int security_enabled, erase_timeout, pwdsize;
3289 struct ata_security_password pwd;
3297 memset(&pwd, 0, sizeof(pwd));
3299 /* default action is to print security information */
3300 action = ATA_SECURITY_ACTION_PRINT;
3302 /* user is master by default as its safer that way */
3303 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3304 pwdsize = sizeof(pwd.password);
3306 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3309 action = ATA_SECURITY_ACTION_FREEZE;
3314 if (strcasecmp(optarg, "user") == 0) {
3315 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
3316 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
3317 } else if (strcasecmp(optarg, "master") == 0) {
3318 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3319 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
3321 warnx("-U argument '%s' is invalid (must be "
3322 "'user' or 'master')", optarg);
3328 if (strcasecmp(optarg, "high") == 0) {
3329 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3330 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3331 } else if (strcasecmp(optarg, "maximum") == 0) {
3332 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3333 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3335 warnx("-l argument '%s' is unknown (must be "
3336 "'high' or 'maximum')", optarg);
3342 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3344 action = ATA_SECURITY_ACTION_UNLOCK;
3349 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3351 action = ATA_SECURITY_ACTION_DISABLE;
3356 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3358 action = ATA_SECURITY_ACTION_ERASE;
3363 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3365 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3366 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3371 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3374 if (action == ATA_SECURITY_ACTION_PRINT)
3375 action = ATA_SECURITY_ACTION_SET_PASSWORD;
3377 * Don't increment action as this can be combined
3378 * with other actions.
3391 erase_timeout = atoi(optarg) * 1000;
3397 warnx("too many security actions specified");
3401 if ((ccb = cam_getccb(device)) == NULL) {
3402 warnx("couldn't allocate CCB");
3406 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3413 printf("%s%d: ", device->device_name, device->dev_unit_num);
3414 ata_print_ident(ident_buf);
3415 camxferrate(device);
3418 if (action == ATA_SECURITY_ACTION_PRINT) {
3419 atasecurity_print(ident_buf);
3425 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3426 warnx("Security not supported");
3432 /* default timeout 15 seconds the same as linux hdparm */
3433 timeout = timeout ? timeout : 15 * 1000;
3435 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3437 /* first set the password if requested */
3439 /* confirm we can erase before setting the password if erasing */
3441 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3442 action == ATA_SECURITY_ACTION_ERASE) &&
3443 atasecurity_erase_confirm(device, ident_buf) == 0) {
3449 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3450 pwd.revision = ident_buf->master_passwd_revision;
3451 if (pwd.revision != 0 && pwd.revision != 0xfff &&
3452 --pwd.revision == 0) {
3453 pwd.revision = 0xfffe;
3456 error = atasecurity_set_password(device, ccb, retry_count,
3457 timeout, &pwd, quiet);
3463 security_enabled = 1;
3467 case ATA_SECURITY_ACTION_FREEZE:
3468 error = atasecurity_freeze(device, ccb, retry_count,
3472 case ATA_SECURITY_ACTION_UNLOCK:
3473 if (security_enabled) {
3474 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3475 error = atasecurity_unlock(device, ccb,
3476 retry_count, timeout, &pwd, quiet);
3478 warnx("Can't unlock, drive is not locked");
3482 warnx("Can't unlock, security is disabled");
3487 case ATA_SECURITY_ACTION_DISABLE:
3488 if (security_enabled) {
3489 /* First unlock the drive if its locked */
3490 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3491 error = atasecurity_unlock(device, ccb,
3499 error = atasecurity_disable(device,
3507 warnx("Can't disable security (already disabled)");
3512 case ATA_SECURITY_ACTION_ERASE:
3513 if (security_enabled) {
3514 if (erase_timeout == 0) {
3515 erase_timeout = atasecurity_erase_timeout_msecs(
3516 ident_buf->erase_time);
3519 error = atasecurity_erase(device, ccb, retry_count,
3520 timeout, erase_timeout, &pwd, quiet);
3522 warnx("Can't secure erase (security is disabled)");
3527 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3528 if (security_enabled) {
3529 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3530 if (erase_timeout == 0) {
3532 atasecurity_erase_timeout_msecs(
3533 ident_buf->enhanced_erase_time);
3536 error = atasecurity_erase(device, ccb,
3537 retry_count, timeout,
3538 erase_timeout, &pwd,
3541 warnx("Enhanced erase is not supported");
3545 warnx("Can't secure erase (enhanced), "
3546 "(security is disabled)");
3557 #endif /* MINIMALISTIC */
3560 * Parse out a bus, or a bus, target and lun in the following
3566 * Returns the number of parsed components, or 0.
3569 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3570 cam_argmask *arglst)
3575 while (isspace(*tstr) && (*tstr != '\0'))
3578 tmpstr = (char *)strtok(tstr, ":");
3579 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3580 *bus = strtol(tmpstr, NULL, 0);
3581 *arglst |= CAM_ARG_BUS;
3583 tmpstr = (char *)strtok(NULL, ":");
3584 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3585 *target = strtol(tmpstr, NULL, 0);
3586 *arglst |= CAM_ARG_TARGET;
3588 tmpstr = (char *)strtok(NULL, ":");
3589 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3590 *lun = strtol(tmpstr, NULL, 0);
3591 *arglst |= CAM_ARG_LUN;
3601 dorescan_or_reset(int argc, char **argv, int rescan)
3603 static const char must[] =
3604 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3606 path_id_t bus = CAM_BUS_WILDCARD;
3607 target_id_t target = CAM_TARGET_WILDCARD;
3608 lun_id_t lun = CAM_LUN_WILDCARD;
3612 warnx(must, rescan? "rescan" : "reset");
3616 tstr = argv[optind];
3617 while (isspace(*tstr) && (*tstr != '\0'))
3619 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3620 arglist |= CAM_ARG_BUS;
3621 else if (isdigit(*tstr)) {
3622 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3623 if (rv != 1 && rv != 3) {
3624 warnx(must, rescan? "rescan" : "reset");
3634 * Note that resetting or rescanning a device used to
3635 * require a bus or bus:target:lun. This is because the
3636 * device in question may not exist and you're trying to
3637 * get the controller to rescan to find it. It may also be
3638 * because the device is hung / unresponsive, and opening
3639 * an unresponsive device is not desireable.
3641 * It can be more convenient to reference a device by
3642 * peripheral name and unit number, though, and it is
3643 * possible to get the bus:target:lun for devices that
3644 * currently exist in the EDT. So this can work for
3645 * devices that we want to reset, or devices that exist
3646 * that we want to rescan, but not devices that do not
3649 * So, we are careful here to look up the bus/target/lun
3650 * for the device the user wants to operate on, specified
3651 * by peripheral instance (e.g. da0, pass32) without
3652 * actually opening that device. The process is similar to
3653 * what cam_lookup_pass() does, except that we don't
3654 * actually open the passthrough driver instance in the end.
3657 if (cam_get_device(tstr, name, sizeof(name), &unit) == -1) {
3658 warnx("%s", cam_errbuf);
3663 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3664 warn("Unable to open %s", XPT_DEVICE);
3669 bzero(&ccb, sizeof(ccb));
3672 * The function code isn't strictly necessary for the
3673 * GETPASSTHRU ioctl.
3675 ccb.ccb_h.func_code = XPT_GDEVLIST;
3678 * These two are necessary for the GETPASSTHRU ioctl to
3681 strlcpy(ccb.cgdl.periph_name, name,
3682 sizeof(ccb.cgdl.periph_name));
3683 ccb.cgdl.unit_number = unit;
3686 * Attempt to get the passthrough device. This ioctl will
3687 * fail if the device name is null, if the device doesn't
3688 * exist, or if the passthrough driver isn't in the kernel.
3690 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3691 warn("Unable to find bus:target:lun for device %s%d",
3697 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3698 const struct cam_status_entry *entry;
3700 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3701 warnx("Unable to find bus:target_lun for device %s%d, "
3702 "CAM status: %s (%#x)", name, unit,
3703 entry ? entry->status_text : "Unknown",
3711 * The kernel fills in the bus/target/lun. We don't
3712 * need the passthrough device name and unit number since
3713 * we aren't going to open it.
3715 bus = ccb.ccb_h.path_id;
3716 target = ccb.ccb_h.target_id;
3717 lun = ccb.ccb_h.target_lun;
3719 arglist |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3724 if ((arglist & CAM_ARG_BUS)
3725 && (arglist & CAM_ARG_TARGET)
3726 && (arglist & CAM_ARG_LUN))
3727 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3729 error = rescan_or_reset_bus(bus, rescan);
3737 rescan_or_reset_bus(path_id_t bus, int rescan)
3739 union ccb *ccb = NULL, *matchccb = NULL;
3740 int fd = -1, retval;
3745 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3746 warnx("error opening transport layer device %s", XPT_DEVICE);
3747 warn("%s", XPT_DEVICE);
3751 ccb = malloc(sizeof(*ccb));
3753 warn("failed to allocate CCB");
3757 bzero(ccb, sizeof(*ccb));
3759 if (bus != CAM_BUS_WILDCARD) {
3760 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3761 ccb->ccb_h.path_id = bus;
3762 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3763 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3764 ccb->crcn.flags = CAM_FLAG_NONE;
3766 /* run this at a low priority */
3767 ccb->ccb_h.pinfo.priority = 5;
3769 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3770 warn("CAMIOCOMMAND ioctl failed");
3775 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3776 fprintf(stdout, "%s of bus %d was successful\n",
3777 rescan ? "Re-scan" : "Reset", bus);
3779 fprintf(stdout, "%s of bus %d returned error %#x\n",
3780 rescan ? "Re-scan" : "Reset", bus,
3781 ccb->ccb_h.status & CAM_STATUS_MASK);
3790 * The right way to handle this is to modify the xpt so that it can
3791 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3792 * that isn't implemented, so instead we enumerate the buses and
3793 * send the rescan or reset to those buses in the case where the
3794 * given bus is -1 (wildcard). We don't send a rescan or reset
3795 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3796 * no-op, sending a rescan to the xpt bus would result in a status of
3799 matchccb = malloc(sizeof(*matchccb));
3800 if (matchccb == NULL) {
3801 warn("failed to allocate CCB");
3805 bzero(matchccb, sizeof(*matchccb));
3806 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3807 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3808 bufsize = sizeof(struct dev_match_result) * 20;
3809 matchccb->cdm.match_buf_len = bufsize;
3810 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3811 if (matchccb->cdm.matches == NULL) {
3812 warnx("can't malloc memory for matches");
3816 matchccb->cdm.num_matches = 0;
3818 matchccb->cdm.num_patterns = 1;
3819 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3821 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3822 matchccb->cdm.pattern_buf_len);
3823 if (matchccb->cdm.patterns == NULL) {
3824 warnx("can't malloc memory for patterns");
3828 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3829 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3834 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3835 warn("CAMIOCOMMAND ioctl failed");
3840 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3841 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3842 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3843 warnx("got CAM error %#x, CDM error %d\n",
3844 matchccb->ccb_h.status, matchccb->cdm.status);
3849 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3850 struct bus_match_result *bus_result;
3852 /* This shouldn't happen. */
3853 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3856 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3859 * We don't want to rescan or reset the xpt bus.
3862 if (bus_result->path_id == CAM_XPT_PATH_ID)
3865 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3867 ccb->ccb_h.path_id = bus_result->path_id;
3868 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3869 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3870 ccb->crcn.flags = CAM_FLAG_NONE;
3872 /* run this at a low priority */
3873 ccb->ccb_h.pinfo.priority = 5;
3875 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3876 warn("CAMIOCOMMAND ioctl failed");
3881 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3882 fprintf(stdout, "%s of bus %d was successful\n",
3883 rescan? "Re-scan" : "Reset",
3884 bus_result->path_id);
3887 * Don't bail out just yet, maybe the other
3888 * rescan or reset commands will complete
3891 fprintf(stderr, "%s of bus %d returned error "
3892 "%#x\n", rescan? "Re-scan" : "Reset",
3893 bus_result->path_id,
3894 ccb->ccb_h.status & CAM_STATUS_MASK);
3898 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3899 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3906 if (matchccb != NULL) {
3907 free(matchccb->cdm.patterns);
3908 free(matchccb->cdm.matches);
3917 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3920 struct cam_device *device;
3925 if (bus == CAM_BUS_WILDCARD) {
3926 warnx("invalid bus number %d", bus);
3930 if (target == CAM_TARGET_WILDCARD) {
3931 warnx("invalid target number %d", target);
3935 if (lun == CAM_LUN_WILDCARD) {
3936 warnx("invalid lun number %jx", (uintmax_t)lun);
3942 bzero(&ccb, sizeof(union ccb));
3945 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3946 warnx("error opening transport layer device %s\n",
3948 warn("%s", XPT_DEVICE);
3952 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3953 if (device == NULL) {
3954 warnx("%s", cam_errbuf);
3959 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3960 ccb.ccb_h.path_id = bus;
3961 ccb.ccb_h.target_id = target;
3962 ccb.ccb_h.target_lun = lun;
3963 ccb.ccb_h.timeout = 5000;
3964 ccb.crcn.flags = CAM_FLAG_NONE;
3966 /* run this at a low priority */
3967 ccb.ccb_h.pinfo.priority = 5;
3970 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3971 warn("CAMIOCOMMAND ioctl failed");
3976 if (cam_send_ccb(device, &ccb) < 0) {
3977 warn("error sending XPT_RESET_DEV CCB");
3978 cam_close_device(device);
3986 cam_close_device(device);
3989 * An error code of CAM_BDR_SENT is normal for a BDR request.
3991 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3993 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3994 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3995 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3998 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3999 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
4000 ccb.ccb_h.status & CAM_STATUS_MASK);
4005 #ifndef MINIMALISTIC
4007 static struct scsi_nv defect_list_type_map[] = {
4008 { "block", SRDD10_BLOCK_FORMAT },
4009 { "extbfi", SRDD10_EXT_BFI_FORMAT },
4010 { "extphys", SRDD10_EXT_PHYS_FORMAT },
4011 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
4012 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
4013 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
4017 readdefects(struct cam_device *device, int argc, char **argv,
4018 char *combinedopt, int task_attr, int retry_count, int timeout)
4020 union ccb *ccb = NULL;
4021 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
4022 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
4023 size_t hdr_size = 0, entry_size = 0;
4026 u_int8_t *defect_list = NULL;
4027 u_int8_t list_format = 0;
4028 int list_type_set = 0;
4029 u_int32_t dlist_length = 0;
4030 u_int32_t returned_length = 0, valid_len = 0;
4031 u_int32_t num_returned = 0, num_valid = 0;
4032 u_int32_t max_possible_size = 0, hdr_max = 0;
4033 u_int32_t starting_offset = 0;
4034 u_int8_t returned_format, returned_type;
4036 int summary = 0, quiet = 0;
4038 int lists_specified = 0;
4039 int get_length = 1, first_pass = 1;
4042 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4046 scsi_nv_status status;
4049 status = scsi_get_nv(defect_list_type_map,
4050 sizeof(defect_list_type_map) /
4051 sizeof(defect_list_type_map[0]), optarg,
4052 &entry_num, SCSI_NV_FLAG_IG_CASE);
4054 if (status == SCSI_NV_FOUND) {
4055 list_format = defect_list_type_map[
4059 warnx("%s: %s %s option %s", __func__,
4060 (status == SCSI_NV_AMBIGUOUS) ?
4061 "ambiguous" : "invalid", "defect list type",
4064 goto defect_bailout;
4069 arglist |= CAM_ARG_GLIST;
4072 arglist |= CAM_ARG_PLIST;
4083 starting_offset = strtoul(optarg, &endptr, 0);
4084 if (*endptr != '\0') {
4086 warnx("invalid starting offset %s", optarg);
4087 goto defect_bailout;
4099 if (list_type_set == 0) {
4101 warnx("no defect list format specified");
4102 goto defect_bailout;
4105 if (arglist & CAM_ARG_PLIST) {
4106 list_format |= SRDD10_PLIST;
4110 if (arglist & CAM_ARG_GLIST) {
4111 list_format |= SRDD10_GLIST;
4116 * This implies a summary, and was the previous behavior.
4118 if (lists_specified == 0)
4121 ccb = cam_getccb(device);
4126 * We start off asking for just the header to determine how much
4127 * defect data is available. Some Hitachi drives return an error
4128 * if you ask for more data than the drive has. Once we know the
4129 * length, we retry the command with the returned length.
4131 if (use_12byte == 0)
4132 dlist_length = sizeof(*hdr10);
4134 dlist_length = sizeof(*hdr12);
4137 if (defect_list != NULL) {
4141 defect_list = malloc(dlist_length);
4142 if (defect_list == NULL) {
4143 warnx("can't malloc memory for defect list");
4145 goto defect_bailout;
4149 bzero(defect_list, dlist_length);
4152 * cam_getccb() zeros the CCB header only. So we need to zero the
4153 * payload portion of the ccb.
4155 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4157 scsi_read_defects(&ccb->csio,
4158 /*retries*/ retry_count,
4160 /*tag_action*/ task_attr,
4161 /*list_format*/ list_format,
4162 /*addr_desc_index*/ starting_offset,
4163 /*data_ptr*/ defect_list,
4164 /*dxfer_len*/ dlist_length,
4165 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
4166 /*sense_len*/ SSD_FULL_SIZE,
4167 /*timeout*/ timeout ? timeout : 5000);
4169 /* Disable freezing the device queue */
4170 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4172 if (cam_send_ccb(device, ccb) < 0) {
4173 perror("error reading defect list");
4175 if (arglist & CAM_ARG_VERBOSE) {
4176 cam_error_print(device, ccb, CAM_ESF_ALL,
4177 CAM_EPF_ALL, stderr);
4181 goto defect_bailout;
4184 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
4186 if (use_12byte == 0) {
4187 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
4188 hdr_size = sizeof(*hdr10);
4189 hdr_max = SRDDH10_MAX_LENGTH;
4191 if (valid_len >= hdr_size) {
4192 returned_length = scsi_2btoul(hdr10->length);
4193 returned_format = hdr10->format;
4195 returned_length = 0;
4196 returned_format = 0;
4199 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
4200 hdr_size = sizeof(*hdr12);
4201 hdr_max = SRDDH12_MAX_LENGTH;
4203 if (valid_len >= hdr_size) {
4204 returned_length = scsi_4btoul(hdr12->length);
4205 returned_format = hdr12->format;
4207 returned_length = 0;
4208 returned_format = 0;
4212 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
4213 switch (returned_type) {
4214 case SRDD10_BLOCK_FORMAT:
4215 entry_size = sizeof(struct scsi_defect_desc_block);
4217 case SRDD10_LONG_BLOCK_FORMAT:
4218 entry_size = sizeof(struct scsi_defect_desc_long_block);
4220 case SRDD10_EXT_PHYS_FORMAT:
4221 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4222 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
4224 case SRDD10_EXT_BFI_FORMAT:
4225 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4226 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
4229 warnx("Unknown defect format 0x%x\n", returned_type);
4231 goto defect_bailout;
4235 max_possible_size = (hdr_max / entry_size) * entry_size;
4236 num_returned = returned_length / entry_size;
4237 num_valid = min(returned_length, valid_len - hdr_size);
4238 num_valid /= entry_size;
4240 if (get_length != 0) {
4243 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
4244 CAM_SCSI_STATUS_ERROR) {
4245 struct scsi_sense_data *sense;
4246 int error_code, sense_key, asc, ascq;
4248 sense = &ccb->csio.sense_data;
4249 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4250 ccb->csio.sense_resid, &error_code, &sense_key,
4251 &asc, &ascq, /*show_errors*/ 1);
4254 * If the drive is reporting that it just doesn't
4255 * support the defect list format, go ahead and use
4256 * the length it reported. Otherwise, the length
4257 * may not be valid, so use the maximum.
4259 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4260 && (asc == 0x1c) && (ascq == 0x00)
4261 && (returned_length > 0)) {
4262 if ((use_12byte == 0)
4263 && (returned_length >= max_possible_size)) {
4268 dlist_length = returned_length + hdr_size;
4269 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4270 && (asc == 0x1f) && (ascq == 0x00)
4271 && (returned_length > 0)) {
4272 /* Partial defect list transfer */
4274 * Hitachi drives return this error
4275 * along with a partial defect list if they
4276 * have more defects than the 10 byte
4277 * command can support. Retry with the 12
4280 if (use_12byte == 0) {
4285 dlist_length = returned_length + hdr_size;
4286 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
4287 && (asc == 0x24) && (ascq == 0x00)) {
4288 /* Invalid field in CDB */
4290 * SBC-3 says that if the drive has more
4291 * defects than can be reported with the
4292 * 10 byte command, it should return this
4293 * error and no data. Retry with the 12
4296 if (use_12byte == 0) {
4301 dlist_length = returned_length + hdr_size;
4304 * If we got a SCSI error and no valid length,
4305 * just use the 10 byte maximum. The 12
4306 * byte maximum is too large.
4308 if (returned_length == 0)
4309 dlist_length = SRDD10_MAX_LENGTH;
4311 if ((use_12byte == 0)
4312 && (returned_length >=
4313 max_possible_size)) {
4318 dlist_length = returned_length +
4322 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4325 warnx("Error reading defect header");
4326 if (arglist & CAM_ARG_VERBOSE)
4327 cam_error_print(device, ccb, CAM_ESF_ALL,
4328 CAM_EPF_ALL, stderr);
4329 goto defect_bailout;
4331 if ((use_12byte == 0)
4332 && (returned_length >= max_possible_size)) {
4337 dlist_length = returned_length + hdr_size;
4340 fprintf(stdout, "%u", num_returned);
4342 fprintf(stdout, " defect%s",
4343 (num_returned != 1) ? "s" : "");
4345 fprintf(stdout, "\n");
4347 goto defect_bailout;
4351 * We always limit the list length to the 10-byte maximum
4352 * length (0xffff). The reason is that some controllers
4353 * can't handle larger I/Os, and we can transfer the entire
4354 * 10 byte list in one shot. For drives that support the 12
4355 * byte read defects command, we'll step through the list
4356 * by specifying a starting offset. For drives that don't
4357 * support the 12 byte command's starting offset, we'll
4358 * just display the first 64K.
4360 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4366 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4367 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4368 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4369 struct scsi_sense_data *sense;
4370 int error_code, sense_key, asc, ascq;
4372 sense = &ccb->csio.sense_data;
4373 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4374 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4375 &ascq, /*show_errors*/ 1);
4378 * According to the SCSI spec, if the disk doesn't support
4379 * the requested format, it will generally return a sense
4380 * key of RECOVERED ERROR, and an additional sense code
4381 * of "DEFECT LIST NOT FOUND". HGST drives also return
4382 * Primary/Grown defect list not found errors. So just
4383 * check for an ASC of 0x1c.
4385 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4387 const char *format_str;
4389 format_str = scsi_nv_to_str(defect_list_type_map,
4390 sizeof(defect_list_type_map) /
4391 sizeof(defect_list_type_map[0]),
4392 list_format & SRDD10_DLIST_FORMAT_MASK);
4393 warnx("requested defect format %s not available",
4394 format_str ? format_str : "unknown");
4396 format_str = scsi_nv_to_str(defect_list_type_map,
4397 sizeof(defect_list_type_map) /
4398 sizeof(defect_list_type_map[0]), returned_type);
4399 if (format_str != NULL) {
4400 warnx("Device returned %s format",
4404 warnx("Device returned unknown defect"
4405 " data format %#x", returned_type);
4406 goto defect_bailout;
4410 warnx("Error returned from read defect data command");
4411 if (arglist & CAM_ARG_VERBOSE)
4412 cam_error_print(device, ccb, CAM_ESF_ALL,
4413 CAM_EPF_ALL, stderr);
4414 goto defect_bailout;
4416 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4418 warnx("Error returned from read defect data command");
4419 if (arglist & CAM_ARG_VERBOSE)
4420 cam_error_print(device, ccb, CAM_ESF_ALL,
4421 CAM_EPF_ALL, stderr);
4422 goto defect_bailout;
4425 if (first_pass != 0) {
4426 fprintf(stderr, "Got %d defect", num_returned);
4428 if ((lists_specified == 0) || (num_returned == 0)) {
4429 fprintf(stderr, "s.\n");
4430 goto defect_bailout;
4431 } else if (num_returned == 1)
4432 fprintf(stderr, ":\n");
4434 fprintf(stderr, "s:\n");
4440 * XXX KDM I should probably clean up the printout format for the
4443 switch (returned_type) {
4444 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4445 case SRDD10_EXT_PHYS_FORMAT:
4447 struct scsi_defect_desc_phys_sector *dlist;
4449 dlist = (struct scsi_defect_desc_phys_sector *)
4450 (defect_list + hdr_size);
4452 for (i = 0; i < num_valid; i++) {
4455 sector = scsi_4btoul(dlist[i].sector);
4456 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4457 mads = (sector & SDD_EXT_PHYS_MADS) ?
4459 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4461 if (hex_format == 0)
4462 fprintf(stdout, "%d:%d:%d%s",
4463 scsi_3btoul(dlist[i].cylinder),
4465 scsi_4btoul(dlist[i].sector),
4466 mads ? " - " : "\n");
4468 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4469 scsi_3btoul(dlist[i].cylinder),
4471 scsi_4btoul(dlist[i].sector),
4472 mads ? " - " : "\n");
4475 if (num_valid < num_returned) {
4476 starting_offset += num_valid;
4481 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4482 case SRDD10_EXT_BFI_FORMAT:
4484 struct scsi_defect_desc_bytes_from_index *dlist;
4486 dlist = (struct scsi_defect_desc_bytes_from_index *)
4487 (defect_list + hdr_size);
4489 for (i = 0; i < num_valid; i++) {
4492 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4493 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4494 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4495 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4497 if (hex_format == 0)
4498 fprintf(stdout, "%d:%d:%d%s",
4499 scsi_3btoul(dlist[i].cylinder),
4501 scsi_4btoul(dlist[i].bytes_from_index),
4502 mads ? " - " : "\n");
4504 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4505 scsi_3btoul(dlist[i].cylinder),
4507 scsi_4btoul(dlist[i].bytes_from_index),
4508 mads ? " - " : "\n");
4512 if (num_valid < num_returned) {
4513 starting_offset += num_valid;
4518 case SRDDH10_BLOCK_FORMAT:
4520 struct scsi_defect_desc_block *dlist;
4522 dlist = (struct scsi_defect_desc_block *)
4523 (defect_list + hdr_size);
4525 for (i = 0; i < num_valid; i++) {
4526 if (hex_format == 0)
4527 fprintf(stdout, "%u\n",
4528 scsi_4btoul(dlist[i].address));
4530 fprintf(stdout, "0x%x\n",
4531 scsi_4btoul(dlist[i].address));
4534 if (num_valid < num_returned) {
4535 starting_offset += num_valid;
4541 case SRDD10_LONG_BLOCK_FORMAT:
4543 struct scsi_defect_desc_long_block *dlist;
4545 dlist = (struct scsi_defect_desc_long_block *)
4546 (defect_list + hdr_size);
4548 for (i = 0; i < num_valid; i++) {
4549 if (hex_format == 0)
4550 fprintf(stdout, "%ju\n",
4551 (uintmax_t)scsi_8btou64(
4554 fprintf(stdout, "0x%jx\n",
4555 (uintmax_t)scsi_8btou64(
4559 if (num_valid < num_returned) {
4560 starting_offset += num_valid;
4566 fprintf(stderr, "Unknown defect format 0x%x\n",
4573 if (defect_list != NULL)
4581 #endif /* MINIMALISTIC */
4585 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4589 ccb = cam_getccb(device);
4595 #ifndef MINIMALISTIC
4597 mode_sense(struct cam_device *device, int dbd, int pc, int page, int subpage,
4598 int task_attr, int retry_count, int timeout, u_int8_t *data,
4604 ccb = cam_getccb(device);
4607 errx(1, "mode_sense: couldn't allocate CCB");
4609 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4611 scsi_mode_sense_subpage(&ccb->csio,
4612 /* retries */ retry_count,
4614 /* tag_action */ task_attr,
4618 /* subpage */ subpage,
4619 /* param_buf */ data,
4620 /* param_len */ datalen,
4621 /* minimum_cmd_size */ 0,
4622 /* sense_len */ SSD_FULL_SIZE,
4623 /* timeout */ timeout ? timeout : 5000);
4625 if (arglist & CAM_ARG_ERR_RECOVER)
4626 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4628 /* Disable freezing the device queue */
4629 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4631 if (((retval = cam_send_ccb(device, ccb)) < 0)
4632 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4633 if (arglist & CAM_ARG_VERBOSE) {
4634 cam_error_print(device, ccb, CAM_ESF_ALL,
4635 CAM_EPF_ALL, stderr);
4638 cam_close_device(device);
4640 err(1, "error sending mode sense command");
4642 errx(1, "error sending mode sense command");
4649 mode_select(struct cam_device *device, int save_pages, int task_attr,
4650 int retry_count, int timeout, u_int8_t *data, int datalen)
4655 ccb = cam_getccb(device);
4658 errx(1, "mode_select: couldn't allocate CCB");
4660 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4662 scsi_mode_select(&ccb->csio,
4663 /* retries */ retry_count,
4665 /* tag_action */ task_attr,
4666 /* scsi_page_fmt */ 1,
4667 /* save_pages */ save_pages,
4668 /* param_buf */ data,
4669 /* param_len */ datalen,
4670 /* sense_len */ SSD_FULL_SIZE,
4671 /* timeout */ timeout ? timeout : 5000);
4673 if (arglist & CAM_ARG_ERR_RECOVER)
4674 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4676 /* Disable freezing the device queue */
4677 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4679 if (((retval = cam_send_ccb(device, ccb)) < 0)
4680 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4681 if (arglist & CAM_ARG_VERBOSE) {
4682 cam_error_print(device, ccb, CAM_ESF_ALL,
4683 CAM_EPF_ALL, stderr);
4686 cam_close_device(device);
4689 err(1, "error sending mode select command");
4691 errx(1, "error sending mode select command");
4699 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4700 int task_attr, int retry_count, int timeout)
4703 int c, page = -1, subpage = -1, pc = 0;
4704 int binary = 0, dbd = 0, edit = 0, list = 0;
4706 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4721 str_subpage = optarg;
4722 strsep(&str_subpage, ",");
4723 page = strtol(optarg, NULL, 0);
4725 subpage = strtol(str_subpage, NULL, 0);
4729 errx(1, "invalid mode page %d", page);
4731 errx(1, "invalid mode subpage %d", subpage);
4734 pc = strtol(optarg, NULL, 0);
4735 if ((pc < 0) || (pc > 3))
4736 errx(1, "invalid page control field %d", pc);
4743 if (page == -1 && list == 0)
4744 errx(1, "you must specify a mode page!");
4747 mode_list(device, dbd, pc, list > 1, task_attr, retry_count,
4750 mode_edit(device, dbd, pc, page, subpage, edit, binary,
4751 task_attr, retry_count, timeout);
4756 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4757 int task_attr, int retry_count, int timeout)
4760 u_int32_t flags = CAM_DIR_NONE;
4761 u_int8_t *data_ptr = NULL;
4763 u_int8_t atacmd[12];
4764 struct get_hook hook;
4765 int c, data_bytes = 0, valid_bytes;
4771 char *datastr = NULL, *tstr, *resstr = NULL;
4773 int fd_data = 0, fd_res = 0;
4776 ccb = cam_getccb(device);
4779 warnx("scsicmd: error allocating ccb");
4783 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4785 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4789 while (isspace(*tstr) && (*tstr != '\0'))
4791 hook.argc = argc - optind;
4792 hook.argv = argv + optind;
4794 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4797 * Increment optind by the number of arguments the
4798 * encoding routine processed. After each call to
4799 * getopt(3), optind points to the argument that
4800 * getopt should process _next_. In this case,
4801 * that means it points to the first command string
4802 * argument, if there is one. Once we increment
4803 * this, it should point to either the next command
4804 * line argument, or it should be past the end of
4811 while (isspace(*tstr) && (*tstr != '\0'))
4813 hook.argc = argc - optind;
4814 hook.argv = argv + optind;
4816 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4819 * Increment optind by the number of arguments the
4820 * encoding routine processed. After each call to
4821 * getopt(3), optind points to the argument that
4822 * getopt should process _next_. In this case,
4823 * that means it points to the first command string
4824 * argument, if there is one. Once we increment
4825 * this, it should point to either the next command
4826 * line argument, or it should be past the end of
4838 if (arglist & CAM_ARG_CMD_OUT) {
4839 warnx("command must either be "
4840 "read or write, not both");
4842 goto scsicmd_bailout;
4844 arglist |= CAM_ARG_CMD_IN;
4846 data_bytes = strtol(optarg, NULL, 0);
4847 if (data_bytes <= 0) {
4848 warnx("invalid number of input bytes %d",
4851 goto scsicmd_bailout;
4853 hook.argc = argc - optind;
4854 hook.argv = argv + optind;
4857 datastr = cget(&hook, NULL);
4859 * If the user supplied "-" instead of a format, he
4860 * wants the data to be written to stdout.
4862 if ((datastr != NULL)
4863 && (datastr[0] == '-'))
4866 data_ptr = (u_int8_t *)malloc(data_bytes);
4867 if (data_ptr == NULL) {
4868 warnx("can't malloc memory for data_ptr");
4870 goto scsicmd_bailout;
4874 if (arglist & CAM_ARG_CMD_IN) {
4875 warnx("command must either be "
4876 "read or write, not both");
4878 goto scsicmd_bailout;
4880 arglist |= CAM_ARG_CMD_OUT;
4881 flags = CAM_DIR_OUT;
4882 data_bytes = strtol(optarg, NULL, 0);
4883 if (data_bytes <= 0) {
4884 warnx("invalid number of output bytes %d",
4887 goto scsicmd_bailout;
4889 hook.argc = argc - optind;
4890 hook.argv = argv + optind;
4892 datastr = cget(&hook, NULL);
4893 data_ptr = (u_int8_t *)malloc(data_bytes);
4894 if (data_ptr == NULL) {
4895 warnx("can't malloc memory for data_ptr");
4897 goto scsicmd_bailout;
4899 bzero(data_ptr, data_bytes);
4901 * If the user supplied "-" instead of a format, he
4902 * wants the data to be read from stdin.
4904 if ((datastr != NULL)
4905 && (datastr[0] == '-'))
4908 buff_encode_visit(data_ptr, data_bytes, datastr,
4914 hook.argc = argc - optind;
4915 hook.argv = argv + optind;
4917 resstr = cget(&hook, NULL);
4918 if ((resstr != NULL) && (resstr[0] == '-'))
4928 * If fd_data is set, and we're writing to the device, we need to
4929 * read the data the user wants written from stdin.
4931 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4933 int amt_to_read = data_bytes;
4934 u_int8_t *buf_ptr = data_ptr;
4936 for (amt_read = 0; amt_to_read > 0;
4937 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4938 if (amt_read == -1) {
4939 warn("error reading data from stdin");
4941 goto scsicmd_bailout;
4943 amt_to_read -= amt_read;
4944 buf_ptr += amt_read;
4948 if (arglist & CAM_ARG_ERR_RECOVER)
4949 flags |= CAM_PASS_ERR_RECOVER;
4951 /* Disable freezing the device queue */
4952 flags |= CAM_DEV_QFRZDIS;
4956 * This is taken from the SCSI-3 draft spec.
4957 * (T10/1157D revision 0.3)
4958 * The top 3 bits of an opcode are the group code.
4959 * The next 5 bits are the command code.
4960 * Group 0: six byte commands
4961 * Group 1: ten byte commands
4962 * Group 2: ten byte commands
4964 * Group 4: sixteen byte commands
4965 * Group 5: twelve byte commands
4966 * Group 6: vendor specific
4967 * Group 7: vendor specific
4969 switch((cdb[0] >> 5) & 0x7) {
4980 /* computed by buff_encode_visit */
4991 * We should probably use csio_build_visit or something like that
4992 * here, but it's easier to encode arguments as you go. The
4993 * alternative would be skipping the CDB argument and then encoding
4994 * it here, since we've got the data buffer argument by now.
4996 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4998 cam_fill_csio(&ccb->csio,
4999 /*retries*/ retry_count,
5002 /*tag_action*/ task_attr,
5003 /*data_ptr*/ data_ptr,
5004 /*dxfer_len*/ data_bytes,
5005 /*sense_len*/ SSD_FULL_SIZE,
5006 /*cdb_len*/ cdb_len,
5007 /*timeout*/ timeout ? timeout : 5000);
5010 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
5012 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5014 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5016 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5018 cam_fill_ataio(&ccb->ataio,
5019 /*retries*/ retry_count,
5023 /*data_ptr*/ data_ptr,
5024 /*dxfer_len*/ data_bytes,
5025 /*timeout*/ timeout ? timeout : 5000);
5028 if (((retval = cam_send_ccb(device, ccb)) < 0)
5029 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
5030 const char warnstr[] = "error sending command";
5037 if (arglist & CAM_ARG_VERBOSE) {
5038 cam_error_print(device, ccb, CAM_ESF_ALL,
5039 CAM_EPF_ALL, stderr);
5043 goto scsicmd_bailout;
5046 if (atacmd_len && need_res) {
5048 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
5050 fprintf(stdout, "\n");
5053 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
5054 ccb->ataio.res.status,
5055 ccb->ataio.res.error,
5056 ccb->ataio.res.lba_low,
5057 ccb->ataio.res.lba_mid,
5058 ccb->ataio.res.lba_high,
5059 ccb->ataio.res.device,
5060 ccb->ataio.res.lba_low_exp,
5061 ccb->ataio.res.lba_mid_exp,
5062 ccb->ataio.res.lba_high_exp,
5063 ccb->ataio.res.sector_count,
5064 ccb->ataio.res.sector_count_exp);
5070 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
5072 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
5073 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
5074 && (arglist & CAM_ARG_CMD_IN)
5075 && (valid_bytes > 0)) {
5077 buff_decode_visit(data_ptr, valid_bytes, datastr,
5079 fprintf(stdout, "\n");
5081 ssize_t amt_written;
5082 int amt_to_write = valid_bytes;
5083 u_int8_t *buf_ptr = data_ptr;
5085 for (amt_written = 0; (amt_to_write > 0) &&
5086 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
5087 amt_to_write -= amt_written;
5088 buf_ptr += amt_written;
5090 if (amt_written == -1) {
5091 warn("error writing data to stdout");
5093 goto scsicmd_bailout;
5094 } else if ((amt_written == 0)
5095 && (amt_to_write > 0)) {
5096 warnx("only wrote %u bytes out of %u",
5097 valid_bytes - amt_to_write, valid_bytes);
5104 if ((data_bytes > 0) && (data_ptr != NULL))
5113 camdebug(int argc, char **argv, char *combinedopt)
5116 path_id_t bus = CAM_BUS_WILDCARD;
5117 target_id_t target = CAM_TARGET_WILDCARD;
5118 lun_id_t lun = CAM_LUN_WILDCARD;
5119 char *tstr, *tmpstr = NULL;
5123 bzero(&ccb, sizeof(union ccb));
5125 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5128 arglist |= CAM_ARG_DEBUG_INFO;
5129 ccb.cdbg.flags |= CAM_DEBUG_INFO;
5132 arglist |= CAM_ARG_DEBUG_PERIPH;
5133 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
5136 arglist |= CAM_ARG_DEBUG_SUBTRACE;
5137 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
5140 arglist |= CAM_ARG_DEBUG_TRACE;
5141 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
5144 arglist |= CAM_ARG_DEBUG_XPT;
5145 ccb.cdbg.flags |= CAM_DEBUG_XPT;
5148 arglist |= CAM_ARG_DEBUG_CDB;
5149 ccb.cdbg.flags |= CAM_DEBUG_CDB;
5152 arglist |= CAM_ARG_DEBUG_PROBE;
5153 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
5160 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
5161 warnx("error opening transport layer device %s", XPT_DEVICE);
5162 warn("%s", XPT_DEVICE);
5169 warnx("you must specify \"off\", \"all\" or a bus,");
5170 warnx("bus:target, or bus:target:lun");
5177 while (isspace(*tstr) && (*tstr != '\0'))
5180 if (strncmp(tstr, "off", 3) == 0) {
5181 ccb.cdbg.flags = CAM_DEBUG_NONE;
5182 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
5183 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
5184 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
5185 } else if (strncmp(tstr, "all", 3) != 0) {
5186 tmpstr = (char *)strtok(tstr, ":");
5187 if ((tmpstr != NULL) && (*tmpstr != '\0')){
5188 bus = strtol(tmpstr, NULL, 0);
5189 arglist |= CAM_ARG_BUS;
5190 tmpstr = (char *)strtok(NULL, ":");
5191 if ((tmpstr != NULL) && (*tmpstr != '\0')){
5192 target = strtol(tmpstr, NULL, 0);
5193 arglist |= CAM_ARG_TARGET;
5194 tmpstr = (char *)strtok(NULL, ":");
5195 if ((tmpstr != NULL) && (*tmpstr != '\0')){
5196 lun = strtol(tmpstr, NULL, 0);
5197 arglist |= CAM_ARG_LUN;
5202 warnx("you must specify \"all\", \"off\", or a bus,");
5203 warnx("bus:target, or bus:target:lun to debug");
5209 ccb.ccb_h.func_code = XPT_DEBUG;
5210 ccb.ccb_h.path_id = bus;
5211 ccb.ccb_h.target_id = target;
5212 ccb.ccb_h.target_lun = lun;
5214 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
5215 warn("CAMIOCOMMAND ioctl failed");
5220 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
5221 CAM_FUNC_NOTAVAIL) {
5222 warnx("CAM debugging not available");
5223 warnx("you need to put options CAMDEBUG in"
5224 " your kernel config file!");
5226 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
5228 warnx("XPT_DEBUG CCB failed with status %#x",
5232 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
5234 "Debugging turned off\n");
5237 "Debugging enabled for "
5239 bus, target, (uintmax_t)lun);
5250 tagcontrol(struct cam_device *device, int argc, char **argv,
5260 ccb = cam_getccb(device);
5263 warnx("tagcontrol: error allocating ccb");
5267 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5270 numtags = strtol(optarg, NULL, 0);
5272 warnx("tag count %d is < 0", numtags);
5274 goto tagcontrol_bailout;
5285 cam_path_string(device, pathstr, sizeof(pathstr));
5288 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
5289 ccb->ccb_h.func_code = XPT_REL_SIMQ;
5290 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5291 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5292 ccb->crs.openings = numtags;
5295 if (cam_send_ccb(device, ccb) < 0) {
5296 perror("error sending XPT_REL_SIMQ CCB");
5298 goto tagcontrol_bailout;
5301 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5302 warnx("XPT_REL_SIMQ CCB failed");
5303 cam_error_print(device, ccb, CAM_ESF_ALL,
5304 CAM_EPF_ALL, stderr);
5306 goto tagcontrol_bailout;
5311 fprintf(stdout, "%stagged openings now %d\n",
5312 pathstr, ccb->crs.openings);
5315 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5317 ccb->ccb_h.func_code = XPT_GDEV_STATS;
5319 if (cam_send_ccb(device, ccb) < 0) {
5320 perror("error sending XPT_GDEV_STATS CCB");
5322 goto tagcontrol_bailout;
5325 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5326 warnx("XPT_GDEV_STATS CCB failed");
5327 cam_error_print(device, ccb, CAM_ESF_ALL,
5328 CAM_EPF_ALL, stderr);
5330 goto tagcontrol_bailout;
5333 if (arglist & CAM_ARG_VERBOSE) {
5334 fprintf(stdout, "%s", pathstr);
5335 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5336 fprintf(stdout, "%s", pathstr);
5337 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5338 fprintf(stdout, "%s", pathstr);
5339 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5340 fprintf(stdout, "%s", pathstr);
5341 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5342 fprintf(stdout, "%s", pathstr);
5343 fprintf(stdout, "held %d\n", ccb->cgds.held);
5344 fprintf(stdout, "%s", pathstr);
5345 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5346 fprintf(stdout, "%s", pathstr);
5347 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5350 fprintf(stdout, "%s", pathstr);
5351 fprintf(stdout, "device openings: ");
5353 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5354 ccb->cgds.dev_active);
5364 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5368 cam_path_string(device, pathstr, sizeof(pathstr));
5370 if (cts->transport == XPORT_SPI) {
5371 struct ccb_trans_settings_spi *spi =
5372 &cts->xport_specific.spi;
5374 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5376 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5379 if (spi->sync_offset != 0) {
5382 freq = scsi_calc_syncsrate(spi->sync_period);
5383 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5384 pathstr, freq / 1000, freq % 1000);
5388 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5389 fprintf(stdout, "%soffset: %d\n", pathstr,
5393 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5394 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5395 (0x01 << spi->bus_width) * 8);
5398 if (spi->valid & CTS_SPI_VALID_DISC) {
5399 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5400 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5401 "enabled" : "disabled");
5404 if (cts->transport == XPORT_FC) {
5405 struct ccb_trans_settings_fc *fc =
5406 &cts->xport_specific.fc;
5408 if (fc->valid & CTS_FC_VALID_WWNN)
5409 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5410 (long long) fc->wwnn);
5411 if (fc->valid & CTS_FC_VALID_WWPN)
5412 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5413 (long long) fc->wwpn);
5414 if (fc->valid & CTS_FC_VALID_PORT)
5415 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5416 if (fc->valid & CTS_FC_VALID_SPEED)
5417 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5418 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5420 if (cts->transport == XPORT_SAS) {
5421 struct ccb_trans_settings_sas *sas =
5422 &cts->xport_specific.sas;
5424 if (sas->valid & CTS_SAS_VALID_SPEED)
5425 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5426 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5428 if (cts->transport == XPORT_ATA) {
5429 struct ccb_trans_settings_pata *pata =
5430 &cts->xport_specific.ata;
5432 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5433 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5434 ata_mode2string(pata->mode));
5436 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5437 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5440 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5441 fprintf(stdout, "%sPIO transaction length: %d\n",
5442 pathstr, pata->bytecount);
5445 if (cts->transport == XPORT_SATA) {
5446 struct ccb_trans_settings_sata *sata =
5447 &cts->xport_specific.sata;
5449 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5450 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5453 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5454 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5455 ata_mode2string(sata->mode));
5457 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5458 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5461 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5462 fprintf(stdout, "%sPIO transaction length: %d\n",
5463 pathstr, sata->bytecount);
5465 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5466 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5469 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5470 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5473 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5474 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5478 if (cts->protocol == PROTO_ATA) {
5479 struct ccb_trans_settings_ata *ata=
5480 &cts->proto_specific.ata;
5482 if (ata->valid & CTS_ATA_VALID_TQ) {
5483 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5484 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5485 "enabled" : "disabled");
5488 if (cts->protocol == PROTO_SCSI) {
5489 struct ccb_trans_settings_scsi *scsi=
5490 &cts->proto_specific.scsi;
5492 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5493 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5494 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5495 "enabled" : "disabled");
5499 if (cts->protocol == PROTO_NVME) {
5500 struct ccb_trans_settings_nvme *nvmex =
5501 &cts->xport_specific.nvme;
5503 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5504 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5505 NVME_MAJOR(nvmex->spec),
5506 NVME_MINOR(nvmex->spec));
5508 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5509 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5510 nvmex->lanes, nvmex->max_lanes);
5511 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5512 nvmex->speed, nvmex->max_speed);
5519 * Get a path inquiry CCB for the specified device.
5522 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5527 ccb = cam_getccb(device);
5529 warnx("get_cpi: couldn't allocate CCB");
5532 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5533 ccb->ccb_h.func_code = XPT_PATH_INQ;
5534 if (cam_send_ccb(device, ccb) < 0) {
5535 warn("get_cpi: error sending Path Inquiry CCB");
5536 if (arglist & CAM_ARG_VERBOSE)
5537 cam_error_print(device, ccb, CAM_ESF_ALL,
5538 CAM_EPF_ALL, stderr);
5540 goto get_cpi_bailout;
5542 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5543 if (arglist & CAM_ARG_VERBOSE)
5544 cam_error_print(device, ccb, CAM_ESF_ALL,
5545 CAM_EPF_ALL, stderr);
5547 goto get_cpi_bailout;
5549 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5557 * Get a get device CCB for the specified device.
5560 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5565 ccb = cam_getccb(device);
5567 warnx("get_cgd: couldn't allocate CCB");
5570 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5571 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5572 if (cam_send_ccb(device, ccb) < 0) {
5573 warn("get_cgd: error sending Path Inquiry CCB");
5574 if (arglist & CAM_ARG_VERBOSE)
5575 cam_error_print(device, ccb, CAM_ESF_ALL,
5576 CAM_EPF_ALL, stderr);
5578 goto get_cgd_bailout;
5580 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5581 if (arglist & CAM_ARG_VERBOSE)
5582 cam_error_print(device, ccb, CAM_ESF_ALL,
5583 CAM_EPF_ALL, stderr);
5585 goto get_cgd_bailout;
5587 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5595 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5599 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5600 int timeout, int verbosemode)
5602 union ccb *ccb = NULL;
5603 struct scsi_vpd_supported_page_list sup_pages;
5607 ccb = cam_getccb(dev);
5609 warn("Unable to allocate CCB");
5614 /* cam_getccb cleans up the header, caller has to zero the payload */
5615 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5617 bzero(&sup_pages, sizeof(sup_pages));
5619 scsi_inquiry(&ccb->csio,
5620 /*retries*/ retry_count,
5622 /* tag_action */ MSG_SIMPLE_Q_TAG,
5623 /* inq_buf */ (u_int8_t *)&sup_pages,
5624 /* inq_len */ sizeof(sup_pages),
5626 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5627 /* sense_len */ SSD_FULL_SIZE,
5628 /* timeout */ timeout ? timeout : 5000);
5630 /* Disable freezing the device queue */
5631 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5633 if (retry_count != 0)
5634 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5636 if (cam_send_ccb(dev, ccb) < 0) {
5643 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5644 if (verbosemode != 0)
5645 cam_error_print(dev, ccb, CAM_ESF_ALL,
5646 CAM_EPF_ALL, stderr);
5651 for (i = 0; i < sup_pages.length; i++) {
5652 if (sup_pages.list[i] == page_id) {
5665 * devtype is filled in with the type of device.
5666 * Returns 0 for success, non-zero for failure.
5669 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5670 int verbosemode, camcontrol_devtype *devtype)
5672 struct ccb_getdev cgd;
5675 retval = get_cgd(dev, &cgd);
5679 switch (cgd.protocol) {
5685 *devtype = CC_DT_ATA;
5687 break; /*NOTREACHED*/
5689 *devtype = CC_DT_NVME;
5691 break; /*NOTREACHED*/
5693 *devtype = CC_DT_MMCSD;
5695 break; /*NOTREACHED*/
5697 *devtype = CC_DT_UNKNOWN;
5699 break; /*NOTREACHED*/
5702 if (retry_count == -1) {
5704 * For a retry count of -1, used only the cached data to avoid
5705 * I/O to the drive. Sending the identify command to the drive
5706 * can cause issues for SATL attachaed drives since identify is
5707 * not an NCQ command.
5709 if (cgd.ident_data.config != 0)
5710 *devtype = CC_DT_SATL;
5712 *devtype = CC_DT_SCSI;
5715 * Check for the ATA Information VPD page (0x89). If this is an
5716 * ATA device behind a SCSI to ATA translation layer (SATL),
5717 * this VPD page should be present.
5719 * If that VPD page isn't present, or we get an error back from
5720 * the INQUIRY command, we'll just treat it as a normal SCSI
5723 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5724 timeout, verbosemode);
5726 *devtype = CC_DT_SATL;
5728 *devtype = CC_DT_SCSI;
5737 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5738 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5739 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5740 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5741 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5742 int is48bit, camcontrol_devtype devtype)
5746 if (devtype == CC_DT_ATA) {
5747 cam_fill_ataio(&ccb->ataio,
5748 /*retries*/ retry_count,
5751 /*tag_action*/ tag_action,
5752 /*data_ptr*/ data_ptr,
5753 /*dxfer_len*/ dxfer_len,
5754 /*timeout*/ timeout);
5755 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5756 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5759 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5762 if (auxiliary != 0) {
5763 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5764 ccb->ataio.aux = auxiliary;
5767 if (ata_flags & AP_FLAG_CHK_COND)
5768 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5770 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5771 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5772 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5773 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5775 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5776 protocol |= AP_EXTEND;
5778 retval = scsi_ata_pass(&ccb->csio,
5779 /*retries*/ retry_count,
5782 /*tag_action*/ tag_action,
5783 /*protocol*/ protocol,
5784 /*ata_flags*/ ata_flags,
5785 /*features*/ features,
5786 /*sector_count*/ sector_count,
5788 /*command*/ command,
5791 /*auxiliary*/ auxiliary,
5793 /*data_ptr*/ data_ptr,
5794 /*dxfer_len*/ dxfer_len,
5795 /*cdb_storage*/ cdb_storage,
5796 /*cdb_storage_len*/ cdb_storage_len,
5797 /*minimum_cmd_size*/ 0,
5798 /*sense_len*/ sense_len,
5799 /*timeout*/ timeout);
5806 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5807 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5811 switch (ccb->ccb_h.func_code) {
5814 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5817 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5818 * or 16 byte, and need to see what
5820 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5821 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5823 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5824 if ((opcode != ATA_PASS_12)
5825 && (opcode != ATA_PASS_16)) {
5827 warnx("%s: unsupported opcode %02x", __func__, opcode);
5831 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5833 /* Note: the _ccb() variant returns 0 for an error */
5840 switch (error_code) {
5841 case SSD_DESC_CURRENT_ERROR:
5842 case SSD_DESC_DEFERRED_ERROR: {
5843 struct scsi_sense_data_desc *sense;
5844 struct scsi_sense_ata_ret_desc *desc;
5847 sense = (struct scsi_sense_data_desc *)
5848 &ccb->csio.sense_data;
5850 desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len -
5851 ccb->csio.sense_resid, SSD_DESC_ATA);
5852 if (desc_ptr == NULL) {
5853 cam_error_print(dev, ccb, CAM_ESF_ALL,
5854 CAM_EPF_ALL, stderr);
5858 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5860 *error = desc->error;
5861 *count = (desc->count_15_8 << 8) |
5863 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5864 ((uint64_t)desc->lba_39_32 << 32) |
5865 ((uint64_t)desc->lba_31_24 << 24) |
5866 (desc->lba_23_16 << 16) |
5867 (desc->lba_15_8 << 8) |
5869 *device = desc->device;
5870 *status = desc->status;
5873 * If the extend bit isn't set, the result is for a
5874 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5875 * command without the extend bit set. This means
5876 * that the device is supposed to return 28-bit
5877 * status. The count field is only 8 bits, and the
5878 * LBA field is only 8 bits.
5880 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5886 case SSD_CURRENT_ERROR:
5887 case SSD_DEFERRED_ERROR: {
5889 struct scsi_sense_data_fixed *sense;
5892 * XXX KDM need to support fixed sense data.
5894 warnx("%s: Fixed sense data not supported yet",
5898 break; /*NOTREACHED*/
5909 struct ata_res *res;
5912 * In this case, we have an ATA command, and we need to
5913 * fill in the requested values from the result register
5916 res = &ccb->ataio.res;
5917 *error = res->error;
5918 *status = res->status;
5919 *device = res->device;
5920 *count = res->sector_count;
5921 *lba = (res->lba_high << 16) |
5922 (res->lba_mid << 8) |
5924 if (res->flags & CAM_ATAIO_48BIT) {
5925 *count |= (res->sector_count_exp << 8);
5926 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5927 ((uint64_t)res->lba_mid_exp << 32) |
5928 ((uint64_t)res->lba_high_exp << 40);
5930 *lba |= (res->device & 0xf) << 24;
5943 cpi_print(struct ccb_pathinq *cpi)
5945 char adapter_str[1024];
5948 snprintf(adapter_str, sizeof(adapter_str),
5949 "%s%d:", cpi->dev_name, cpi->unit_number);
5951 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5954 for (i = 1; i < UINT8_MAX; i = i << 1) {
5957 if ((i & cpi->hba_inquiry) == 0)
5960 fprintf(stdout, "%s supports ", adapter_str);
5964 str = "MDP message";
5967 str = "32 bit wide SCSI";
5970 str = "16 bit wide SCSI";
5973 str = "SDTR message";
5976 str = "linked CDBs";
5979 str = "tag queue messages";
5982 str = "soft reset alternative";
5985 str = "SATA Port Multiplier";
5988 str = "unknown PI bit set";
5991 fprintf(stdout, "%s\n", str);
5994 for (i = 1; i < UINT32_MAX; i = i << 1) {
5997 if ((i & cpi->hba_misc) == 0)
6000 fprintf(stdout, "%s ", adapter_str);
6004 str = "can understand ata_ext requests";
6007 str = "64bit extended LUNs supported";
6010 str = "bus scans from high ID to low ID";
6013 str = "removable devices not included in scan";
6015 case PIM_NOINITIATOR:
6016 str = "initiator role not supported";
6018 case PIM_NOBUSRESET:
6019 str = "user has disabled initial BUS RESET or"
6020 " controller is in target/mixed mode";
6023 str = "do not send 6-byte commands";
6026 str = "scan bus sequentially";
6029 str = "unmapped I/O supported";
6032 str = "does its own scanning";
6035 str = "unknown PIM bit set";
6038 fprintf(stdout, "%s\n", str);
6041 for (i = 1; i < UINT16_MAX; i = i << 1) {
6044 if ((i & cpi->target_sprt) == 0)
6047 fprintf(stdout, "%s supports ", adapter_str);
6050 str = "target mode processor mode";
6053 str = "target mode phase cog. mode";
6055 case PIT_DISCONNECT:
6056 str = "disconnects in target mode";
6059 str = "terminate I/O message in target mode";
6062 str = "group 6 commands in target mode";
6065 str = "group 7 commands in target mode";
6068 str = "unknown PIT bit set";
6072 fprintf(stdout, "%s\n", str);
6074 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
6076 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
6078 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
6080 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
6081 adapter_str, cpi->hpath_id);
6082 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
6084 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
6085 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
6086 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
6087 adapter_str, cpi->hba_vendor);
6088 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
6089 adapter_str, cpi->hba_device);
6090 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
6091 adapter_str, cpi->hba_subvendor);
6092 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
6093 adapter_str, cpi->hba_subdevice);
6094 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
6095 fprintf(stdout, "%s base transfer speed: ", adapter_str);
6096 if (cpi->base_transfer_speed > 1000)
6097 fprintf(stdout, "%d.%03dMB/sec\n",
6098 cpi->base_transfer_speed / 1000,
6099 cpi->base_transfer_speed % 1000);
6101 fprintf(stdout, "%dKB/sec\n",
6102 (cpi->base_transfer_speed % 1000) * 1000);
6103 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
6104 adapter_str, cpi->maxio);
6108 get_print_cts(struct cam_device *device, int user_settings, int quiet,
6109 struct ccb_trans_settings *cts)
6115 ccb = cam_getccb(device);
6118 warnx("get_print_cts: error allocating ccb");
6122 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
6124 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
6126 if (user_settings == 0)
6127 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
6129 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
6131 if (cam_send_ccb(device, ccb) < 0) {
6132 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
6133 if (arglist & CAM_ARG_VERBOSE)
6134 cam_error_print(device, ccb, CAM_ESF_ALL,
6135 CAM_EPF_ALL, stderr);
6137 goto get_print_cts_bailout;
6140 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6141 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
6142 if (arglist & CAM_ARG_VERBOSE)
6143 cam_error_print(device, ccb, CAM_ESF_ALL,
6144 CAM_EPF_ALL, stderr);
6146 goto get_print_cts_bailout;
6150 cts_print(device, &ccb->cts);
6153 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
6155 get_print_cts_bailout:
6163 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
6164 int timeout, int argc, char **argv, char *combinedopt)
6168 int user_settings = 0;
6170 int disc_enable = -1, tag_enable = -1;
6173 double syncrate = -1;
6176 int change_settings = 0, send_tur = 0;
6177 struct ccb_pathinq cpi;
6179 ccb = cam_getccb(device);
6181 warnx("ratecontrol: error allocating ccb");
6184 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6193 if (strncasecmp(optarg, "enable", 6) == 0)
6195 else if (strncasecmp(optarg, "disable", 7) == 0)
6198 warnx("-D argument \"%s\" is unknown", optarg);
6200 goto ratecontrol_bailout;
6202 change_settings = 1;
6205 mode = ata_string2mode(optarg);
6207 warnx("unknown mode '%s'", optarg);
6209 goto ratecontrol_bailout;
6211 change_settings = 1;
6214 offset = strtol(optarg, NULL, 0);
6216 warnx("offset value %d is < 0", offset);
6218 goto ratecontrol_bailout;
6220 change_settings = 1;
6226 syncrate = atof(optarg);
6228 warnx("sync rate %f is < 0", syncrate);
6230 goto ratecontrol_bailout;
6232 change_settings = 1;
6235 if (strncasecmp(optarg, "enable", 6) == 0)
6237 else if (strncasecmp(optarg, "disable", 7) == 0)
6240 warnx("-T argument \"%s\" is unknown", optarg);
6242 goto ratecontrol_bailout;
6244 change_settings = 1;
6250 bus_width = strtol(optarg, NULL, 0);
6251 if (bus_width < 0) {
6252 warnx("bus width %d is < 0", bus_width);
6254 goto ratecontrol_bailout;
6256 change_settings = 1;
6262 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
6264 * Grab path inquiry information, so we can determine whether
6265 * or not the initiator is capable of the things that the user
6268 ccb->ccb_h.func_code = XPT_PATH_INQ;
6269 if (cam_send_ccb(device, ccb) < 0) {
6270 perror("error sending XPT_PATH_INQ CCB");
6271 if (arglist & CAM_ARG_VERBOSE) {
6272 cam_error_print(device, ccb, CAM_ESF_ALL,
6273 CAM_EPF_ALL, stderr);
6276 goto ratecontrol_bailout;
6278 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6279 warnx("XPT_PATH_INQ CCB failed");
6280 if (arglist & CAM_ARG_VERBOSE) {
6281 cam_error_print(device, ccb, CAM_ESF_ALL,
6282 CAM_EPF_ALL, stderr);
6285 goto ratecontrol_bailout;
6287 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
6288 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
6290 fprintf(stdout, "%s parameters:\n",
6291 user_settings ? "User" : "Current");
6293 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
6295 goto ratecontrol_bailout;
6297 if (arglist & CAM_ARG_VERBOSE)
6300 if (change_settings) {
6301 int didsettings = 0;
6302 struct ccb_trans_settings_spi *spi = NULL;
6303 struct ccb_trans_settings_pata *pata = NULL;
6304 struct ccb_trans_settings_sata *sata = NULL;
6305 struct ccb_trans_settings_ata *ata = NULL;
6306 struct ccb_trans_settings_scsi *scsi = NULL;
6308 if (ccb->cts.transport == XPORT_SPI)
6309 spi = &ccb->cts.xport_specific.spi;
6310 if (ccb->cts.transport == XPORT_ATA)
6311 pata = &ccb->cts.xport_specific.ata;
6312 if (ccb->cts.transport == XPORT_SATA)
6313 sata = &ccb->cts.xport_specific.sata;
6314 if (ccb->cts.protocol == PROTO_ATA)
6315 ata = &ccb->cts.proto_specific.ata;
6316 if (ccb->cts.protocol == PROTO_SCSI)
6317 scsi = &ccb->cts.proto_specific.scsi;
6318 ccb->cts.xport_specific.valid = 0;
6319 ccb->cts.proto_specific.valid = 0;
6320 if (spi && disc_enable != -1) {
6321 spi->valid |= CTS_SPI_VALID_DISC;
6322 if (disc_enable == 0)
6323 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6325 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6328 if (tag_enable != -1) {
6329 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6330 warnx("HBA does not support tagged queueing, "
6331 "so you cannot modify tag settings");
6333 goto ratecontrol_bailout;
6336 ata->valid |= CTS_SCSI_VALID_TQ;
6337 if (tag_enable == 0)
6338 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6340 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6343 scsi->valid |= CTS_SCSI_VALID_TQ;
6344 if (tag_enable == 0)
6345 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6347 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6351 if (spi && offset != -1) {
6352 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6353 warnx("HBA is not capable of changing offset");
6355 goto ratecontrol_bailout;
6357 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6358 spi->sync_offset = offset;
6361 if (spi && syncrate != -1) {
6362 int prelim_sync_period;
6364 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6365 warnx("HBA is not capable of changing "
6368 goto ratecontrol_bailout;
6370 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6372 * The sync rate the user gives us is in MHz.
6373 * We need to translate it into KHz for this
6378 * Next, we calculate a "preliminary" sync period
6379 * in tenths of a nanosecond.
6382 prelim_sync_period = 0;
6384 prelim_sync_period = 10000000 / syncrate;
6386 scsi_calc_syncparam(prelim_sync_period);
6389 if (sata && syncrate != -1) {
6390 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6391 warnx("HBA is not capable of changing "
6394 goto ratecontrol_bailout;
6396 if (!user_settings) {
6397 warnx("You can modify only user rate "
6398 "settings for SATA");
6400 goto ratecontrol_bailout;
6402 sata->revision = ata_speed2revision(syncrate * 100);
6403 if (sata->revision < 0) {
6404 warnx("Invalid rate %f", syncrate);
6406 goto ratecontrol_bailout;
6408 sata->valid |= CTS_SATA_VALID_REVISION;
6411 if ((pata || sata) && mode != -1) {
6412 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6413 warnx("HBA is not capable of changing "
6416 goto ratecontrol_bailout;
6418 if (!user_settings) {
6419 warnx("You can modify only user mode "
6420 "settings for ATA/SATA");
6422 goto ratecontrol_bailout;
6426 pata->valid |= CTS_ATA_VALID_MODE;
6429 sata->valid |= CTS_SATA_VALID_MODE;
6434 * The bus_width argument goes like this:
6438 * Therefore, if you shift the number of bits given on the
6439 * command line right by 4, you should get the correct
6442 if (spi && bus_width != -1) {
6444 * We might as well validate things here with a
6445 * decipherable error message, rather than what
6446 * will probably be an indecipherable error message
6447 * by the time it gets back to us.
6449 if ((bus_width == 16)
6450 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6451 warnx("HBA does not support 16 bit bus width");
6453 goto ratecontrol_bailout;
6454 } else if ((bus_width == 32)
6455 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6456 warnx("HBA does not support 32 bit bus width");
6458 goto ratecontrol_bailout;
6459 } else if ((bus_width != 8)
6460 && (bus_width != 16)
6461 && (bus_width != 32)) {
6462 warnx("Invalid bus width %d", bus_width);
6464 goto ratecontrol_bailout;
6466 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6467 spi->bus_width = bus_width >> 4;
6470 if (didsettings == 0) {
6471 goto ratecontrol_bailout;
6473 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6474 if (cam_send_ccb(device, ccb) < 0) {
6475 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
6476 if (arglist & CAM_ARG_VERBOSE) {
6477 cam_error_print(device, ccb, CAM_ESF_ALL,
6478 CAM_EPF_ALL, stderr);
6481 goto ratecontrol_bailout;
6483 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6484 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6485 if (arglist & CAM_ARG_VERBOSE) {
6486 cam_error_print(device, ccb, CAM_ESF_ALL,
6487 CAM_EPF_ALL, stderr);
6490 goto ratecontrol_bailout;
6494 retval = testunitready(device, task_attr, retry_count, timeout,
6495 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6497 * If the TUR didn't succeed, just bail.
6501 fprintf(stderr, "Test Unit Ready failed\n");
6502 goto ratecontrol_bailout;
6505 if ((change_settings || send_tur) && !quiet &&
6506 (ccb->cts.transport == XPORT_ATA ||
6507 ccb->cts.transport == XPORT_SATA || send_tur)) {
6508 fprintf(stdout, "New parameters:\n");
6509 retval = get_print_cts(device, user_settings, 0, NULL);
6512 ratecontrol_bailout:
6518 scsiformat(struct cam_device *device, int argc, char **argv,
6519 char *combinedopt, int task_attr, int retry_count, int timeout)
6523 int ycount = 0, quiet = 0;
6524 int error = 0, retval = 0;
6525 int use_timeout = 10800 * 1000;
6527 struct format_defect_list_header fh;
6528 u_int8_t *data_ptr = NULL;
6529 u_int32_t dxfer_len = 0;
6531 int num_warnings = 0;
6534 ccb = cam_getccb(device);
6537 warnx("scsiformat: error allocating ccb");
6541 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6543 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6564 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6565 "following device:\n");
6567 error = scsidoinquiry(device, argc, argv, combinedopt,
6568 task_attr, retry_count, timeout);
6571 warnx("scsiformat: error sending inquiry");
6572 goto scsiformat_bailout;
6577 if (!get_confirmation()) {
6579 goto scsiformat_bailout;
6584 use_timeout = timeout;
6587 fprintf(stdout, "Current format timeout is %d seconds\n",
6588 use_timeout / 1000);
6592 * If the user hasn't disabled questions and didn't specify a
6593 * timeout on the command line, ask them if they want the current
6597 && (timeout == 0)) {
6599 int new_timeout = 0;
6601 fprintf(stdout, "Enter new timeout in seconds or press\n"
6602 "return to keep the current timeout [%d] ",
6603 use_timeout / 1000);
6605 if (fgets(str, sizeof(str), stdin) != NULL) {
6607 new_timeout = atoi(str);
6610 if (new_timeout != 0) {
6611 use_timeout = new_timeout * 1000;
6612 fprintf(stdout, "Using new timeout value %d\n",
6613 use_timeout / 1000);
6618 * Keep this outside the if block below to silence any unused
6619 * variable warnings.
6621 bzero(&fh, sizeof(fh));
6624 * If we're in immediate mode, we've got to include the format
6627 if (immediate != 0) {
6628 fh.byte2 = FU_DLH_IMMED;
6629 data_ptr = (u_int8_t *)&fh;
6630 dxfer_len = sizeof(fh);
6631 byte2 = FU_FMT_DATA;
6632 } else if (quiet == 0) {
6633 fprintf(stdout, "Formatting...");
6637 scsi_format_unit(&ccb->csio,
6638 /* retries */ retry_count,
6640 /* tag_action */ task_attr,
6643 /* data_ptr */ data_ptr,
6644 /* dxfer_len */ dxfer_len,
6645 /* sense_len */ SSD_FULL_SIZE,
6646 /* timeout */ use_timeout);
6648 /* Disable freezing the device queue */
6649 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6651 if (arglist & CAM_ARG_ERR_RECOVER)
6652 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6654 if (((retval = cam_send_ccb(device, ccb)) < 0)
6655 || ((immediate == 0)
6656 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6657 const char errstr[] = "error sending format command";
6664 if (arglist & CAM_ARG_VERBOSE) {
6665 cam_error_print(device, ccb, CAM_ESF_ALL,
6666 CAM_EPF_ALL, stderr);
6669 goto scsiformat_bailout;
6673 * If we ran in non-immediate mode, we already checked for errors
6674 * above and printed out any necessary information. If we're in
6675 * immediate mode, we need to loop through and get status
6676 * information periodically.
6678 if (immediate == 0) {
6680 fprintf(stdout, "Format Complete\n");
6682 goto scsiformat_bailout;
6689 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6692 * There's really no need to do error recovery or
6693 * retries here, since we're just going to sit in a
6694 * loop and wait for the device to finish formatting.
6696 scsi_test_unit_ready(&ccb->csio,
6699 /* tag_action */ task_attr,
6700 /* sense_len */ SSD_FULL_SIZE,
6701 /* timeout */ 5000);
6703 /* Disable freezing the device queue */
6704 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6706 retval = cam_send_ccb(device, ccb);
6709 * If we get an error from the ioctl, bail out. SCSI
6710 * errors are expected.
6713 warn("error sending CAMIOCOMMAND ioctl");
6714 if (arglist & CAM_ARG_VERBOSE) {
6715 cam_error_print(device, ccb, CAM_ESF_ALL,
6716 CAM_EPF_ALL, stderr);
6719 goto scsiformat_bailout;
6722 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6724 if ((status != CAM_REQ_CMP)
6725 && (status == CAM_SCSI_STATUS_ERROR)
6726 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6727 struct scsi_sense_data *sense;
6728 int error_code, sense_key, asc, ascq;
6730 sense = &ccb->csio.sense_data;
6731 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6732 ccb->csio.sense_resid, &error_code, &sense_key,
6733 &asc, &ascq, /*show_errors*/ 1);
6736 * According to the SCSI-2 and SCSI-3 specs, a
6737 * drive that is in the middle of a format should
6738 * return NOT READY with an ASC of "logical unit
6739 * not ready, format in progress". The sense key
6740 * specific bytes will then be a progress indicator.
6742 if ((sense_key == SSD_KEY_NOT_READY)
6743 && (asc == 0x04) && (ascq == 0x04)) {
6746 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6747 ccb->csio.sense_resid, sks) == 0)
6750 u_int64_t percentage;
6752 val = scsi_2btoul(&sks[1]);
6753 percentage = 10000ull * val;
6756 "\rFormatting: %ju.%02u %% "
6758 (uintmax_t)(percentage /
6760 (unsigned)((percentage /
6764 } else if ((quiet == 0)
6765 && (++num_warnings <= 1)) {
6766 warnx("Unexpected SCSI Sense Key "
6767 "Specific value returned "
6769 scsi_sense_print(device, &ccb->csio,
6771 warnx("Unable to print status "
6772 "information, but format will "
6774 warnx("will exit when format is "
6779 warnx("Unexpected SCSI error during format");
6780 cam_error_print(device, ccb, CAM_ESF_ALL,
6781 CAM_EPF_ALL, stderr);
6783 goto scsiformat_bailout;
6786 } else if (status != CAM_REQ_CMP) {
6787 warnx("Unexpected CAM status %#x", status);
6788 if (arglist & CAM_ARG_VERBOSE)
6789 cam_error_print(device, ccb, CAM_ESF_ALL,
6790 CAM_EPF_ALL, stderr);
6792 goto scsiformat_bailout;
6795 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6798 fprintf(stdout, "\nFormat Complete\n");
6808 scsisanitize(struct cam_device *device, int argc, char **argv,
6809 char *combinedopt, int task_attr, int retry_count, int timeout)
6812 u_int8_t action = 0;
6814 int ycount = 0, quiet = 0;
6815 int error = 0, retval = 0;
6816 int use_timeout = 10800 * 1000;
6822 const char *pattern = NULL;
6823 u_int8_t *data_ptr = NULL;
6824 u_int32_t dxfer_len = 0;
6826 int num_warnings = 0;
6829 ccb = cam_getccb(device);
6832 warnx("scsisanitize: error allocating ccb");
6836 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6838 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6841 if (strcasecmp(optarg, "overwrite") == 0)
6842 action = SSZ_SERVICE_ACTION_OVERWRITE;
6843 else if (strcasecmp(optarg, "block") == 0)
6844 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6845 else if (strcasecmp(optarg, "crypto") == 0)
6846 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6847 else if (strcasecmp(optarg, "exitfailure") == 0)
6848 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6850 warnx("invalid service operation \"%s\"",
6853 goto scsisanitize_bailout;
6857 passes = strtol(optarg, NULL, 0);
6858 if (passes < 1 || passes > 31) {
6859 warnx("invalid passes value %d", passes);
6861 goto scsisanitize_bailout;
6892 warnx("an action is required");
6894 goto scsisanitize_bailout;
6895 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6896 struct scsi_sanitize_parameter_list *pl;
6900 if (pattern == NULL) {
6901 warnx("overwrite action requires -P argument");
6903 goto scsisanitize_bailout;
6905 fd = open(pattern, O_RDONLY);
6907 warn("cannot open pattern file %s", pattern);
6909 goto scsisanitize_bailout;
6911 if (fstat(fd, &sb) < 0) {
6912 warn("cannot stat pattern file %s", pattern);
6914 goto scsisanitize_bailout;
6917 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6918 warnx("pattern file size exceeds maximum value %d",
6919 SSZPL_MAX_PATTERN_LENGTH);
6921 goto scsisanitize_bailout;
6923 dxfer_len = sizeof(*pl) + sz;
6924 data_ptr = calloc(1, dxfer_len);
6925 if (data_ptr == NULL) {
6926 warnx("cannot allocate parameter list buffer");
6928 goto scsisanitize_bailout;
6931 amt = read(fd, data_ptr + sizeof(*pl), sz);
6933 warn("cannot read pattern file");
6935 goto scsisanitize_bailout;
6936 } else if (amt != sz) {
6937 warnx("short pattern file read");
6939 goto scsisanitize_bailout;
6942 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6948 pl->byte1 |= SSZPL_INVERT;
6949 scsi_ulto2b(sz, pl->length);
6955 else if (invert != 0)
6957 else if (pattern != NULL)
6962 warnx("%s argument only valid with overwrite "
6965 goto scsisanitize_bailout;
6970 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6971 "following device:\n");
6973 error = scsidoinquiry(device, argc, argv, combinedopt,
6974 task_attr, retry_count, timeout);
6977 warnx("scsisanitize: error sending inquiry");
6978 goto scsisanitize_bailout;
6983 if (!get_confirmation()) {
6985 goto scsisanitize_bailout;
6990 use_timeout = timeout;
6993 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6994 use_timeout / 1000);
6998 * If the user hasn't disabled questions and didn't specify a
6999 * timeout on the command line, ask them if they want the current
7003 && (timeout == 0)) {
7005 int new_timeout = 0;
7007 fprintf(stdout, "Enter new timeout in seconds or press\n"
7008 "return to keep the current timeout [%d] ",
7009 use_timeout / 1000);
7011 if (fgets(str, sizeof(str), stdin) != NULL) {
7013 new_timeout = atoi(str);
7016 if (new_timeout != 0) {
7017 use_timeout = new_timeout * 1000;
7018 fprintf(stdout, "Using new timeout value %d\n",
7019 use_timeout / 1000);
7025 byte2 |= SSZ_UNRESTRICTED_EXIT;
7029 scsi_sanitize(&ccb->csio,
7030 /* retries */ retry_count,
7032 /* tag_action */ task_attr,
7035 /* data_ptr */ data_ptr,
7036 /* dxfer_len */ dxfer_len,
7037 /* sense_len */ SSD_FULL_SIZE,
7038 /* timeout */ use_timeout);
7040 /* Disable freezing the device queue */
7041 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7043 if (arglist & CAM_ARG_ERR_RECOVER)
7044 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7046 if (cam_send_ccb(device, ccb) < 0) {
7047 warn("error sending sanitize command");
7049 goto scsisanitize_bailout;
7052 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7053 struct scsi_sense_data *sense;
7054 int error_code, sense_key, asc, ascq;
7056 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
7057 CAM_SCSI_STATUS_ERROR) {
7058 sense = &ccb->csio.sense_data;
7059 scsi_extract_sense_len(sense, ccb->csio.sense_len -
7060 ccb->csio.sense_resid, &error_code, &sense_key,
7061 &asc, &ascq, /*show_errors*/ 1);
7063 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
7064 asc == 0x20 && ascq == 0x00)
7065 warnx("sanitize is not supported by "
7068 warnx("error sanitizing this device");
7070 warnx("error sanitizing this device");
7072 if (arglist & CAM_ARG_VERBOSE) {
7073 cam_error_print(device, ccb, CAM_ESF_ALL,
7074 CAM_EPF_ALL, stderr);
7077 goto scsisanitize_bailout;
7081 * If we ran in non-immediate mode, we already checked for errors
7082 * above and printed out any necessary information. If we're in
7083 * immediate mode, we need to loop through and get status
7084 * information periodically.
7086 if (immediate == 0) {
7088 fprintf(stdout, "Sanitize Complete\n");
7090 goto scsisanitize_bailout;
7097 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7100 * There's really no need to do error recovery or
7101 * retries here, since we're just going to sit in a
7102 * loop and wait for the device to finish sanitizing.
7104 scsi_test_unit_ready(&ccb->csio,
7107 /* tag_action */ task_attr,
7108 /* sense_len */ SSD_FULL_SIZE,
7109 /* timeout */ 5000);
7111 /* Disable freezing the device queue */
7112 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7114 retval = cam_send_ccb(device, ccb);
7117 * If we get an error from the ioctl, bail out. SCSI
7118 * errors are expected.
7121 warn("error sending CAMIOCOMMAND ioctl");
7122 if (arglist & CAM_ARG_VERBOSE) {
7123 cam_error_print(device, ccb, CAM_ESF_ALL,
7124 CAM_EPF_ALL, stderr);
7127 goto scsisanitize_bailout;
7130 status = ccb->ccb_h.status & CAM_STATUS_MASK;
7132 if ((status != CAM_REQ_CMP)
7133 && (status == CAM_SCSI_STATUS_ERROR)
7134 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
7135 struct scsi_sense_data *sense;
7136 int error_code, sense_key, asc, ascq;
7138 sense = &ccb->csio.sense_data;
7139 scsi_extract_sense_len(sense, ccb->csio.sense_len -
7140 ccb->csio.sense_resid, &error_code, &sense_key,
7141 &asc, &ascq, /*show_errors*/ 1);
7144 * According to the SCSI-3 spec, a drive that is in the
7145 * middle of a sanitize should return NOT READY with an
7146 * ASC of "logical unit not ready, sanitize in
7147 * progress". The sense key specific bytes will then
7148 * be a progress indicator.
7150 if ((sense_key == SSD_KEY_NOT_READY)
7151 && (asc == 0x04) && (ascq == 0x1b)) {
7154 if ((scsi_get_sks(sense, ccb->csio.sense_len -
7155 ccb->csio.sense_resid, sks) == 0)
7158 u_int64_t percentage;
7160 val = scsi_2btoul(&sks[1]);
7161 percentage = 10000 * val;
7164 "\rSanitizing: %ju.%02u %% "
7166 (uintmax_t)(percentage /
7168 (unsigned)((percentage /
7172 } else if ((quiet == 0)
7173 && (++num_warnings <= 1)) {
7174 warnx("Unexpected SCSI Sense Key "
7175 "Specific value returned "
7176 "during sanitize:");
7177 scsi_sense_print(device, &ccb->csio,
7179 warnx("Unable to print status "
7180 "information, but sanitze will "
7182 warnx("will exit when sanitize is "
7187 warnx("Unexpected SCSI error during sanitize");
7188 cam_error_print(device, ccb, CAM_ESF_ALL,
7189 CAM_EPF_ALL, stderr);
7191 goto scsisanitize_bailout;
7194 } else if (status != CAM_REQ_CMP) {
7195 warnx("Unexpected CAM status %#x", status);
7196 if (arglist & CAM_ARG_VERBOSE)
7197 cam_error_print(device, ccb, CAM_ESF_ALL,
7198 CAM_EPF_ALL, stderr);
7200 goto scsisanitize_bailout;
7202 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
7205 fprintf(stdout, "\nSanitize Complete\n");
7207 scsisanitize_bailout:
7210 if (data_ptr != NULL)
7218 scsireportluns(struct cam_device *device, int argc, char **argv,
7219 char *combinedopt, int task_attr, int retry_count, int timeout)
7222 int c, countonly, lunsonly;
7223 struct scsi_report_luns_data *lundata;
7225 uint8_t report_type;
7226 uint32_t list_len, i, j;
7231 report_type = RPL_REPORT_DEFAULT;
7232 ccb = cam_getccb(device);
7235 warnx("%s: error allocating ccb", __func__);
7239 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7244 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7253 if (strcasecmp(optarg, "default") == 0)
7254 report_type = RPL_REPORT_DEFAULT;
7255 else if (strcasecmp(optarg, "wellknown") == 0)
7256 report_type = RPL_REPORT_WELLKNOWN;
7257 else if (strcasecmp(optarg, "all") == 0)
7258 report_type = RPL_REPORT_ALL;
7260 warnx("%s: invalid report type \"%s\"",
7271 if ((countonly != 0)
7272 && (lunsonly != 0)) {
7273 warnx("%s: you can only specify one of -c or -l", __func__);
7278 * According to SPC-4, the allocation length must be at least 16
7279 * bytes -- enough for the header and one LUN.
7281 alloc_len = sizeof(*lundata) + 8;
7285 lundata = malloc(alloc_len);
7287 if (lundata == NULL) {
7288 warn("%s: error mallocing %d bytes", __func__, alloc_len);
7293 scsi_report_luns(&ccb->csio,
7294 /*retries*/ retry_count,
7296 /*tag_action*/ task_attr,
7297 /*select_report*/ report_type,
7298 /*rpl_buf*/ lundata,
7299 /*alloc_len*/ alloc_len,
7300 /*sense_len*/ SSD_FULL_SIZE,
7301 /*timeout*/ timeout ? timeout : 5000);
7303 /* Disable freezing the device queue */
7304 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7306 if (arglist & CAM_ARG_ERR_RECOVER)
7307 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7309 if (cam_send_ccb(device, ccb) < 0) {
7310 warn("error sending REPORT LUNS command");
7312 if (arglist & CAM_ARG_VERBOSE)
7313 cam_error_print(device, ccb, CAM_ESF_ALL,
7314 CAM_EPF_ALL, stderr);
7320 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7321 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7327 list_len = scsi_4btoul(lundata->length);
7330 * If we need to list the LUNs, and our allocation
7331 * length was too short, reallocate and retry.
7333 if ((countonly == 0)
7334 && (list_len > (alloc_len - sizeof(*lundata)))) {
7335 alloc_len = list_len + sizeof(*lundata);
7341 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7342 ((list_len / 8) > 1) ? "s" : "");
7347 for (i = 0; i < (list_len / 8); i++) {
7351 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7353 fprintf(stdout, ",");
7354 switch (lundata->luns[i].lundata[j] &
7355 RPL_LUNDATA_ATYP_MASK) {
7356 case RPL_LUNDATA_ATYP_PERIPH:
7357 if ((lundata->luns[i].lundata[j] &
7358 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7359 fprintf(stdout, "%d:",
7360 lundata->luns[i].lundata[j] &
7361 RPL_LUNDATA_PERIPH_BUS_MASK);
7363 && ((lundata->luns[i].lundata[j+2] &
7364 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7367 fprintf(stdout, "%d",
7368 lundata->luns[i].lundata[j+1]);
7370 case RPL_LUNDATA_ATYP_FLAT: {
7372 tmplun[0] = lundata->luns[i].lundata[j] &
7373 RPL_LUNDATA_FLAT_LUN_MASK;
7374 tmplun[1] = lundata->luns[i].lundata[j+1];
7376 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7380 case RPL_LUNDATA_ATYP_LUN:
7381 fprintf(stdout, "%d:%d:%d",
7382 (lundata->luns[i].lundata[j+1] &
7383 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7384 lundata->luns[i].lundata[j] &
7385 RPL_LUNDATA_LUN_TARG_MASK,
7386 lundata->luns[i].lundata[j+1] &
7387 RPL_LUNDATA_LUN_LUN_MASK);
7389 case RPL_LUNDATA_ATYP_EXTLUN: {
7390 int field_len_code, eam_code;
7392 eam_code = lundata->luns[i].lundata[j] &
7393 RPL_LUNDATA_EXT_EAM_MASK;
7394 field_len_code = (lundata->luns[i].lundata[j] &
7395 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7397 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7398 && (field_len_code == 0x00)) {
7399 fprintf(stdout, "%d",
7400 lundata->luns[i].lundata[j+1]);
7401 } else if ((eam_code ==
7402 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7403 && (field_len_code == 0x03)) {
7407 * This format takes up all 8 bytes.
7408 * If we aren't starting at offset 0,
7412 fprintf(stdout, "Invalid "
7415 "specified format", j);
7419 bzero(tmp_lun, sizeof(tmp_lun));
7420 bcopy(&lundata->luns[i].lundata[j+1],
7421 &tmp_lun[1], sizeof(tmp_lun) - 1);
7422 fprintf(stdout, "%#jx",
7423 (intmax_t)scsi_8btou64(tmp_lun));
7426 fprintf(stderr, "Unknown Extended LUN"
7427 "Address method %#x, length "
7428 "code %#x", eam_code,
7435 fprintf(stderr, "Unknown LUN address method "
7436 "%#x\n", lundata->luns[i].lundata[0] &
7437 RPL_LUNDATA_ATYP_MASK);
7441 * For the flat addressing method, there are no
7442 * other levels after it.
7447 fprintf(stdout, "\n");
7460 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7461 char *combinedopt, int task_attr, int retry_count, int timeout)
7464 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7465 struct scsi_read_capacity_data rcap;
7466 struct scsi_read_capacity_data_long rcaplong;
7481 ccb = cam_getccb(device);
7484 warnx("%s: error allocating ccb", __func__);
7488 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7490 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7520 if ((blocksizeonly != 0)
7521 && (numblocks != 0)) {
7522 warnx("%s: you can only specify one of -b or -N", __func__);
7527 if ((blocksizeonly != 0)
7528 && (sizeonly != 0)) {
7529 warnx("%s: you can only specify one of -b or -s", __func__);
7536 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7542 && (blocksizeonly != 0)) {
7543 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7551 scsi_read_capacity(&ccb->csio,
7552 /*retries*/ retry_count,
7554 /*tag_action*/ task_attr,
7557 /*timeout*/ timeout ? timeout : 5000);
7559 /* Disable freezing the device queue */
7560 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7562 if (arglist & CAM_ARG_ERR_RECOVER)
7563 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7565 if (cam_send_ccb(device, ccb) < 0) {
7566 warn("error sending READ CAPACITY command");
7568 if (arglist & CAM_ARG_VERBOSE)
7569 cam_error_print(device, ccb, CAM_ESF_ALL,
7570 CAM_EPF_ALL, stderr);
7576 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7577 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7582 maxsector = scsi_4btoul(rcap.addr);
7583 block_len = scsi_4btoul(rcap.length);
7586 * A last block of 2^32-1 means that the true capacity is over 2TB,
7587 * and we need to issue the long READ CAPACITY to get the real
7588 * capacity. Otherwise, we're all set.
7590 if (maxsector != 0xffffffff)
7594 scsi_read_capacity_16(&ccb->csio,
7595 /*retries*/ retry_count,
7597 /*tag_action*/ task_attr,
7601 /*rcap_buf*/ (uint8_t *)&rcaplong,
7602 /*rcap_buf_len*/ sizeof(rcaplong),
7603 /*sense_len*/ SSD_FULL_SIZE,
7604 /*timeout*/ timeout ? timeout : 5000);
7606 /* Disable freezing the device queue */
7607 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7609 if (arglist & CAM_ARG_ERR_RECOVER)
7610 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7612 if (cam_send_ccb(device, ccb) < 0) {
7613 warn("error sending READ CAPACITY (16) command");
7615 if (arglist & CAM_ARG_VERBOSE)
7616 cam_error_print(device, ccb, CAM_ESF_ALL,
7617 CAM_EPF_ALL, stderr);
7623 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7624 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7629 maxsector = scsi_8btou64(rcaplong.addr);
7630 block_len = scsi_4btoul(rcaplong.length);
7633 if (blocksizeonly == 0) {
7635 * Humanize implies !quiet, and also implies numblocks.
7637 if (humanize != 0) {
7642 tmpbytes = (maxsector + 1) * block_len;
7643 ret = humanize_number(tmpstr, sizeof(tmpstr),
7644 tmpbytes, "", HN_AUTOSCALE,
7647 HN_DIVISOR_1000 : 0));
7649 warnx("%s: humanize_number failed!", __func__);
7653 fprintf(stdout, "Device Size: %s%s", tmpstr,
7654 (sizeonly == 0) ? ", " : "\n");
7655 } else if (numblocks != 0) {
7656 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7657 "Blocks: " : "", (uintmax_t)maxsector + 1,
7658 (sizeonly == 0) ? ", " : "\n");
7660 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7661 "Last Block: " : "", (uintmax_t)maxsector,
7662 (sizeonly == 0) ? ", " : "\n");
7666 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7667 "Block Length: " : "", block_len, (quiet == 0) ?
7676 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7677 int retry_count, int timeout)
7681 uint8_t *smp_request = NULL, *smp_response = NULL;
7682 int request_size = 0, response_size = 0;
7683 int fd_request = 0, fd_response = 0;
7684 char *datastr = NULL;
7685 struct get_hook hook;
7690 * Note that at the moment we don't support sending SMP CCBs to
7691 * devices that aren't probed by CAM.
7693 ccb = cam_getccb(device);
7695 warnx("%s: error allocating CCB", __func__);
7699 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7701 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7704 arglist |= CAM_ARG_CMD_IN;
7705 response_size = strtol(optarg, NULL, 0);
7706 if (response_size <= 0) {
7707 warnx("invalid number of response bytes %d",
7710 goto smpcmd_bailout;
7712 hook.argc = argc - optind;
7713 hook.argv = argv + optind;
7716 datastr = cget(&hook, NULL);
7718 * If the user supplied "-" instead of a format, he
7719 * wants the data to be written to stdout.
7721 if ((datastr != NULL)
7722 && (datastr[0] == '-'))
7725 smp_response = (u_int8_t *)malloc(response_size);
7726 if (smp_response == NULL) {
7727 warn("can't malloc memory for SMP response");
7729 goto smpcmd_bailout;
7733 arglist |= CAM_ARG_CMD_OUT;
7734 request_size = strtol(optarg, NULL, 0);
7735 if (request_size <= 0) {
7736 warnx("invalid number of request bytes %d",
7739 goto smpcmd_bailout;
7741 hook.argc = argc - optind;
7742 hook.argv = argv + optind;
7744 datastr = cget(&hook, NULL);
7745 smp_request = (u_int8_t *)malloc(request_size);
7746 if (smp_request == NULL) {
7747 warn("can't malloc memory for SMP request");
7749 goto smpcmd_bailout;
7751 bzero(smp_request, request_size);
7753 * If the user supplied "-" instead of a format, he
7754 * wants the data to be read from stdin.
7756 if ((datastr != NULL)
7757 && (datastr[0] == '-'))
7760 buff_encode_visit(smp_request, request_size,
7771 * If fd_data is set, and we're writing to the device, we need to
7772 * read the data the user wants written from stdin.
7774 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7776 int amt_to_read = request_size;
7777 u_int8_t *buf_ptr = smp_request;
7779 for (amt_read = 0; amt_to_read > 0;
7780 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7781 if (amt_read == -1) {
7782 warn("error reading data from stdin");
7784 goto smpcmd_bailout;
7786 amt_to_read -= amt_read;
7787 buf_ptr += amt_read;
7791 if (((arglist & CAM_ARG_CMD_IN) == 0)
7792 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7793 warnx("%s: need both the request (-r) and response (-R) "
7794 "arguments", __func__);
7796 goto smpcmd_bailout;
7799 flags |= CAM_DEV_QFRZDIS;
7801 cam_fill_smpio(&ccb->smpio,
7802 /*retries*/ retry_count,
7805 /*smp_request*/ smp_request,
7806 /*smp_request_len*/ request_size,
7807 /*smp_response*/ smp_response,
7808 /*smp_response_len*/ response_size,
7809 /*timeout*/ timeout ? timeout : 5000);
7811 ccb->smpio.flags = SMP_FLAG_NONE;
7813 if (((retval = cam_send_ccb(device, ccb)) < 0)
7814 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7815 const char warnstr[] = "error sending command";
7822 if (arglist & CAM_ARG_VERBOSE) {
7823 cam_error_print(device, ccb, CAM_ESF_ALL,
7824 CAM_EPF_ALL, stderr);
7828 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7829 && (response_size > 0)) {
7830 if (fd_response == 0) {
7831 buff_decode_visit(smp_response, response_size,
7832 datastr, arg_put, NULL);
7833 fprintf(stdout, "\n");
7835 ssize_t amt_written;
7836 int amt_to_write = response_size;
7837 u_int8_t *buf_ptr = smp_response;
7839 for (amt_written = 0; (amt_to_write > 0) &&
7840 (amt_written = write(STDOUT_FILENO, buf_ptr,
7841 amt_to_write)) > 0;){
7842 amt_to_write -= amt_written;
7843 buf_ptr += amt_written;
7845 if (amt_written == -1) {
7846 warn("error writing data to stdout");
7848 goto smpcmd_bailout;
7849 } else if ((amt_written == 0)
7850 && (amt_to_write > 0)) {
7851 warnx("only wrote %u bytes out of %u",
7852 response_size - amt_to_write,
7861 if (smp_request != NULL)
7864 if (smp_response != NULL)
7871 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7872 int retry_count, int timeout)
7876 int32_t mmc_opcode = 0, mmc_arg = 0;
7877 int32_t mmc_flags = -1;
7880 int is_bw_4 = 0, is_bw_1 = 0;
7881 int is_highspeed = 0, is_stdspeed = 0;
7882 int is_info_request = 0;
7884 uint8_t mmc_data_byte = 0;
7886 /* For IO_RW_EXTENDED command */
7887 uint8_t *mmc_data = NULL;
7888 struct mmc_data mmc_d;
7889 int mmc_data_len = 0;
7892 * Note that at the moment we don't support sending SMP CCBs to
7893 * devices that aren't probed by CAM.
7895 ccb = cam_getccb(device);
7897 warnx("%s: error allocating CCB", __func__);
7901 bzero(&(&ccb->ccb_h)[1],
7902 sizeof(union ccb) - sizeof(struct ccb_hdr));
7904 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7913 if (!strcmp(optarg, "high"))
7919 is_info_request = 1;
7922 mmc_opcode = strtol(optarg, NULL, 0);
7923 if (mmc_opcode < 0) {
7924 warnx("invalid MMC opcode %d",
7927 goto mmccmd_bailout;
7931 mmc_arg = strtol(optarg, NULL, 0);
7933 warnx("invalid MMC arg %d",
7936 goto mmccmd_bailout;
7940 mmc_flags = strtol(optarg, NULL, 0);
7941 if (mmc_flags < 0) {
7942 warnx("invalid MMC flags %d",
7945 goto mmccmd_bailout;
7949 mmc_data_len = strtol(optarg, NULL, 0);
7950 if (mmc_data_len <= 0) {
7951 warnx("invalid MMC data len %d",
7954 goto mmccmd_bailout;
7961 mmc_data_byte = strtol(optarg, NULL, 0);
7967 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7969 /* If flags are left default, supply the right flags */
7971 switch (mmc_opcode) {
7972 case MMC_GO_IDLE_STATE:
7973 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7975 case IO_SEND_OP_COND:
7976 mmc_flags = MMC_RSP_R4;
7978 case SD_SEND_RELATIVE_ADDR:
7979 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7981 case MMC_SELECT_CARD:
7982 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7983 mmc_arg = mmc_arg << 16;
7985 case SD_IO_RW_DIRECT:
7986 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7987 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7989 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7991 case SD_IO_RW_EXTENDED:
7992 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7993 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7994 int len_arg = mmc_data_len;
7995 if (mmc_data_len == 512)
7999 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
8001 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
8004 mmc_flags = MMC_RSP_R1;
8008 // Switch bus width instead of sending IO command
8009 if (is_bw_4 || is_bw_1) {
8010 struct ccb_trans_settings_mmc *cts;
8011 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
8012 ccb->ccb_h.flags = 0;
8013 cts = &ccb->cts.proto_specific.mmc;
8014 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
8015 cts->ios_valid = MMC_BW;
8016 if (((retval = cam_send_ccb(device, ccb)) < 0)
8017 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8018 warn("Error sending command");
8020 printf("Parameters set OK\n");
8026 // Switch bus speed instead of sending IO command
8027 if (is_stdspeed || is_highspeed) {
8028 struct ccb_trans_settings_mmc *cts;
8029 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
8030 ccb->ccb_h.flags = 0;
8031 cts = &ccb->cts.proto_specific.mmc;
8032 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
8033 cts->ios_valid = MMC_BT;
8034 if (((retval = cam_send_ccb(device, ccb)) < 0)
8035 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8036 warn("Error sending command");
8038 printf("Speed set OK (HS: %d)\n", is_highspeed);
8044 // Get information about controller and its settings
8045 if (is_info_request) {
8046 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
8047 ccb->ccb_h.flags = 0;
8048 struct ccb_trans_settings_mmc *cts;
8049 cts = &ccb->cts.proto_specific.mmc;
8050 if (((retval = cam_send_ccb(device, ccb)) < 0)
8051 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8052 warn("Error sending command");
8055 printf("Host controller information\n");
8056 printf("Host OCR: 0x%x\n", cts->host_ocr);
8057 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
8058 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
8059 printf("Supported bus width: ");
8060 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
8062 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
8064 printf("\nCurrent settings:\n");
8065 printf("Bus width: ");
8066 switch (cts->ios.bus_width) {
8077 printf("Freq: %d.%03d MHz%s\n",
8078 cts->ios.clock / 1000000,
8079 (cts->ios.clock / 1000) % 1000,
8080 cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : "");
8084 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
8086 if (mmc_data_len > 0) {
8087 flags |= CAM_DIR_IN;
8088 mmc_data = malloc(mmc_data_len);
8089 memset(mmc_data, 0, mmc_data_len);
8090 mmc_d.len = mmc_data_len;
8091 mmc_d.data = mmc_data;
8092 mmc_d.flags = MMC_DATA_READ;
8093 } else flags |= CAM_DIR_NONE;
8095 cam_fill_mmcio(&ccb->mmcio,
8096 /*retries*/ retry_count,
8099 /*mmc_opcode*/ mmc_opcode,
8100 /*mmc_arg*/ mmc_arg,
8101 /*mmc_flags*/ mmc_flags,
8102 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
8103 /*timeout*/ timeout ? timeout : 5000);
8105 if (((retval = cam_send_ccb(device, ccb)) < 0)
8106 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8107 const char warnstr[] = "error sending command";
8114 if (arglist & CAM_ARG_VERBOSE) {
8115 cam_error_print(device, ccb, CAM_ESF_ALL,
8116 CAM_EPF_ALL, stderr);
8120 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
8121 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
8122 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
8123 ccb->mmcio.cmd.resp[1],
8124 ccb->mmcio.cmd.resp[2],
8125 ccb->mmcio.cmd.resp[3]);
8127 switch (mmc_opcode) {
8128 case SD_IO_RW_DIRECT:
8129 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
8130 SD_R5_DATA(ccb->mmcio.cmd.resp),
8131 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
8133 case SD_IO_RW_EXTENDED:
8134 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
8135 hexdump(mmc_data, mmc_data_len, NULL, 0);
8137 case SD_SEND_RELATIVE_ADDR:
8138 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
8141 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
8148 if (mmc_data_len > 0 && mmc_data != NULL)
8155 smpreportgeneral(struct cam_device *device, int argc, char **argv,
8156 char *combinedopt, int retry_count, int timeout)
8159 struct smp_report_general_request *request = NULL;
8160 struct smp_report_general_response *response = NULL;
8161 struct sbuf *sb = NULL;
8163 int c, long_response = 0;
8167 * Note that at the moment we don't support sending SMP CCBs to
8168 * devices that aren't probed by CAM.
8170 ccb = cam_getccb(device);
8172 warnx("%s: error allocating CCB", __func__);
8176 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8178 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8187 request = malloc(sizeof(*request));
8188 if (request == NULL) {
8189 warn("%s: unable to allocate %zd bytes", __func__,
8195 response = malloc(sizeof(*response));
8196 if (response == NULL) {
8197 warn("%s: unable to allocate %zd bytes", __func__,
8204 smp_report_general(&ccb->smpio,
8208 /*request_len*/ sizeof(*request),
8209 (uint8_t *)response,
8210 /*response_len*/ sizeof(*response),
8211 /*long_response*/ long_response,
8214 if (((retval = cam_send_ccb(device, ccb)) < 0)
8215 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8216 const char warnstr[] = "error sending command";
8223 if (arglist & CAM_ARG_VERBOSE) {
8224 cam_error_print(device, ccb, CAM_ESF_ALL,
8225 CAM_EPF_ALL, stderr);
8232 * If the device supports the long response bit, try again and see
8233 * if we can get all of the data.
8235 if ((response->long_response & SMP_RG_LONG_RESPONSE)
8236 && (long_response == 0)) {
8237 ccb->ccb_h.status = CAM_REQ_INPROG;
8238 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8244 * XXX KDM detect and decode SMP errors here.
8246 sb = sbuf_new_auto();
8248 warnx("%s: error allocating sbuf", __func__);
8252 smp_report_general_sbuf(response, sizeof(*response), sb);
8254 if (sbuf_finish(sb) != 0) {
8255 warnx("%s: sbuf_finish", __func__);
8259 printf("%s", sbuf_data(sb));
8265 if (request != NULL)
8268 if (response != NULL)
8277 static struct camcontrol_opts phy_ops[] = {
8278 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
8279 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
8280 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
8281 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
8282 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
8283 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
8284 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
8285 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
8286 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
8291 smpphycontrol(struct cam_device *device, int argc, char **argv,
8292 char *combinedopt, int retry_count, int timeout)
8295 struct smp_phy_control_request *request = NULL;
8296 struct smp_phy_control_response *response = NULL;
8297 int long_response = 0;
8300 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
8302 uint64_t attached_dev_name = 0;
8303 int dev_name_set = 0;
8304 uint32_t min_plr = 0, max_plr = 0;
8305 uint32_t pp_timeout_val = 0;
8306 int slumber_partial = 0;
8307 int set_pp_timeout_val = 0;
8311 * Note that at the moment we don't support sending SMP CCBs to
8312 * devices that aren't probed by CAM.
8314 ccb = cam_getccb(device);
8316 warnx("%s: error allocating CCB", __func__);
8320 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8322 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8330 if (strcasecmp(optarg, "enable") == 0)
8332 else if (strcasecmp(optarg, "disable") == 0)
8335 warnx("%s: Invalid argument %s", __func__,
8342 slumber_partial |= enable <<
8343 SMP_PC_SAS_SLUMBER_SHIFT;
8346 slumber_partial |= enable <<
8347 SMP_PC_SAS_PARTIAL_SHIFT;
8350 slumber_partial |= enable <<
8351 SMP_PC_SATA_SLUMBER_SHIFT;
8354 slumber_partial |= enable <<
8355 SMP_PC_SATA_PARTIAL_SHIFT;
8358 warnx("%s: programmer error", __func__);
8361 break; /*NOTREACHED*/
8366 attached_dev_name = (uintmax_t)strtoumax(optarg,
8375 * We don't do extensive checking here, so this
8376 * will continue to work when new speeds come out.
8378 min_plr = strtoul(optarg, NULL, 0);
8380 || (min_plr > 0xf)) {
8381 warnx("%s: invalid link rate %x",
8389 * We don't do extensive checking here, so this
8390 * will continue to work when new speeds come out.
8392 max_plr = strtoul(optarg, NULL, 0);
8394 || (max_plr > 0xf)) {
8395 warnx("%s: invalid link rate %x",
8402 camcontrol_optret optreturn;
8403 cam_argmask argnums;
8406 if (phy_op_set != 0) {
8407 warnx("%s: only one phy operation argument "
8408 "(-o) allowed", __func__);
8416 * Allow the user to specify the phy operation
8417 * numerically, as well as with a name. This will
8418 * future-proof it a bit, so options that are added
8419 * in future specs can be used.
8421 if (isdigit(optarg[0])) {
8422 phy_operation = strtoul(optarg, NULL, 0);
8423 if ((phy_operation == 0)
8424 || (phy_operation > 0xff)) {
8425 warnx("%s: invalid phy operation %#x",
8426 __func__, phy_operation);
8432 optreturn = getoption(phy_ops, optarg, &phy_operation,
8435 if (optreturn == CC_OR_AMBIGUOUS) {
8436 warnx("%s: ambiguous option %s", __func__,
8441 } else if (optreturn == CC_OR_NOT_FOUND) {
8442 warnx("%s: option %s not found", __func__,
8454 pp_timeout_val = strtoul(optarg, NULL, 0);
8455 if (pp_timeout_val > 15) {
8456 warnx("%s: invalid partial pathway timeout "
8457 "value %u, need a value less than 16",
8458 __func__, pp_timeout_val);
8462 set_pp_timeout_val = 1;
8470 warnx("%s: a PHY (-p phy) argument is required",__func__);
8475 if (((dev_name_set != 0)
8476 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8477 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8478 && (dev_name_set == 0))) {
8479 warnx("%s: -d name and -o setdevname arguments both "
8480 "required to set device name", __func__);
8485 request = malloc(sizeof(*request));
8486 if (request == NULL) {
8487 warn("%s: unable to allocate %zd bytes", __func__,
8493 response = malloc(sizeof(*response));
8494 if (response == NULL) {
8495 warn("%s: unable to allocate %zd bytes", __func__,
8501 smp_phy_control(&ccb->smpio,
8506 (uint8_t *)response,
8509 /*expected_exp_change_count*/ 0,
8512 (set_pp_timeout_val != 0) ? 1 : 0,
8520 if (((retval = cam_send_ccb(device, ccb)) < 0)
8521 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8522 const char warnstr[] = "error sending command";
8529 if (arglist & CAM_ARG_VERBOSE) {
8531 * Use CAM_EPF_NORMAL so we only get one line of
8532 * SMP command decoding.
8534 cam_error_print(device, ccb, CAM_ESF_ALL,
8535 CAM_EPF_NORMAL, stderr);
8541 /* XXX KDM print out something here for success? */
8546 if (request != NULL)
8549 if (response != NULL)
8556 smpmaninfo(struct cam_device *device, int argc, char **argv,
8557 char *combinedopt, int retry_count, int timeout)
8560 struct smp_report_manuf_info_request request;
8561 struct smp_report_manuf_info_response response;
8562 struct sbuf *sb = NULL;
8563 int long_response = 0;
8568 * Note that at the moment we don't support sending SMP CCBs to
8569 * devices that aren't probed by CAM.
8571 ccb = cam_getccb(device);
8573 warnx("%s: error allocating CCB", __func__);
8577 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8579 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8588 bzero(&request, sizeof(request));
8589 bzero(&response, sizeof(response));
8591 smp_report_manuf_info(&ccb->smpio,
8596 (uint8_t *)&response,
8601 if (((retval = cam_send_ccb(device, ccb)) < 0)
8602 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8603 const char warnstr[] = "error sending command";
8610 if (arglist & CAM_ARG_VERBOSE) {
8611 cam_error_print(device, ccb, CAM_ESF_ALL,
8612 CAM_EPF_ALL, stderr);
8618 sb = sbuf_new_auto();
8620 warnx("%s: error allocating sbuf", __func__);
8624 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8626 if (sbuf_finish(sb) != 0) {
8627 warnx("%s: sbuf_finish", __func__);
8631 printf("%s", sbuf_data(sb));
8645 getdevid(struct cam_devitem *item)
8648 union ccb *ccb = NULL;
8650 struct cam_device *dev;
8652 dev = cam_open_btl(item->dev_match.path_id,
8653 item->dev_match.target_id,
8654 item->dev_match.target_lun, O_RDWR, NULL);
8657 warnx("%s", cam_errbuf);
8662 item->device_id_len = 0;
8664 ccb = cam_getccb(dev);
8666 warnx("%s: error allocating CCB", __func__);
8671 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8674 * On the first try, we just probe for the size of the data, and
8675 * then allocate that much memory and try again.
8678 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8679 ccb->ccb_h.flags = CAM_DIR_IN;
8680 ccb->cdai.flags = CDAI_FLAG_NONE;
8681 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8682 ccb->cdai.bufsiz = item->device_id_len;
8683 if (item->device_id_len != 0)
8684 ccb->cdai.buf = (uint8_t *)item->device_id;
8686 if (cam_send_ccb(dev, ccb) < 0) {
8687 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8692 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8693 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8698 if (item->device_id_len == 0) {
8700 * This is our first time through. Allocate the buffer,
8701 * and then go back to get the data.
8703 if (ccb->cdai.provsiz == 0) {
8704 warnx("%s: invalid .provsiz field returned with "
8705 "XPT_GDEV_ADVINFO CCB", __func__);
8709 item->device_id_len = ccb->cdai.provsiz;
8710 item->device_id = malloc(item->device_id_len);
8711 if (item->device_id == NULL) {
8712 warn("%s: unable to allocate %d bytes", __func__,
8713 item->device_id_len);
8717 ccb->ccb_h.status = CAM_REQ_INPROG;
8723 cam_close_device(dev);
8732 * XXX KDM merge this code with getdevtree()?
8735 buildbusdevlist(struct cam_devlist *devlist)
8738 int bufsize, fd = -1;
8739 struct dev_match_pattern *patterns;
8740 struct cam_devitem *item = NULL;
8741 int skip_device = 0;
8744 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8745 warn("couldn't open %s", XPT_DEVICE);
8749 bzero(&ccb, sizeof(union ccb));
8751 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8752 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8753 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8755 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8756 bufsize = sizeof(struct dev_match_result) * 100;
8757 ccb.cdm.match_buf_len = bufsize;
8758 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8759 if (ccb.cdm.matches == NULL) {
8760 warnx("can't malloc memory for matches");
8764 ccb.cdm.num_matches = 0;
8765 ccb.cdm.num_patterns = 2;
8766 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8767 ccb.cdm.num_patterns;
8769 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8770 if (patterns == NULL) {
8771 warnx("can't malloc memory for patterns");
8776 ccb.cdm.patterns = patterns;
8777 bzero(patterns, ccb.cdm.pattern_buf_len);
8779 patterns[0].type = DEV_MATCH_DEVICE;
8780 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8781 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8782 patterns[1].type = DEV_MATCH_PERIPH;
8783 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8784 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8787 * We do the ioctl multiple times if necessary, in case there are
8788 * more than 100 nodes in the EDT.
8793 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8794 warn("error sending CAMIOCOMMAND ioctl");
8799 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8800 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8801 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8802 warnx("got CAM error %#x, CDM error %d\n",
8803 ccb.ccb_h.status, ccb.cdm.status);
8808 for (i = 0; i < ccb.cdm.num_matches; i++) {
8809 switch (ccb.cdm.matches[i].type) {
8810 case DEV_MATCH_DEVICE: {
8811 struct device_match_result *dev_result;
8814 &ccb.cdm.matches[i].result.device_result;
8816 if (dev_result->flags &
8817 DEV_RESULT_UNCONFIGURED) {
8823 item = malloc(sizeof(*item));
8825 warn("%s: unable to allocate %zd bytes",
8826 __func__, sizeof(*item));
8830 bzero(item, sizeof(*item));
8831 bcopy(dev_result, &item->dev_match,
8832 sizeof(*dev_result));
8833 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8836 if (getdevid(item) != 0) {
8842 case DEV_MATCH_PERIPH: {
8843 struct periph_match_result *periph_result;
8846 &ccb.cdm.matches[i].result.periph_result;
8848 if (skip_device != 0)
8850 item->num_periphs++;
8851 item->periph_matches = realloc(
8852 item->periph_matches,
8854 sizeof(struct periph_match_result));
8855 if (item->periph_matches == NULL) {
8856 warn("%s: error allocating periph "
8861 bcopy(periph_result, &item->periph_matches[
8862 item->num_periphs - 1],
8863 sizeof(*periph_result));
8867 fprintf(stderr, "%s: unexpected match "
8868 "type %d\n", __func__,
8869 ccb.cdm.matches[i].type);
8872 break; /*NOTREACHED*/
8875 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8876 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8884 free(ccb.cdm.matches);
8887 freebusdevlist(devlist);
8893 freebusdevlist(struct cam_devlist *devlist)
8895 struct cam_devitem *item, *item2;
8897 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8898 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8900 free(item->device_id);
8901 free(item->periph_matches);
8906 static struct cam_devitem *
8907 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8909 struct cam_devitem *item;
8911 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8912 struct scsi_vpd_id_descriptor *idd;
8915 * XXX KDM look for LUN IDs as well?
8917 idd = scsi_get_devid(item->device_id,
8918 item->device_id_len,
8919 scsi_devid_is_sas_target);
8923 if (scsi_8btou64(idd->identifier) == sasaddr)
8931 smpphylist(struct cam_device *device, int argc, char **argv,
8932 char *combinedopt, int retry_count, int timeout)
8934 struct smp_report_general_request *rgrequest = NULL;
8935 struct smp_report_general_response *rgresponse = NULL;
8936 struct smp_discover_request *disrequest = NULL;
8937 struct smp_discover_response *disresponse = NULL;
8938 struct cam_devlist devlist;
8940 int long_response = 0;
8947 * Note that at the moment we don't support sending SMP CCBs to
8948 * devices that aren't probed by CAM.
8950 ccb = cam_getccb(device);
8952 warnx("%s: error allocating CCB", __func__);
8956 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8957 STAILQ_INIT(&devlist.dev_queue);
8959 rgrequest = malloc(sizeof(*rgrequest));
8960 if (rgrequest == NULL) {
8961 warn("%s: unable to allocate %zd bytes", __func__,
8962 sizeof(*rgrequest));
8967 rgresponse = malloc(sizeof(*rgresponse));
8968 if (rgresponse == NULL) {
8969 warn("%s: unable to allocate %zd bytes", __func__,
8970 sizeof(*rgresponse));
8975 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8988 smp_report_general(&ccb->smpio,
8992 /*request_len*/ sizeof(*rgrequest),
8993 (uint8_t *)rgresponse,
8994 /*response_len*/ sizeof(*rgresponse),
8995 /*long_response*/ long_response,
8998 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9000 if (((retval = cam_send_ccb(device, ccb)) < 0)
9001 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
9002 const char warnstr[] = "error sending command";
9009 if (arglist & CAM_ARG_VERBOSE) {
9010 cam_error_print(device, ccb, CAM_ESF_ALL,
9011 CAM_EPF_ALL, stderr);
9017 num_phys = rgresponse->num_phys;
9019 if (num_phys == 0) {
9021 fprintf(stdout, "%s: No Phys reported\n", __func__);
9026 devlist.path_id = device->path_id;
9028 retval = buildbusdevlist(&devlist);
9033 fprintf(stdout, "%d PHYs:\n", num_phys);
9034 fprintf(stdout, "PHY Attached SAS Address\n");
9037 disrequest = malloc(sizeof(*disrequest));
9038 if (disrequest == NULL) {
9039 warn("%s: unable to allocate %zd bytes", __func__,
9040 sizeof(*disrequest));
9045 disresponse = malloc(sizeof(*disresponse));
9046 if (disresponse == NULL) {
9047 warn("%s: unable to allocate %zd bytes", __func__,
9048 sizeof(*disresponse));
9053 for (i = 0; i < num_phys; i++) {
9054 struct cam_devitem *item;
9055 struct device_match_result *dev_match;
9056 char vendor[16], product[48], revision[16];
9060 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
9062 ccb->ccb_h.status = CAM_REQ_INPROG;
9063 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9065 smp_discover(&ccb->smpio,
9069 sizeof(*disrequest),
9070 (uint8_t *)disresponse,
9071 sizeof(*disresponse),
9073 /*ignore_zone_group*/ 0,
9077 if (((retval = cam_send_ccb(device, ccb)) < 0)
9078 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
9079 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
9080 const char warnstr[] = "error sending command";
9087 if (arglist & CAM_ARG_VERBOSE) {
9088 cam_error_print(device, ccb, CAM_ESF_ALL,
9089 CAM_EPF_ALL, stderr);
9095 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
9097 fprintf(stdout, "%3d <vacant>\n", i);
9101 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
9104 item = findsasdevice(&devlist,
9105 scsi_8btou64(disresponse->attached_sas_address));
9109 || (item != NULL)) {
9110 fprintf(stdout, "%3d 0x%016jx", i,
9111 (uintmax_t)scsi_8btou64(
9112 disresponse->attached_sas_address));
9114 fprintf(stdout, "\n");
9117 } else if (quiet != 0)
9120 dev_match = &item->dev_match;
9122 if (dev_match->protocol == PROTO_SCSI) {
9123 cam_strvis(vendor, dev_match->inq_data.vendor,
9124 sizeof(dev_match->inq_data.vendor),
9126 cam_strvis(product, dev_match->inq_data.product,
9127 sizeof(dev_match->inq_data.product),
9129 cam_strvis(revision, dev_match->inq_data.revision,
9130 sizeof(dev_match->inq_data.revision),
9132 sprintf(tmpstr, "<%s %s %s>", vendor, product,
9134 } else if ((dev_match->protocol == PROTO_ATA)
9135 || (dev_match->protocol == PROTO_SATAPM)) {
9136 cam_strvis(product, dev_match->ident_data.model,
9137 sizeof(dev_match->ident_data.model),
9139 cam_strvis(revision, dev_match->ident_data.revision,
9140 sizeof(dev_match->ident_data.revision),
9142 sprintf(tmpstr, "<%s %s>", product, revision);
9144 sprintf(tmpstr, "<>");
9146 fprintf(stdout, " %-33s ", tmpstr);
9149 * If we have 0 periphs, that's a bug...
9151 if (item->num_periphs == 0) {
9152 fprintf(stdout, "\n");
9156 fprintf(stdout, "(");
9157 for (j = 0; j < item->num_periphs; j++) {
9159 fprintf(stdout, ",");
9161 fprintf(stdout, "%s%d",
9162 item->periph_matches[j].periph_name,
9163 item->periph_matches[j].unit_number);
9166 fprintf(stdout, ")\n");
9180 freebusdevlist(&devlist);
9186 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
9188 struct ata_res *res;
9190 res = &ccb->ataio.res;
9191 if (res->status & ATA_STATUS_ERROR) {
9192 if (arglist & CAM_ARG_VERBOSE) {
9193 cam_error_print(device, ccb, CAM_ESF_ALL,
9194 CAM_EPF_ALL, stderr);
9195 printf("error = 0x%02x, sector_count = 0x%04x, "
9196 "device = 0x%02x, status = 0x%02x\n",
9197 res->error, res->sector_count,
9198 res->device, res->status);
9204 if (arglist & CAM_ARG_VERBOSE) {
9205 fprintf(stdout, "%s%d: Raw native check power data:\n",
9206 device->device_name, device->dev_unit_num);
9207 /* res is 4 byte aligned */
9208 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
9210 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
9211 "status = 0x%02x\n", res->error, res->sector_count,
9212 res->device, res->status);
9215 printf("%s%d: ", device->device_name, device->dev_unit_num);
9216 switch (res->sector_count) {
9218 printf("Standby mode\n");
9221 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
9224 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
9227 printf("Idle mode\n");
9230 printf("Active or Idle mode\n");
9233 printf("Unknown mode 0x%02x\n", res->sector_count);
9241 atapm(struct cam_device *device, int argc, char **argv,
9242 char *combinedopt, int retry_count, int timeout)
9248 u_int8_t ata_flags = 0;
9251 ccb = cam_getccb(device);
9254 warnx("%s: error allocating ccb", __func__);
9258 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9267 if (strcmp(argv[1], "idle") == 0) {
9269 cmd = ATA_IDLE_IMMEDIATE;
9272 } else if (strcmp(argv[1], "standby") == 0) {
9274 cmd = ATA_STANDBY_IMMEDIATE;
9276 cmd = ATA_STANDBY_CMD;
9277 } else if (strcmp(argv[1], "powermode") == 0) {
9278 cmd = ATA_CHECK_POWER_MODE;
9279 ata_flags = AP_FLAG_CHK_COND;
9288 else if (t <= (240 * 5))
9290 else if (t <= (252 * 5))
9291 /* special encoding for 21 minutes */
9293 else if (t <= (11 * 30 * 60))
9294 sc = (t - 1) / (30 * 60) + 241;
9298 retval = ata_do_cmd(device,
9300 /*retries*/retry_count,
9301 /*flags*/CAM_DIR_NONE,
9302 /*protocol*/AP_PROTO_NON_DATA,
9303 /*ata_flags*/ata_flags,
9304 /*tag_action*/MSG_SIMPLE_Q_TAG,
9311 /*timeout*/timeout ? timeout : 30 * 1000,
9316 if (retval || cmd != ATA_CHECK_POWER_MODE)
9319 return (atapm_proc_resp(device, ccb));
9323 ataaxm(struct cam_device *device, int argc, char **argv,
9324 char *combinedopt, int retry_count, int timeout)
9332 ccb = cam_getccb(device);
9335 warnx("%s: error allocating ccb", __func__);
9339 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9349 if (strcmp(argv[1], "apm") == 0) {
9365 retval = ata_do_28bit_cmd(device,
9367 /*retries*/retry_count,
9368 /*flags*/CAM_DIR_NONE,
9369 /*protocol*/AP_PROTO_NON_DATA,
9370 /*tag_action*/MSG_SIMPLE_Q_TAG,
9371 /*command*/ATA_SETFEATURES,
9377 /*timeout*/timeout ? timeout : 30 * 1000,
9385 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9386 int show_sa_errors, int sa_set, int service_action,
9387 int timeout_desc, int task_attr, int retry_count, int timeout,
9388 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9390 union ccb *ccb = NULL;
9391 uint8_t *buf = NULL;
9392 uint32_t alloc_len = 0, num_opcodes;
9393 uint32_t valid_len = 0;
9394 uint32_t avail_len = 0;
9395 struct scsi_report_supported_opcodes_all *all_hdr;
9396 struct scsi_report_supported_opcodes_one *one;
9401 * Make it clear that we haven't yet allocated or filled anything.
9406 ccb = cam_getccb(device);
9408 warnx("couldn't allocate CCB");
9413 /* cam_getccb cleans up the header, caller has to zero the payload */
9414 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9416 if (opcode_set != 0) {
9417 options |= RSO_OPTIONS_OC;
9419 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9422 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9423 sizeof(struct scsi_report_supported_opcodes_descr));
9426 if (timeout_desc != 0) {
9427 options |= RSO_RCTD;
9428 alloc_len += num_opcodes *
9429 sizeof(struct scsi_report_supported_opcodes_timeout);
9433 options |= RSO_OPTIONS_OC_SA;
9434 if (show_sa_errors != 0)
9435 options &= ~RSO_OPTIONS_OC;
9444 buf = malloc(alloc_len);
9446 warn("Unable to allocate %u bytes", alloc_len);
9450 bzero(buf, alloc_len);
9452 scsi_report_supported_opcodes(&ccb->csio,
9453 /*retries*/ retry_count,
9455 /*tag_action*/ task_attr,
9456 /*options*/ options,
9457 /*req_opcode*/ opcode,
9458 /*req_service_action*/ service_action,
9460 /*dxfer_len*/ alloc_len,
9461 /*sense_len*/ SSD_FULL_SIZE,
9462 /*timeout*/ timeout ? timeout : 10000);
9464 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9466 if (retry_count != 0)
9467 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9469 if (cam_send_ccb(device, ccb) < 0) {
9470 perror("error sending REPORT SUPPORTED OPERATION CODES");
9475 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9476 if (verbosemode != 0)
9477 cam_error_print(device, ccb, CAM_ESF_ALL,
9478 CAM_EPF_ALL, stderr);
9483 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9485 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9486 && (valid_len >= sizeof(*all_hdr))) {
9487 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9488 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9489 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9490 && (valid_len >= sizeof(*one))) {
9491 uint32_t cdb_length;
9493 one = (struct scsi_report_supported_opcodes_one *)buf;
9494 cdb_length = scsi_2btoul(one->cdb_length);
9495 avail_len = sizeof(*one) + cdb_length;
9496 if (one->support & RSO_ONE_CTDP) {
9497 struct scsi_report_supported_opcodes_timeout *td;
9499 td = (struct scsi_report_supported_opcodes_timeout *)
9501 if (valid_len >= (avail_len + sizeof(td->length))) {
9502 avail_len += scsi_2btoul(td->length) +
9505 avail_len += sizeof(*td);
9511 * avail_len could be zero if we didn't get enough data back from
9512 * thet target to determine
9514 if ((avail_len != 0)
9515 && (avail_len > valid_len)) {
9516 alloc_len = avail_len;
9520 *fill_len = valid_len;
9532 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9533 int req_sa, uint8_t *buf, uint32_t valid_len)
9535 struct scsi_report_supported_opcodes_one *one;
9536 struct scsi_report_supported_opcodes_timeout *td;
9537 uint32_t cdb_len = 0, td_len = 0;
9538 const char *op_desc = NULL;
9542 one = (struct scsi_report_supported_opcodes_one *)buf;
9545 * If we don't have the full single opcode descriptor, no point in
9548 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9550 warnx("Only %u bytes returned, not enough to verify support",
9556 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9558 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9561 printf(", SA 0x%x", req_sa);
9564 switch (one->support & RSO_ONE_SUP_MASK) {
9565 case RSO_ONE_SUP_UNAVAIL:
9566 printf("No command support information currently available\n");
9568 case RSO_ONE_SUP_NOT_SUP:
9569 printf("Command not supported\n");
9572 break; /*NOTREACHED*/
9573 case RSO_ONE_SUP_AVAIL:
9574 printf("Command is supported, complies with a SCSI standard\n");
9576 case RSO_ONE_SUP_VENDOR:
9577 printf("Command is supported, vendor-specific "
9578 "implementation\n");
9581 printf("Unknown command support flags 0x%#x\n",
9582 one->support & RSO_ONE_SUP_MASK);
9587 * If we don't have the CDB length, it isn't exactly an error, the
9588 * command probably isn't supported.
9590 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9594 cdb_len = scsi_2btoul(one->cdb_length);
9597 * If our valid data doesn't include the full reported length,
9598 * return. The caller should have detected this and adjusted his
9599 * allocation length to get all of the available data.
9601 if (valid_len < sizeof(*one) + cdb_len) {
9607 * If all we have is the opcode, there is no point in printing out
9615 printf("CDB usage bitmap:");
9616 for (i = 0; i < cdb_len; i++) {
9617 printf(" %02x", one->cdb_usage[i]);
9622 * If we don't have a timeout descriptor, we're done.
9624 if ((one->support & RSO_ONE_CTDP) == 0)
9628 * If we don't have enough valid length to include the timeout
9629 * descriptor length, we're done.
9631 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9634 td = (struct scsi_report_supported_opcodes_timeout *)
9635 &buf[sizeof(*one) + cdb_len];
9636 td_len = scsi_2btoul(td->length);
9637 td_len += sizeof(td->length);
9640 * If we don't have the full timeout descriptor, we're done.
9642 if (td_len < sizeof(*td))
9646 * If we don't have enough valid length to contain the full timeout
9647 * descriptor, we're done.
9649 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9652 printf("Timeout information:\n");
9653 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9654 printf("Nominal timeout: %u seconds\n",
9655 scsi_4btoul(td->nominal_time));
9656 printf("Recommended timeout: %u seconds\n",
9657 scsi_4btoul(td->recommended_time));
9664 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9667 struct scsi_report_supported_opcodes_all *hdr;
9668 struct scsi_report_supported_opcodes_descr *desc;
9669 uint32_t avail_len = 0, used_len = 0;
9673 if (valid_len < sizeof(*hdr)) {
9674 warnx("%s: not enough returned data (%u bytes) opcode list",
9675 __func__, valid_len);
9679 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9680 avail_len = scsi_4btoul(hdr->length);
9681 avail_len += sizeof(hdr->length);
9683 * Take the lesser of the amount of data the drive claims is
9684 * available, and the amount of data the HBA says was returned.
9686 avail_len = MIN(avail_len, valid_len);
9688 used_len = sizeof(hdr->length);
9690 printf("%-6s %4s %8s ",
9691 "Opcode", "SA", "CDB len" );
9694 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9695 printf(" Description\n");
9697 while ((avail_len - used_len) > sizeof(*desc)) {
9698 struct scsi_report_supported_opcodes_timeout *td;
9700 const char *op_desc = NULL;
9702 cur_ptr = &buf[used_len];
9703 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9705 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9706 if (op_desc == NULL)
9707 op_desc = "UNKNOWN";
9709 printf("0x%02x %#4x %8u ", desc->opcode,
9710 scsi_2btoul(desc->service_action),
9711 scsi_2btoul(desc->cdb_length));
9713 used_len += sizeof(*desc);
9715 if ((desc->flags & RSO_CTDP) == 0) {
9716 printf(" %s\n", op_desc);
9721 * If we don't have enough space to fit a timeout
9722 * descriptor, then we're done.
9724 if (avail_len - used_len < sizeof(*td)) {
9725 used_len = avail_len;
9726 printf(" %s\n", op_desc);
9729 cur_ptr = &buf[used_len];
9730 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9731 td_len = scsi_2btoul(td->length);
9732 td_len += sizeof(td->length);
9736 * If the given timeout descriptor length is less than what
9737 * we understand, skip it.
9739 if (td_len < sizeof(*td)) {
9740 printf(" %s\n", op_desc);
9744 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9745 scsi_4btoul(td->nominal_time),
9746 scsi_4btoul(td->recommended_time), op_desc);
9753 scsiopcodes(struct cam_device *device, int argc, char **argv,
9754 char *combinedopt, int task_attr, int retry_count, int timeout,
9758 uint32_t opcode = 0, service_action = 0;
9759 int td_set = 0, opcode_set = 0, sa_set = 0;
9760 int show_sa_errors = 1;
9761 uint32_t valid_len = 0;
9762 uint8_t *buf = NULL;
9766 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9772 opcode = strtoul(optarg, &endptr, 0);
9773 if (*endptr != '\0') {
9774 warnx("Invalid opcode \"%s\", must be a number",
9779 if (opcode > 0xff) {
9780 warnx("Invalid opcode 0x%#x, must be between"
9781 "0 and 0xff inclusive", opcode);
9788 service_action = strtoul(optarg, &endptr, 0);
9789 if (*endptr != '\0') {
9790 warnx("Invalid service action \"%s\", must "
9791 "be a number", optarg);
9795 if (service_action > 0xffff) {
9796 warnx("Invalid service action 0x%#x, must "
9797 "be between 0 and 0xffff inclusive",
9812 && (opcode_set == 0)) {
9813 warnx("You must specify an opcode with -o if a service "
9818 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9819 sa_set, service_action, td_set, task_attr,
9820 retry_count, timeout, verbosemode, &valid_len,
9825 if ((opcode_set != 0)
9827 retval = scsiprintoneopcode(device, opcode, sa_set,
9828 service_action, buf, valid_len);
9830 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9839 #endif /* MINIMALISTIC */
9842 scsireprobe(struct cam_device *device)
9847 ccb = cam_getccb(device);
9850 warnx("%s: error allocating ccb", __func__);
9854 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9856 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9858 if (cam_send_ccb(device, ccb) < 0) {
9859 warn("error sending XPT_REPROBE_LUN CCB");
9864 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9865 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9877 usage(int printlong)
9880 fprintf(printlong ? stdout : stderr,
9881 "usage: camcontrol <command> [device id][generic args][command args]\n"
9882 " camcontrol devlist [-b] [-v]\n"
9883 #ifndef MINIMALISTIC
9884 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9885 " camcontrol tur [dev_id][generic args]\n"
9886 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9887 " camcontrol identify [dev_id][generic args] [-v]\n"
9888 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9889 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9891 " camcontrol start [dev_id][generic args]\n"
9892 " camcontrol stop [dev_id][generic args]\n"
9893 " camcontrol load [dev_id][generic args]\n"
9894 " camcontrol eject [dev_id][generic args]\n"
9895 " camcontrol reprobe [dev_id][generic args]\n"
9896 #endif /* MINIMALISTIC */
9897 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9898 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9899 #ifndef MINIMALISTIC
9900 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9901 " [-q][-s][-S offset][-X]\n"
9902 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9903 " [-P pagectl][-e | -b][-d]\n"
9904 " camcontrol cmd [dev_id][generic args]\n"
9905 " <-a cmd [args] | -c cmd [args]>\n"
9906 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9907 " camcontrol smpcmd [dev_id][generic args]\n"
9908 " <-r len fmt [args]> <-R len fmt [args]>\n"
9909 " camcontrol smprg [dev_id][generic args][-l]\n"
9910 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9911 " [-o operation][-d name][-m rate][-M rate]\n"
9912 " [-T pp_timeout][-a enable|disable]\n"
9913 " [-A enable|disable][-s enable|disable]\n"
9914 " [-S enable|disable]\n"
9915 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9916 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9917 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9918 " <all|bus[:target[:lun]]|off>\n"
9919 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9920 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9921 " [-D <enable|disable>][-M mode][-O offset]\n"
9922 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9923 " [-U][-W bus_width]\n"
9924 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9925 " camcontrol sanitize [dev_id][generic args]\n"
9926 " [-a overwrite|block|crypto|exitfailure]\n"
9927 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9929 " camcontrol idle [dev_id][generic args][-t time]\n"
9930 " camcontrol standby [dev_id][generic args][-t time]\n"
9931 " camcontrol sleep [dev_id][generic args]\n"
9932 " camcontrol powermode [dev_id][generic args]\n"
9933 " camcontrol apm [dev_id][generic args][-l level]\n"
9934 " camcontrol aam [dev_id][generic args][-l level]\n"
9935 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9937 " camcontrol security [dev_id][generic args]\n"
9938 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9939 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9940 " [-U <user|master>] [-y]\n"
9941 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9942 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9943 " camcontrol ama [dev_id][generic args] [-f] [-q] [-s max_sectors]\n"
9944 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9945 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9946 " [-s scope][-S][-T type][-U]\n"
9947 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9948 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9949 " [-p part][-s start][-T type][-V vol]\n"
9950 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9952 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9953 " [-o rep_opts] [-P print_opts]\n"
9954 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9955 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9956 " [-S power_src] [-T timer]\n"
9957 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9958 " <-s <-f format -T time | -U >>\n"
9959 " camcontrol devtype [dev_id]\n"
9961 #endif /* MINIMALISTIC */
9962 " camcontrol help\n");
9965 #ifndef MINIMALISTIC
9967 "Specify one of the following options:\n"
9968 "devlist list all CAM devices\n"
9969 "periphlist list all CAM peripheral drivers attached to a device\n"
9970 "tur send a test unit ready to the named device\n"
9971 "inquiry send a SCSI inquiry command to the named device\n"
9972 "identify send a ATA identify command to the named device\n"
9973 "reportluns send a SCSI report luns command to the device\n"
9974 "readcap send a SCSI read capacity command to the device\n"
9975 "start send a Start Unit command to the device\n"
9976 "stop send a Stop Unit command to the device\n"
9977 "load send a Start Unit command to the device with the load bit set\n"
9978 "eject send a Stop Unit command to the device with the eject bit set\n"
9979 "reprobe update capacity information of the given device\n"
9980 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9981 "reset reset all buses, the given bus, bus:target:lun or device\n"
9982 "defects read the defect list of the specified device\n"
9983 "modepage display or edit (-e) the given mode page\n"
9984 "cmd send the given SCSI command, may need -i or -o as well\n"
9985 "smpcmd send the given SMP command, requires -o and -i\n"
9986 "smprg send the SMP Report General command\n"
9987 "smppc send the SMP PHY Control command, requires -p\n"
9988 "smpphylist display phys attached to a SAS expander\n"
9989 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9990 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9991 "tags report or set the number of transaction slots for a device\n"
9992 "negotiate report or set device negotiation parameters\n"
9993 "format send the SCSI FORMAT UNIT command to the named device\n"
9994 "sanitize send the SCSI SANITIZE command to the named device\n"
9995 "idle send the ATA IDLE command to the named device\n"
9996 "standby send the ATA STANDBY command to the named device\n"
9997 "sleep send the ATA SLEEP command to the named device\n"
9998 "powermode send the ATA CHECK POWER MODE command to the named device\n"
9999 "fwdownload program firmware of the named device with the given image\n"
10000 "security report or send ATA security commands to the named device\n"
10001 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
10002 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
10003 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
10004 "zone manage Zoned Block (Shingled) devices\n"
10005 "epc send ATA Extended Power Conditions commands\n"
10006 "timestamp report or set the device's timestamp\n"
10007 "devtype report the type of device\n"
10008 "help this message\n"
10009 "Device Identifiers:\n"
10010 "bus:target specify the bus and target, lun defaults to 0\n"
10011 "bus:target:lun specify the bus, target and lun\n"
10012 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
10013 "Generic arguments:\n"
10014 "-v be verbose, print out sense information\n"
10015 "-t timeout command timeout in seconds, overrides default timeout\n"
10016 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
10017 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
10018 "-E have the kernel attempt to perform SCSI error recovery\n"
10019 "-C count specify the SCSI command retry count (needs -E to work)\n"
10020 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
10021 "modepage arguments:\n"
10022 "-l list all available mode pages\n"
10023 "-m page specify the mode page to view or edit\n"
10024 "-e edit the specified mode page\n"
10025 "-b force view to binary mode\n"
10026 "-d disable block descriptors for mode sense\n"
10027 "-P pgctl page control field 0-3\n"
10028 "defects arguments:\n"
10029 "-f format specify defect list format (block, bfi or phys)\n"
10030 "-G get the grown defect list\n"
10031 "-P get the permanent defect list\n"
10032 "inquiry arguments:\n"
10033 "-D get the standard inquiry data\n"
10034 "-S get the serial number\n"
10035 "-R get the transfer rate, etc.\n"
10036 "reportluns arguments:\n"
10037 "-c only report a count of available LUNs\n"
10038 "-l only print out luns, and not a count\n"
10039 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
10040 "readcap arguments\n"
10041 "-b only report the blocksize\n"
10042 "-h human readable device size, base 2\n"
10043 "-H human readable device size, base 10\n"
10044 "-N print the number of blocks instead of last block\n"
10045 "-q quiet, print numbers only\n"
10046 "-s only report the last block/device size\n"
10048 "-c cdb [args] specify the SCSI CDB\n"
10049 "-i len fmt specify input data and input data format\n"
10050 "-o len fmt [args] specify output data and output data fmt\n"
10051 "smpcmd arguments:\n"
10052 "-r len fmt [args] specify the SMP command to be sent\n"
10053 "-R len fmt [args] specify SMP response format\n"
10054 "smprg arguments:\n"
10055 "-l specify the long response format\n"
10056 "smppc arguments:\n"
10057 "-p phy specify the PHY to operate on\n"
10058 "-l specify the long request/response format\n"
10059 "-o operation specify the phy control operation\n"
10060 "-d name set the attached device name\n"
10061 "-m rate set the minimum physical link rate\n"
10062 "-M rate set the maximum physical link rate\n"
10063 "-T pp_timeout set the partial pathway timeout value\n"
10064 "-a enable|disable enable or disable SATA slumber\n"
10065 "-A enable|disable enable or disable SATA partial phy power\n"
10066 "-s enable|disable enable or disable SAS slumber\n"
10067 "-S enable|disable enable or disable SAS partial phy power\n"
10068 "smpphylist arguments:\n"
10069 "-l specify the long response format\n"
10070 "-q only print phys with attached devices\n"
10071 "smpmaninfo arguments:\n"
10072 "-l specify the long response format\n"
10073 "debug arguments:\n"
10074 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
10075 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
10076 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
10077 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
10078 "tags arguments:\n"
10079 "-N tags specify the number of tags to use for this device\n"
10080 "-q be quiet, don't report the number of tags\n"
10081 "-v report a number of tag-related parameters\n"
10082 "negotiate arguments:\n"
10083 "-a send a test unit ready after negotiation\n"
10084 "-c report/set current negotiation settings\n"
10085 "-D <arg> \"enable\" or \"disable\" disconnection\n"
10086 "-M mode set ATA mode\n"
10087 "-O offset set command delay offset\n"
10088 "-q be quiet, don't report anything\n"
10089 "-R syncrate synchronization rate in MHz\n"
10090 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
10091 "-U report/set user negotiation settings\n"
10092 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
10093 "-v also print a Path Inquiry CCB for the controller\n"
10094 "format arguments:\n"
10095 "-q be quiet, don't print status messages\n"
10096 "-r run in report only mode\n"
10097 "-w don't send immediate format command\n"
10098 "-y don't ask any questions\n"
10099 "sanitize arguments:\n"
10100 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
10101 "-c passes overwrite passes to perform (1 to 31)\n"
10102 "-I invert overwrite pattern after each pass\n"
10103 "-P pattern path to overwrite pattern file\n"
10104 "-q be quiet, don't print status messages\n"
10105 "-r run in report only mode\n"
10106 "-U run operation in unrestricted completion exit mode\n"
10107 "-w don't send immediate sanitize command\n"
10108 "-y don't ask any questions\n"
10109 "idle/standby arguments:\n"
10110 "-t <arg> number of seconds before respective state.\n"
10111 "fwdownload arguments:\n"
10112 "-f fw_image path to firmware image file\n"
10113 "-q don't print informational messages, only errors\n"
10114 "-s run in simulation mode\n"
10115 "-v print info for every firmware segment sent to device\n"
10116 "-y don't ask any questions\n"
10117 "security arguments:\n"
10118 "-d pwd disable security using the given password for the selected\n"
10120 "-e pwd erase the device using the given pwd for the selected user\n"
10121 "-f freeze the security configuration of the specified device\n"
10122 "-h pwd enhanced erase the device using the given pwd for the\n"
10124 "-k pwd unlock the device using the given pwd for the selected\n"
10126 "-l <high|maximum> specifies which security level to set: high or maximum\n"
10127 "-q be quiet, do not print any status messages\n"
10128 "-s pwd password the device (enable security) using the given\n"
10129 " pwd for the selected user\n"
10130 "-T timeout overrides the timeout (seconds) used for erase operation\n"
10131 "-U <user|master> specifies which user to set: user or master\n"
10132 "-y don't ask any questions\n"
10134 "-f freeze the HPA configuration of the device\n"
10135 "-l lock the HPA configuration of the device\n"
10136 "-P make the HPA max sectors persist\n"
10137 "-p pwd Set the HPA configuration password required for unlock\n"
10139 "-q be quiet, do not print any status messages\n"
10140 "-s sectors configures the maximum user accessible sectors of the\n"
10142 "-U pwd unlock the HPA configuration of the device\n"
10143 "-y don't ask any questions\n"
10145 "-f freeze the AMA configuration of the device\n"
10146 "-q be quiet, do not print any status messages\n"
10147 "-s sectors configures the maximum user accessible sectors of the\n"
10149 "persist arguments:\n"
10150 "-i action specify read_keys, read_reservation, report_cap, or\n"
10151 " read_full_status\n"
10152 "-o action specify register, register_ignore, reserve, release,\n"
10153 " clear, preempt, preempt_abort, register_move, replace_lost\n"
10154 "-a set the All Target Ports (ALL_TG_PT) bit\n"
10155 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
10156 "-k key specify the Reservation Key\n"
10157 "-K sa_key specify the Service Action Reservation Key\n"
10158 "-p set the Activate Persist Through Power Loss bit\n"
10159 "-R rtp specify the Relative Target Port\n"
10160 "-s scope specify the scope: lun, extent, element or a number\n"
10161 "-S specify Transport ID for register, requires -I\n"
10162 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
10163 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
10164 "-U unregister the current initiator for register_move\n"
10165 "attrib arguments:\n"
10166 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
10168 "-w attr specify an attribute to write, one -w argument per attr\n"
10169 "-a attr_num only display this attribute number\n"
10170 "-c get cached attributes\n"
10171 "-e elem_addr request attributes for the given element in a changer\n"
10172 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
10173 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
10174 " field_none, field_desc, field_num, field_size, field_rw\n"
10175 "-p partition request attributes for the given partition\n"
10176 "-s start_attr request attributes starting at the given number\n"
10177 "-T elem_type specify the element type (used with -e)\n"
10178 "-V logical_vol specify the logical volume ID\n"
10179 "opcodes arguments:\n"
10180 "-o opcode specify the individual opcode to list\n"
10181 "-s service_action specify the service action for the opcode\n"
10182 "-N do not return SCSI error for unsupported SA\n"
10183 "-T request nominal and recommended timeout values\n"
10184 "zone arguments:\n"
10185 "-c cmd required: rz, open, close, finish, or rwp\n"
10186 "-a apply the action to all zones\n"
10187 "-l LBA specify the zone starting LBA\n"
10188 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
10189 " closed, full, ro, offline, reset, nonseq, nonwp\n"
10190 "-P print_opt report zones printing: normal, summary, script\n"
10192 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
10193 " source, status, list\n"
10194 "-d disable power mode (timer, state)\n"
10195 "-D delayed entry (goto)\n"
10196 "-e enable power mode (timer, state)\n"
10197 "-H hold power mode (goto)\n"
10198 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
10200 "-P only display power mode (status)\n"
10201 "-r rst_src restore settings from: default, saved (restore)\n"
10202 "-s save mode (timer, state, restore)\n"
10203 "-S power_src set power source: battery, nonbattery (source)\n"
10204 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
10205 "timestamp arguments:\n"
10206 "-r report the timestamp of the device\n"
10207 "-f format report the timestamp of the device with the given\n"
10208 " strftime(3) format string\n"
10209 "-m report the timestamp of the device as milliseconds since\n"
10210 " January 1st, 1970\n"
10211 "-U report the time with UTC instead of the local time zone\n"
10212 "-s set the timestamp of the device\n"
10213 "-f format the format of the time string passed into strptime(3)\n"
10214 "-T time the time value passed into strptime(3)\n"
10215 "-U set the timestamp of the device to UTC time\n"
10217 #endif /* MINIMALISTIC */
10221 main(int argc, char **argv)
10224 char *device = NULL;
10226 struct cam_device *cam_dev = NULL;
10227 int timeout = 0, retry_count = 1;
10228 camcontrol_optret optreturn;
10230 const char *mainopt = "C:En:Q:t:u:v";
10231 const char *subopt = NULL;
10232 char combinedopt[256];
10233 int error = 0, optstart = 2;
10234 int task_attr = MSG_SIMPLE_Q_TAG;
10236 #ifndef MINIMALISTIC
10238 target_id_t target;
10240 #endif /* MINIMALISTIC */
10242 cmdlist = CAM_CMD_NONE;
10243 arglist = CAM_ARG_NONE;
10251 * Get the base option.
10253 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
10255 if (optreturn == CC_OR_AMBIGUOUS) {
10256 warnx("ambiguous option %s", argv[1]);
10259 } else if (optreturn == CC_OR_NOT_FOUND) {
10260 warnx("option %s not found", argv[1]);
10266 * Ahh, getopt(3) is a pain.
10268 * This is a gross hack. There really aren't many other good
10269 * options (excuse the pun) for parsing options in a situation like
10270 * this. getopt is kinda braindead, so you end up having to run
10271 * through the options twice, and give each invocation of getopt
10272 * the option string for the other invocation.
10274 * You would think that you could just have two groups of options.
10275 * The first group would get parsed by the first invocation of
10276 * getopt, and the second group would get parsed by the second
10277 * invocation of getopt. It doesn't quite work out that way. When
10278 * the first invocation of getopt finishes, it leaves optind pointing
10279 * to the argument _after_ the first argument in the second group.
10280 * So when the second invocation of getopt comes around, it doesn't
10281 * recognize the first argument it gets and then bails out.
10283 * A nice alternative would be to have a flag for getopt that says
10284 * "just keep parsing arguments even when you encounter an unknown
10285 * argument", but there isn't one. So there's no real clean way to
10286 * easily parse two sets of arguments without having one invocation
10287 * of getopt know about the other.
10289 * Without this hack, the first invocation of getopt would work as
10290 * long as the generic arguments are first, but the second invocation
10291 * (in the subfunction) would fail in one of two ways. In the case
10292 * where you don't set optreset, it would fail because optind may be
10293 * pointing to the argument after the one it should be pointing at.
10294 * In the case where you do set optreset, and reset optind, it would
10295 * fail because getopt would run into the first set of options, which
10296 * it doesn't understand.
10298 * All of this would "sort of" work if you could somehow figure out
10299 * whether optind had been incremented one option too far. The
10300 * mechanics of that, however, are more daunting than just giving
10301 * both invocations all of the expect options for either invocation.
10303 * Needless to say, I wouldn't mind if someone invented a better
10304 * (non-GPL!) command line parsing interface than getopt. I
10305 * wouldn't mind if someone added more knobs to getopt to make it
10306 * work better. Who knows, I may talk myself into doing it someday,
10307 * if the standards weenies let me. As it is, it just leads to
10308 * hackery like this and causes people to avoid it in some cases.
10310 * KDM, September 8th, 1998
10312 if (subopt != NULL)
10313 sprintf(combinedopt, "%s%s", mainopt, subopt);
10315 sprintf(combinedopt, "%s", mainopt);
10318 * For these options we do not parse optional device arguments and
10319 * we do not open a passthrough device.
10321 if ((cmdlist == CAM_CMD_RESCAN)
10322 || (cmdlist == CAM_CMD_RESET)
10323 || (cmdlist == CAM_CMD_DEVTREE)
10324 || (cmdlist == CAM_CMD_USAGE)
10325 || (cmdlist == CAM_CMD_DEBUG))
10328 #ifndef MINIMALISTIC
10330 && (argc > 2 && argv[2][0] != '-')) {
10334 if (isdigit(argv[2][0])) {
10335 /* device specified as bus:target[:lun] */
10336 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10338 errx(1, "numeric device specification must "
10339 "be either bus:target, or "
10341 /* default to 0 if lun was not specified */
10342 if ((arglist & CAM_ARG_LUN) == 0) {
10344 arglist |= CAM_ARG_LUN;
10348 if (cam_get_device(argv[2], name, sizeof name, &unit)
10350 errx(1, "%s", cam_errbuf);
10351 device = strdup(name);
10352 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10356 #endif /* MINIMALISTIC */
10358 * Start getopt processing at argv[2/3], since we've already
10359 * accepted argv[1..2] as the command name, and as a possible
10365 * Now we run through the argument list looking for generic
10366 * options, and ignoring options that possibly belong to
10369 while ((c = getopt(argc, argv, combinedopt))!= -1){
10372 retry_count = strtol(optarg, NULL, 0);
10373 if (retry_count < 0)
10374 errx(1, "retry count %d is < 0",
10376 arglist |= CAM_ARG_RETRIES;
10379 arglist |= CAM_ARG_ERR_RECOVER;
10382 arglist |= CAM_ARG_DEVICE;
10384 while (isspace(*tstr) && (*tstr != '\0'))
10386 device = (char *)strdup(tstr);
10390 int table_entry = 0;
10393 while (isspace(*tstr) && (*tstr != '\0'))
10395 if (isdigit(*tstr)) {
10396 task_attr = strtol(tstr, &endptr, 0);
10397 if (*endptr != '\0') {
10398 errx(1, "Invalid queue option "
10403 scsi_nv_status status;
10405 table_size = sizeof(task_attrs) /
10406 sizeof(task_attrs[0]);
10407 status = scsi_get_nv(task_attrs,
10408 table_size, tstr, &table_entry,
10409 SCSI_NV_FLAG_IG_CASE);
10410 if (status == SCSI_NV_FOUND)
10411 task_attr = task_attrs[
10412 table_entry].value;
10414 errx(1, "%s option %s",
10415 (status == SCSI_NV_AMBIGUOUS)?
10416 "ambiguous" : "invalid",
10423 timeout = strtol(optarg, NULL, 0);
10425 errx(1, "invalid timeout %d", timeout);
10426 /* Convert the timeout from seconds to ms */
10428 arglist |= CAM_ARG_TIMEOUT;
10431 arglist |= CAM_ARG_UNIT;
10432 unit = strtol(optarg, NULL, 0);
10435 arglist |= CAM_ARG_VERBOSE;
10442 #ifndef MINIMALISTIC
10444 * For most commands we'll want to open the passthrough device
10445 * associated with the specified device. In the case of the rescan
10446 * commands, we don't use a passthrough device at all, just the
10447 * transport layer device.
10449 if (devopen == 1) {
10450 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10451 && (((arglist & CAM_ARG_DEVICE) == 0)
10452 || ((arglist & CAM_ARG_UNIT) == 0))) {
10453 errx(1, "subcommand \"%s\" requires a valid device "
10454 "identifier", argv[1]);
10457 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10458 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10459 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10461 errx(1,"%s", cam_errbuf);
10463 #endif /* MINIMALISTIC */
10466 * Reset optind to 2, and reset getopt, so these routines can parse
10467 * the arguments again.
10473 #ifndef MINIMALISTIC
10474 case CAM_CMD_DEVLIST:
10475 error = getdevlist(cam_dev);
10478 error = atahpa(cam_dev, retry_count, timeout,
10479 argc, argv, combinedopt);
10482 error = ataama(cam_dev, retry_count, timeout,
10483 argc, argv, combinedopt);
10485 #endif /* MINIMALISTIC */
10486 case CAM_CMD_DEVTREE:
10487 error = getdevtree(argc, argv, combinedopt);
10489 case CAM_CMD_DEVTYPE:
10490 error = getdevtype(cam_dev);
10492 #ifndef MINIMALISTIC
10494 error = testunitready(cam_dev, task_attr, retry_count,
10497 case CAM_CMD_INQUIRY:
10498 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10499 task_attr, retry_count, timeout);
10501 case CAM_CMD_IDENTIFY:
10502 error = identify(cam_dev, retry_count, timeout);
10504 case CAM_CMD_STARTSTOP:
10505 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10506 arglist & CAM_ARG_EJECT, task_attr,
10507 retry_count, timeout);
10509 #endif /* MINIMALISTIC */
10510 case CAM_CMD_RESCAN:
10511 error = dorescan_or_reset(argc, argv, 1);
10513 case CAM_CMD_RESET:
10514 error = dorescan_or_reset(argc, argv, 0);
10516 #ifndef MINIMALISTIC
10517 case CAM_CMD_READ_DEFECTS:
10518 error = readdefects(cam_dev, argc, argv, combinedopt,
10519 task_attr, retry_count, timeout);
10521 case CAM_CMD_MODE_PAGE:
10522 modepage(cam_dev, argc, argv, combinedopt,
10523 task_attr, retry_count, timeout);
10525 case CAM_CMD_SCSI_CMD:
10526 error = scsicmd(cam_dev, argc, argv, combinedopt,
10527 task_attr, retry_count, timeout);
10529 case CAM_CMD_MMCSD_CMD:
10530 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10531 retry_count, timeout);
10533 case CAM_CMD_SMP_CMD:
10534 error = smpcmd(cam_dev, argc, argv, combinedopt,
10535 retry_count, timeout);
10537 case CAM_CMD_SMP_RG:
10538 error = smpreportgeneral(cam_dev, argc, argv,
10539 combinedopt, retry_count,
10542 case CAM_CMD_SMP_PC:
10543 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10544 retry_count, timeout);
10546 case CAM_CMD_SMP_PHYLIST:
10547 error = smpphylist(cam_dev, argc, argv, combinedopt,
10548 retry_count, timeout);
10550 case CAM_CMD_SMP_MANINFO:
10551 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10552 retry_count, timeout);
10554 case CAM_CMD_DEBUG:
10555 error = camdebug(argc, argv, combinedopt);
10558 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10561 error = ratecontrol(cam_dev, task_attr, retry_count,
10562 timeout, argc, argv, combinedopt);
10564 case CAM_CMD_FORMAT:
10565 error = scsiformat(cam_dev, argc, argv,
10566 combinedopt, task_attr, retry_count,
10569 case CAM_CMD_REPORTLUNS:
10570 error = scsireportluns(cam_dev, argc, argv,
10571 combinedopt, task_attr,
10572 retry_count, timeout);
10574 case CAM_CMD_READCAP:
10575 error = scsireadcapacity(cam_dev, argc, argv,
10576 combinedopt, task_attr,
10577 retry_count, timeout);
10580 case CAM_CMD_STANDBY:
10581 case CAM_CMD_SLEEP:
10582 case CAM_CMD_POWER_MODE:
10583 error = atapm(cam_dev, argc, argv,
10584 combinedopt, retry_count, timeout);
10588 error = ataaxm(cam_dev, argc, argv,
10589 combinedopt, retry_count, timeout);
10591 case CAM_CMD_SECURITY:
10592 error = atasecurity(cam_dev, retry_count, timeout,
10593 argc, argv, combinedopt);
10595 case CAM_CMD_DOWNLOAD_FW:
10596 error = fwdownload(cam_dev, argc, argv, combinedopt,
10597 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10600 case CAM_CMD_SANITIZE:
10601 error = scsisanitize(cam_dev, argc, argv,
10602 combinedopt, task_attr,
10603 retry_count, timeout);
10605 case CAM_CMD_PERSIST:
10606 error = scsipersist(cam_dev, argc, argv, combinedopt,
10607 task_attr, retry_count, timeout,
10608 arglist & CAM_ARG_VERBOSE,
10609 arglist & CAM_ARG_ERR_RECOVER);
10611 case CAM_CMD_ATTRIB:
10612 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10613 task_attr, retry_count, timeout,
10614 arglist & CAM_ARG_VERBOSE,
10615 arglist & CAM_ARG_ERR_RECOVER);
10617 case CAM_CMD_OPCODES:
10618 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10619 task_attr, retry_count, timeout,
10620 arglist & CAM_ARG_VERBOSE);
10622 case CAM_CMD_REPROBE:
10623 error = scsireprobe(cam_dev);
10626 error = zone(cam_dev, argc, argv, combinedopt,
10627 task_attr, retry_count, timeout,
10628 arglist & CAM_ARG_VERBOSE);
10631 error = epc(cam_dev, argc, argv, combinedopt,
10632 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10634 case CAM_CMD_TIMESTAMP:
10635 error = timestamp(cam_dev, argc, argv, combinedopt,
10636 task_attr, retry_count, timeout,
10637 arglist & CAM_ARG_VERBOSE);
10639 #endif /* MINIMALISTIC */
10640 case CAM_CMD_USAGE:
10649 if (cam_dev != NULL)
10650 cam_close_device(cam_dev);