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 * Convert periph name into a bus, target and lun.
3562 * Returns the number of parsed components, or 0.
3565 parse_btl_name(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3566 cam_argmask *arglst)
3571 bzero(&ccb, sizeof(ccb));
3572 ccb.ccb_h.func_code = XPT_GDEVLIST;
3573 if (cam_get_device(tstr, ccb.cgdl.periph_name,
3574 sizeof(ccb.cgdl.periph_name), &ccb.cgdl.unit_number) == -1) {
3575 warnx("%s", cam_errbuf);
3580 * Attempt to get the passthrough device. This ioctl will
3581 * fail if the device name is null, if the device doesn't
3582 * exist, or if the passthrough driver isn't in the kernel.
3584 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3585 warn("Unable to open %s", XPT_DEVICE);
3588 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3589 warn("Unable to find bus:target:lun for device %s%d",
3590 ccb.cgdl.periph_name, ccb.cgdl.unit_number);
3595 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3596 const struct cam_status_entry *entry;
3598 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3599 warnx("Unable to find bus:target_lun for device %s%d, "
3600 "CAM status: %s (%#x)",
3601 ccb.cgdl.periph_name, ccb.cgdl.unit_number,
3602 entry ? entry->status_text : "Unknown",
3608 * The kernel fills in the bus/target/lun. We don't
3609 * need the passthrough device name and unit number since
3610 * we aren't going to open it.
3612 *bus = ccb.ccb_h.path_id;
3613 *target = ccb.ccb_h.target_id;
3614 *lun = ccb.ccb_h.target_lun;
3615 *arglst |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3620 * Parse out a bus, or a bus, target and lun in the following
3626 * Returns the number of parsed components, or 0.
3629 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3630 cam_argmask *arglst)
3635 *bus = CAM_BUS_WILDCARD;
3636 *target = CAM_TARGET_WILDCARD;
3637 *lun = CAM_LUN_WILDCARD;
3639 while (isspace(*tstr) && (*tstr != '\0'))
3642 if (strncasecmp(tstr, "all", strlen("all")) == 0) {
3643 arglist |= CAM_ARG_BUS;
3647 if (!isdigit(*tstr))
3648 return (parse_btl_name(tstr, bus, target, lun, arglst));
3650 tmpstr = strsep(&tstr, ":");
3651 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3652 *bus = strtol(tmpstr, &end, 0);
3655 *arglst |= CAM_ARG_BUS;
3657 tmpstr = strsep(&tstr, ":");
3658 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3659 *target = strtol(tmpstr, &end, 0);
3662 *arglst |= CAM_ARG_TARGET;
3664 tmpstr = strsep(&tstr, ":");
3665 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3666 *lun = strtoll(tmpstr, &end, 0);
3669 *arglst |= CAM_ARG_LUN;
3679 dorescan_or_reset(int argc, char **argv, int rescan)
3681 static const char must[] =
3682 "you must specify \"all\", a bus, a bus:target:lun or periph to %s";
3684 path_id_t bus = CAM_BUS_WILDCARD;
3685 target_id_t target = CAM_TARGET_WILDCARD;
3686 lun_id_t lun = CAM_LUN_WILDCARD;
3690 warnx(must, rescan? "rescan" : "reset");
3694 tstr = argv[optind];
3695 while (isspace(*tstr) && (*tstr != '\0'))
3697 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3698 arglist |= CAM_ARG_BUS;
3700 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3701 if (rv != 1 && rv != 3) {
3702 warnx(must, rescan ? "rescan" : "reset");
3707 if (arglist & CAM_ARG_LUN)
3708 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3710 error = rescan_or_reset_bus(bus, rescan);
3716 rescan_or_reset_bus(path_id_t bus, int rescan)
3718 union ccb *ccb = NULL, *matchccb = NULL;
3719 int fd = -1, retval;
3724 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3725 warnx("error opening transport layer device %s", XPT_DEVICE);
3726 warn("%s", XPT_DEVICE);
3730 ccb = malloc(sizeof(*ccb));
3732 warn("failed to allocate CCB");
3736 bzero(ccb, sizeof(*ccb));
3738 if (bus != CAM_BUS_WILDCARD) {
3739 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3740 ccb->ccb_h.path_id = bus;
3741 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3742 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3743 ccb->crcn.flags = CAM_FLAG_NONE;
3745 /* run this at a low priority */
3746 ccb->ccb_h.pinfo.priority = 5;
3748 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3749 warn("CAMIOCOMMAND ioctl failed");
3754 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3755 fprintf(stdout, "%s of bus %d was successful\n",
3756 rescan ? "Re-scan" : "Reset", bus);
3758 fprintf(stdout, "%s of bus %d returned error %#x\n",
3759 rescan ? "Re-scan" : "Reset", bus,
3760 ccb->ccb_h.status & CAM_STATUS_MASK);
3769 * The right way to handle this is to modify the xpt so that it can
3770 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3771 * that isn't implemented, so instead we enumerate the buses and
3772 * send the rescan or reset to those buses in the case where the
3773 * given bus is -1 (wildcard). We don't send a rescan or reset
3774 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3775 * no-op, sending a rescan to the xpt bus would result in a status of
3778 matchccb = malloc(sizeof(*matchccb));
3779 if (matchccb == NULL) {
3780 warn("failed to allocate CCB");
3784 bzero(matchccb, sizeof(*matchccb));
3785 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3786 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3787 bufsize = sizeof(struct dev_match_result) * 20;
3788 matchccb->cdm.match_buf_len = bufsize;
3789 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3790 if (matchccb->cdm.matches == NULL) {
3791 warnx("can't malloc memory for matches");
3795 matchccb->cdm.num_matches = 0;
3797 matchccb->cdm.num_patterns = 1;
3798 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3800 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3801 matchccb->cdm.pattern_buf_len);
3802 if (matchccb->cdm.patterns == NULL) {
3803 warnx("can't malloc memory for patterns");
3807 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3808 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3813 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3814 warn("CAMIOCOMMAND ioctl failed");
3819 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3820 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3821 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3822 warnx("got CAM error %#x, CDM error %d\n",
3823 matchccb->ccb_h.status, matchccb->cdm.status);
3828 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3829 struct bus_match_result *bus_result;
3831 /* This shouldn't happen. */
3832 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3835 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3838 * We don't want to rescan or reset the xpt bus.
3841 if (bus_result->path_id == CAM_XPT_PATH_ID)
3844 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3846 ccb->ccb_h.path_id = bus_result->path_id;
3847 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3848 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3849 ccb->crcn.flags = CAM_FLAG_NONE;
3851 /* run this at a low priority */
3852 ccb->ccb_h.pinfo.priority = 5;
3854 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3855 warn("CAMIOCOMMAND ioctl failed");
3860 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3861 fprintf(stdout, "%s of bus %d was successful\n",
3862 rescan? "Re-scan" : "Reset",
3863 bus_result->path_id);
3866 * Don't bail out just yet, maybe the other
3867 * rescan or reset commands will complete
3870 fprintf(stderr, "%s of bus %d returned error "
3871 "%#x\n", rescan? "Re-scan" : "Reset",
3872 bus_result->path_id,
3873 ccb->ccb_h.status & CAM_STATUS_MASK);
3877 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3878 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3885 if (matchccb != NULL) {
3886 free(matchccb->cdm.patterns);
3887 free(matchccb->cdm.matches);
3896 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3899 struct cam_device *device;
3904 if (bus == CAM_BUS_WILDCARD) {
3905 warnx("invalid bus number %d", bus);
3909 if (target == CAM_TARGET_WILDCARD) {
3910 warnx("invalid target number %d", target);
3914 if (lun == CAM_LUN_WILDCARD) {
3915 warnx("invalid lun number %jx", (uintmax_t)lun);
3921 bzero(&ccb, sizeof(union ccb));
3924 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3925 warnx("error opening transport layer device %s\n",
3927 warn("%s", XPT_DEVICE);
3931 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3932 if (device == NULL) {
3933 warnx("%s", cam_errbuf);
3938 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3939 ccb.ccb_h.path_id = bus;
3940 ccb.ccb_h.target_id = target;
3941 ccb.ccb_h.target_lun = lun;
3942 ccb.ccb_h.timeout = 5000;
3943 ccb.crcn.flags = CAM_FLAG_NONE;
3945 /* run this at a low priority */
3946 ccb.ccb_h.pinfo.priority = 5;
3949 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3950 warn("CAMIOCOMMAND ioctl failed");
3955 if (cam_send_ccb(device, &ccb) < 0) {
3956 warn("error sending XPT_RESET_DEV CCB");
3957 cam_close_device(device);
3965 cam_close_device(device);
3968 * An error code of CAM_BDR_SENT is normal for a BDR request.
3970 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3972 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3973 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3974 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3977 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3978 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3979 ccb.ccb_h.status & CAM_STATUS_MASK);
3984 #ifndef MINIMALISTIC
3986 static struct scsi_nv defect_list_type_map[] = {
3987 { "block", SRDD10_BLOCK_FORMAT },
3988 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3989 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3990 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3991 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3992 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3996 readdefects(struct cam_device *device, int argc, char **argv,
3997 char *combinedopt, int task_attr, int retry_count, int timeout)
3999 union ccb *ccb = NULL;
4000 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
4001 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
4002 size_t hdr_size = 0, entry_size = 0;
4005 u_int8_t *defect_list = NULL;
4006 u_int8_t list_format = 0;
4007 int list_type_set = 0;
4008 u_int32_t dlist_length = 0;
4009 u_int32_t returned_length = 0, valid_len = 0;
4010 u_int32_t num_returned = 0, num_valid = 0;
4011 u_int32_t max_possible_size = 0, hdr_max = 0;
4012 u_int32_t starting_offset = 0;
4013 u_int8_t returned_format, returned_type;
4015 int summary = 0, quiet = 0;
4017 int lists_specified = 0;
4018 int get_length = 1, first_pass = 1;
4021 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4025 scsi_nv_status status;
4028 status = scsi_get_nv(defect_list_type_map,
4029 sizeof(defect_list_type_map) /
4030 sizeof(defect_list_type_map[0]), optarg,
4031 &entry_num, SCSI_NV_FLAG_IG_CASE);
4033 if (status == SCSI_NV_FOUND) {
4034 list_format = defect_list_type_map[
4038 warnx("%s: %s %s option %s", __func__,
4039 (status == SCSI_NV_AMBIGUOUS) ?
4040 "ambiguous" : "invalid", "defect list type",
4043 goto defect_bailout;
4048 arglist |= CAM_ARG_GLIST;
4051 arglist |= CAM_ARG_PLIST;
4062 starting_offset = strtoul(optarg, &endptr, 0);
4063 if (*endptr != '\0') {
4065 warnx("invalid starting offset %s", optarg);
4066 goto defect_bailout;
4078 if (list_type_set == 0) {
4080 warnx("no defect list format specified");
4081 goto defect_bailout;
4084 if (arglist & CAM_ARG_PLIST) {
4085 list_format |= SRDD10_PLIST;
4089 if (arglist & CAM_ARG_GLIST) {
4090 list_format |= SRDD10_GLIST;
4095 * This implies a summary, and was the previous behavior.
4097 if (lists_specified == 0)
4100 ccb = cam_getccb(device);
4105 * We start off asking for just the header to determine how much
4106 * defect data is available. Some Hitachi drives return an error
4107 * if you ask for more data than the drive has. Once we know the
4108 * length, we retry the command with the returned length.
4110 if (use_12byte == 0)
4111 dlist_length = sizeof(*hdr10);
4113 dlist_length = sizeof(*hdr12);
4116 if (defect_list != NULL) {
4120 defect_list = malloc(dlist_length);
4121 if (defect_list == NULL) {
4122 warnx("can't malloc memory for defect list");
4124 goto defect_bailout;
4128 bzero(defect_list, dlist_length);
4131 * cam_getccb() zeros the CCB header only. So we need to zero the
4132 * payload portion of the ccb.
4134 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4136 scsi_read_defects(&ccb->csio,
4137 /*retries*/ retry_count,
4139 /*tag_action*/ task_attr,
4140 /*list_format*/ list_format,
4141 /*addr_desc_index*/ starting_offset,
4142 /*data_ptr*/ defect_list,
4143 /*dxfer_len*/ dlist_length,
4144 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
4145 /*sense_len*/ SSD_FULL_SIZE,
4146 /*timeout*/ timeout ? timeout : 5000);
4148 /* Disable freezing the device queue */
4149 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4151 if (cam_send_ccb(device, ccb) < 0) {
4152 perror("error reading defect list");
4154 if (arglist & CAM_ARG_VERBOSE) {
4155 cam_error_print(device, ccb, CAM_ESF_ALL,
4156 CAM_EPF_ALL, stderr);
4160 goto defect_bailout;
4163 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
4165 if (use_12byte == 0) {
4166 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
4167 hdr_size = sizeof(*hdr10);
4168 hdr_max = SRDDH10_MAX_LENGTH;
4170 if (valid_len >= hdr_size) {
4171 returned_length = scsi_2btoul(hdr10->length);
4172 returned_format = hdr10->format;
4174 returned_length = 0;
4175 returned_format = 0;
4178 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
4179 hdr_size = sizeof(*hdr12);
4180 hdr_max = SRDDH12_MAX_LENGTH;
4182 if (valid_len >= hdr_size) {
4183 returned_length = scsi_4btoul(hdr12->length);
4184 returned_format = hdr12->format;
4186 returned_length = 0;
4187 returned_format = 0;
4191 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
4192 switch (returned_type) {
4193 case SRDD10_BLOCK_FORMAT:
4194 entry_size = sizeof(struct scsi_defect_desc_block);
4196 case SRDD10_LONG_BLOCK_FORMAT:
4197 entry_size = sizeof(struct scsi_defect_desc_long_block);
4199 case SRDD10_EXT_PHYS_FORMAT:
4200 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4201 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
4203 case SRDD10_EXT_BFI_FORMAT:
4204 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4205 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
4208 warnx("Unknown defect format 0x%x\n", returned_type);
4210 goto defect_bailout;
4214 max_possible_size = (hdr_max / entry_size) * entry_size;
4215 num_returned = returned_length / entry_size;
4216 num_valid = min(returned_length, valid_len - hdr_size);
4217 num_valid /= entry_size;
4219 if (get_length != 0) {
4222 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
4223 CAM_SCSI_STATUS_ERROR) {
4224 struct scsi_sense_data *sense;
4225 int error_code, sense_key, asc, ascq;
4227 sense = &ccb->csio.sense_data;
4228 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4229 ccb->csio.sense_resid, &error_code, &sense_key,
4230 &asc, &ascq, /*show_errors*/ 1);
4233 * If the drive is reporting that it just doesn't
4234 * support the defect list format, go ahead and use
4235 * the length it reported. Otherwise, the length
4236 * may not be valid, so use the maximum.
4238 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4239 && (asc == 0x1c) && (ascq == 0x00)
4240 && (returned_length > 0)) {
4241 if ((use_12byte == 0)
4242 && (returned_length >= max_possible_size)) {
4247 dlist_length = returned_length + hdr_size;
4248 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4249 && (asc == 0x1f) && (ascq == 0x00)
4250 && (returned_length > 0)) {
4251 /* Partial defect list transfer */
4253 * Hitachi drives return this error
4254 * along with a partial defect list if they
4255 * have more defects than the 10 byte
4256 * command can support. Retry with the 12
4259 if (use_12byte == 0) {
4264 dlist_length = returned_length + hdr_size;
4265 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
4266 && (asc == 0x24) && (ascq == 0x00)) {
4267 /* Invalid field in CDB */
4269 * SBC-3 says that if the drive has more
4270 * defects than can be reported with the
4271 * 10 byte command, it should return this
4272 * error and no data. Retry with the 12
4275 if (use_12byte == 0) {
4280 dlist_length = returned_length + hdr_size;
4283 * If we got a SCSI error and no valid length,
4284 * just use the 10 byte maximum. The 12
4285 * byte maximum is too large.
4287 if (returned_length == 0)
4288 dlist_length = SRDD10_MAX_LENGTH;
4290 if ((use_12byte == 0)
4291 && (returned_length >=
4292 max_possible_size)) {
4297 dlist_length = returned_length +
4301 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4304 warnx("Error reading defect header");
4305 if (arglist & CAM_ARG_VERBOSE)
4306 cam_error_print(device, ccb, CAM_ESF_ALL,
4307 CAM_EPF_ALL, stderr);
4308 goto defect_bailout;
4310 if ((use_12byte == 0)
4311 && (returned_length >= max_possible_size)) {
4316 dlist_length = returned_length + hdr_size;
4319 fprintf(stdout, "%u", num_returned);
4321 fprintf(stdout, " defect%s",
4322 (num_returned != 1) ? "s" : "");
4324 fprintf(stdout, "\n");
4326 goto defect_bailout;
4330 * We always limit the list length to the 10-byte maximum
4331 * length (0xffff). The reason is that some controllers
4332 * can't handle larger I/Os, and we can transfer the entire
4333 * 10 byte list in one shot. For drives that support the 12
4334 * byte read defects command, we'll step through the list
4335 * by specifying a starting offset. For drives that don't
4336 * support the 12 byte command's starting offset, we'll
4337 * just display the first 64K.
4339 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4345 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4346 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4347 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4348 struct scsi_sense_data *sense;
4349 int error_code, sense_key, asc, ascq;
4351 sense = &ccb->csio.sense_data;
4352 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4353 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4354 &ascq, /*show_errors*/ 1);
4357 * According to the SCSI spec, if the disk doesn't support
4358 * the requested format, it will generally return a sense
4359 * key of RECOVERED ERROR, and an additional sense code
4360 * of "DEFECT LIST NOT FOUND". HGST drives also return
4361 * Primary/Grown defect list not found errors. So just
4362 * check for an ASC of 0x1c.
4364 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4366 const char *format_str;
4368 format_str = scsi_nv_to_str(defect_list_type_map,
4369 sizeof(defect_list_type_map) /
4370 sizeof(defect_list_type_map[0]),
4371 list_format & SRDD10_DLIST_FORMAT_MASK);
4372 warnx("requested defect format %s not available",
4373 format_str ? format_str : "unknown");
4375 format_str = scsi_nv_to_str(defect_list_type_map,
4376 sizeof(defect_list_type_map) /
4377 sizeof(defect_list_type_map[0]), returned_type);
4378 if (format_str != NULL) {
4379 warnx("Device returned %s format",
4383 warnx("Device returned unknown defect"
4384 " data format %#x", returned_type);
4385 goto defect_bailout;
4389 warnx("Error returned from read defect data command");
4390 if (arglist & CAM_ARG_VERBOSE)
4391 cam_error_print(device, ccb, CAM_ESF_ALL,
4392 CAM_EPF_ALL, stderr);
4393 goto defect_bailout;
4395 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4397 warnx("Error returned from read defect data command");
4398 if (arglist & CAM_ARG_VERBOSE)
4399 cam_error_print(device, ccb, CAM_ESF_ALL,
4400 CAM_EPF_ALL, stderr);
4401 goto defect_bailout;
4404 if (first_pass != 0) {
4405 fprintf(stderr, "Got %d defect", num_returned);
4407 if ((lists_specified == 0) || (num_returned == 0)) {
4408 fprintf(stderr, "s.\n");
4409 goto defect_bailout;
4410 } else if (num_returned == 1)
4411 fprintf(stderr, ":\n");
4413 fprintf(stderr, "s:\n");
4419 * XXX KDM I should probably clean up the printout format for the
4422 switch (returned_type) {
4423 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4424 case SRDD10_EXT_PHYS_FORMAT:
4426 struct scsi_defect_desc_phys_sector *dlist;
4428 dlist = (struct scsi_defect_desc_phys_sector *)
4429 (defect_list + hdr_size);
4431 for (i = 0; i < num_valid; i++) {
4434 sector = scsi_4btoul(dlist[i].sector);
4435 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4436 mads = (sector & SDD_EXT_PHYS_MADS) ?
4438 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4440 if (hex_format == 0)
4441 fprintf(stdout, "%d:%d:%d%s",
4442 scsi_3btoul(dlist[i].cylinder),
4444 scsi_4btoul(dlist[i].sector),
4445 mads ? " - " : "\n");
4447 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4448 scsi_3btoul(dlist[i].cylinder),
4450 scsi_4btoul(dlist[i].sector),
4451 mads ? " - " : "\n");
4454 if (num_valid < num_returned) {
4455 starting_offset += num_valid;
4460 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4461 case SRDD10_EXT_BFI_FORMAT:
4463 struct scsi_defect_desc_bytes_from_index *dlist;
4465 dlist = (struct scsi_defect_desc_bytes_from_index *)
4466 (defect_list + hdr_size);
4468 for (i = 0; i < num_valid; i++) {
4471 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4472 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4473 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4474 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4476 if (hex_format == 0)
4477 fprintf(stdout, "%d:%d:%d%s",
4478 scsi_3btoul(dlist[i].cylinder),
4480 scsi_4btoul(dlist[i].bytes_from_index),
4481 mads ? " - " : "\n");
4483 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4484 scsi_3btoul(dlist[i].cylinder),
4486 scsi_4btoul(dlist[i].bytes_from_index),
4487 mads ? " - " : "\n");
4491 if (num_valid < num_returned) {
4492 starting_offset += num_valid;
4497 case SRDDH10_BLOCK_FORMAT:
4499 struct scsi_defect_desc_block *dlist;
4501 dlist = (struct scsi_defect_desc_block *)
4502 (defect_list + hdr_size);
4504 for (i = 0; i < num_valid; i++) {
4505 if (hex_format == 0)
4506 fprintf(stdout, "%u\n",
4507 scsi_4btoul(dlist[i].address));
4509 fprintf(stdout, "0x%x\n",
4510 scsi_4btoul(dlist[i].address));
4513 if (num_valid < num_returned) {
4514 starting_offset += num_valid;
4520 case SRDD10_LONG_BLOCK_FORMAT:
4522 struct scsi_defect_desc_long_block *dlist;
4524 dlist = (struct scsi_defect_desc_long_block *)
4525 (defect_list + hdr_size);
4527 for (i = 0; i < num_valid; i++) {
4528 if (hex_format == 0)
4529 fprintf(stdout, "%ju\n",
4530 (uintmax_t)scsi_8btou64(
4533 fprintf(stdout, "0x%jx\n",
4534 (uintmax_t)scsi_8btou64(
4538 if (num_valid < num_returned) {
4539 starting_offset += num_valid;
4545 fprintf(stderr, "Unknown defect format 0x%x\n",
4552 if (defect_list != NULL)
4560 #endif /* MINIMALISTIC */
4564 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4568 ccb = cam_getccb(device);
4574 #ifndef MINIMALISTIC
4576 mode_sense(struct cam_device *device, int dbd, int pc, int page, int subpage,
4577 int task_attr, int retry_count, int timeout, u_int8_t *data,
4583 ccb = cam_getccb(device);
4586 errx(1, "mode_sense: couldn't allocate CCB");
4588 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4590 scsi_mode_sense_subpage(&ccb->csio,
4591 /* retries */ retry_count,
4593 /* tag_action */ task_attr,
4597 /* subpage */ subpage,
4598 /* param_buf */ data,
4599 /* param_len */ datalen,
4600 /* minimum_cmd_size */ 0,
4601 /* sense_len */ SSD_FULL_SIZE,
4602 /* timeout */ timeout ? timeout : 5000);
4604 if (arglist & CAM_ARG_ERR_RECOVER)
4605 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4607 /* Disable freezing the device queue */
4608 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4610 if (((retval = cam_send_ccb(device, ccb)) < 0)
4611 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4612 if (arglist & CAM_ARG_VERBOSE) {
4613 cam_error_print(device, ccb, CAM_ESF_ALL,
4614 CAM_EPF_ALL, stderr);
4617 cam_close_device(device);
4619 err(1, "error sending mode sense command");
4621 errx(1, "error sending mode sense command");
4628 mode_select(struct cam_device *device, int save_pages, int task_attr,
4629 int retry_count, int timeout, u_int8_t *data, int datalen)
4634 ccb = cam_getccb(device);
4637 errx(1, "mode_select: couldn't allocate CCB");
4639 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4641 scsi_mode_select(&ccb->csio,
4642 /* retries */ retry_count,
4644 /* tag_action */ task_attr,
4645 /* scsi_page_fmt */ 1,
4646 /* save_pages */ save_pages,
4647 /* param_buf */ data,
4648 /* param_len */ datalen,
4649 /* sense_len */ SSD_FULL_SIZE,
4650 /* timeout */ timeout ? timeout : 5000);
4652 if (arglist & CAM_ARG_ERR_RECOVER)
4653 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4655 /* Disable freezing the device queue */
4656 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4658 if (((retval = cam_send_ccb(device, ccb)) < 0)
4659 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4660 if (arglist & CAM_ARG_VERBOSE) {
4661 cam_error_print(device, ccb, CAM_ESF_ALL,
4662 CAM_EPF_ALL, stderr);
4665 cam_close_device(device);
4668 err(1, "error sending mode select command");
4670 errx(1, "error sending mode select command");
4678 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4679 int task_attr, int retry_count, int timeout)
4682 int c, page = -1, subpage = -1, pc = 0;
4683 int binary = 0, dbd = 0, edit = 0, list = 0;
4685 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4700 str_subpage = optarg;
4701 strsep(&str_subpage, ",");
4702 page = strtol(optarg, NULL, 0);
4704 subpage = strtol(str_subpage, NULL, 0);
4708 errx(1, "invalid mode page %d", page);
4710 errx(1, "invalid mode subpage %d", subpage);
4713 pc = strtol(optarg, NULL, 0);
4714 if ((pc < 0) || (pc > 3))
4715 errx(1, "invalid page control field %d", pc);
4722 if (page == -1 && list == 0)
4723 errx(1, "you must specify a mode page!");
4726 mode_list(device, dbd, pc, list > 1, task_attr, retry_count,
4729 mode_edit(device, dbd, pc, page, subpage, edit, binary,
4730 task_attr, retry_count, timeout);
4735 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4736 int task_attr, int retry_count, int timeout)
4739 u_int32_t flags = CAM_DIR_NONE;
4740 u_int8_t *data_ptr = NULL;
4742 u_int8_t atacmd[12];
4743 struct get_hook hook;
4744 int c, data_bytes = 0, valid_bytes;
4750 char *datastr = NULL, *tstr, *resstr = NULL;
4752 int fd_data = 0, fd_res = 0;
4755 ccb = cam_getccb(device);
4758 warnx("scsicmd: error allocating ccb");
4762 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4764 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4768 while (isspace(*tstr) && (*tstr != '\0'))
4770 hook.argc = argc - optind;
4771 hook.argv = argv + optind;
4773 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4776 * Increment optind by the number of arguments the
4777 * encoding routine processed. After each call to
4778 * getopt(3), optind points to the argument that
4779 * getopt should process _next_. In this case,
4780 * that means it points to the first command string
4781 * argument, if there is one. Once we increment
4782 * this, it should point to either the next command
4783 * line argument, or it should be past the end of
4790 while (isspace(*tstr) && (*tstr != '\0'))
4792 hook.argc = argc - optind;
4793 hook.argv = argv + optind;
4795 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4798 * Increment optind by the number of arguments the
4799 * encoding routine processed. After each call to
4800 * getopt(3), optind points to the argument that
4801 * getopt should process _next_. In this case,
4802 * that means it points to the first command string
4803 * argument, if there is one. Once we increment
4804 * this, it should point to either the next command
4805 * line argument, or it should be past the end of
4817 if (arglist & CAM_ARG_CMD_OUT) {
4818 warnx("command must either be "
4819 "read or write, not both");
4821 goto scsicmd_bailout;
4823 arglist |= CAM_ARG_CMD_IN;
4825 data_bytes = strtol(optarg, NULL, 0);
4826 if (data_bytes <= 0) {
4827 warnx("invalid number of input bytes %d",
4830 goto scsicmd_bailout;
4832 hook.argc = argc - optind;
4833 hook.argv = argv + optind;
4836 datastr = cget(&hook, NULL);
4838 * If the user supplied "-" instead of a format, he
4839 * wants the data to be written to stdout.
4841 if ((datastr != NULL)
4842 && (datastr[0] == '-'))
4845 data_ptr = (u_int8_t *)malloc(data_bytes);
4846 if (data_ptr == NULL) {
4847 warnx("can't malloc memory for data_ptr");
4849 goto scsicmd_bailout;
4853 if (arglist & CAM_ARG_CMD_IN) {
4854 warnx("command must either be "
4855 "read or write, not both");
4857 goto scsicmd_bailout;
4859 arglist |= CAM_ARG_CMD_OUT;
4860 flags = CAM_DIR_OUT;
4861 data_bytes = strtol(optarg, NULL, 0);
4862 if (data_bytes <= 0) {
4863 warnx("invalid number of output bytes %d",
4866 goto scsicmd_bailout;
4868 hook.argc = argc - optind;
4869 hook.argv = argv + optind;
4871 datastr = cget(&hook, NULL);
4872 data_ptr = (u_int8_t *)malloc(data_bytes);
4873 if (data_ptr == NULL) {
4874 warnx("can't malloc memory for data_ptr");
4876 goto scsicmd_bailout;
4878 bzero(data_ptr, data_bytes);
4880 * If the user supplied "-" instead of a format, he
4881 * wants the data to be read from stdin.
4883 if ((datastr != NULL)
4884 && (datastr[0] == '-'))
4887 buff_encode_visit(data_ptr, data_bytes, datastr,
4893 hook.argc = argc - optind;
4894 hook.argv = argv + optind;
4896 resstr = cget(&hook, NULL);
4897 if ((resstr != NULL) && (resstr[0] == '-'))
4907 * If fd_data is set, and we're writing to the device, we need to
4908 * read the data the user wants written from stdin.
4910 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4912 int amt_to_read = data_bytes;
4913 u_int8_t *buf_ptr = data_ptr;
4915 for (amt_read = 0; amt_to_read > 0;
4916 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4917 if (amt_read == -1) {
4918 warn("error reading data from stdin");
4920 goto scsicmd_bailout;
4922 amt_to_read -= amt_read;
4923 buf_ptr += amt_read;
4927 if (arglist & CAM_ARG_ERR_RECOVER)
4928 flags |= CAM_PASS_ERR_RECOVER;
4930 /* Disable freezing the device queue */
4931 flags |= CAM_DEV_QFRZDIS;
4935 * This is taken from the SCSI-3 draft spec.
4936 * (T10/1157D revision 0.3)
4937 * The top 3 bits of an opcode are the group code.
4938 * The next 5 bits are the command code.
4939 * Group 0: six byte commands
4940 * Group 1: ten byte commands
4941 * Group 2: ten byte commands
4943 * Group 4: sixteen byte commands
4944 * Group 5: twelve byte commands
4945 * Group 6: vendor specific
4946 * Group 7: vendor specific
4948 switch((cdb[0] >> 5) & 0x7) {
4959 /* computed by buff_encode_visit */
4970 * We should probably use csio_build_visit or something like that
4971 * here, but it's easier to encode arguments as you go. The
4972 * alternative would be skipping the CDB argument and then encoding
4973 * it here, since we've got the data buffer argument by now.
4975 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4977 cam_fill_csio(&ccb->csio,
4978 /*retries*/ retry_count,
4981 /*tag_action*/ task_attr,
4982 /*data_ptr*/ data_ptr,
4983 /*dxfer_len*/ data_bytes,
4984 /*sense_len*/ SSD_FULL_SIZE,
4985 /*cdb_len*/ cdb_len,
4986 /*timeout*/ timeout ? timeout : 5000);
4989 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4991 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4993 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4995 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4997 cam_fill_ataio(&ccb->ataio,
4998 /*retries*/ retry_count,
5002 /*data_ptr*/ data_ptr,
5003 /*dxfer_len*/ data_bytes,
5004 /*timeout*/ timeout ? timeout : 5000);
5007 if (((retval = cam_send_ccb(device, ccb)) < 0)
5008 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
5009 const char warnstr[] = "error sending command";
5016 if (arglist & CAM_ARG_VERBOSE) {
5017 cam_error_print(device, ccb, CAM_ESF_ALL,
5018 CAM_EPF_ALL, stderr);
5022 goto scsicmd_bailout;
5025 if (atacmd_len && need_res) {
5027 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
5029 fprintf(stdout, "\n");
5032 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
5033 ccb->ataio.res.status,
5034 ccb->ataio.res.error,
5035 ccb->ataio.res.lba_low,
5036 ccb->ataio.res.lba_mid,
5037 ccb->ataio.res.lba_high,
5038 ccb->ataio.res.device,
5039 ccb->ataio.res.lba_low_exp,
5040 ccb->ataio.res.lba_mid_exp,
5041 ccb->ataio.res.lba_high_exp,
5042 ccb->ataio.res.sector_count,
5043 ccb->ataio.res.sector_count_exp);
5049 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
5051 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
5052 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
5053 && (arglist & CAM_ARG_CMD_IN)
5054 && (valid_bytes > 0)) {
5056 buff_decode_visit(data_ptr, valid_bytes, datastr,
5058 fprintf(stdout, "\n");
5060 ssize_t amt_written;
5061 int amt_to_write = valid_bytes;
5062 u_int8_t *buf_ptr = data_ptr;
5064 for (amt_written = 0; (amt_to_write > 0) &&
5065 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
5066 amt_to_write -= amt_written;
5067 buf_ptr += amt_written;
5069 if (amt_written == -1) {
5070 warn("error writing data to stdout");
5072 goto scsicmd_bailout;
5073 } else if ((amt_written == 0)
5074 && (amt_to_write > 0)) {
5075 warnx("only wrote %u bytes out of %u",
5076 valid_bytes - amt_to_write, valid_bytes);
5083 if ((data_bytes > 0) && (data_ptr != NULL))
5092 camdebug(int argc, char **argv, char *combinedopt)
5095 path_id_t bus = CAM_BUS_WILDCARD;
5096 target_id_t target = CAM_TARGET_WILDCARD;
5097 lun_id_t lun = CAM_LUN_WILDCARD;
5102 bzero(&ccb, sizeof(union ccb));
5104 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5107 arglist |= CAM_ARG_DEBUG_INFO;
5108 ccb.cdbg.flags |= CAM_DEBUG_INFO;
5111 arglist |= CAM_ARG_DEBUG_PERIPH;
5112 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
5115 arglist |= CAM_ARG_DEBUG_SUBTRACE;
5116 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
5119 arglist |= CAM_ARG_DEBUG_TRACE;
5120 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
5123 arglist |= CAM_ARG_DEBUG_XPT;
5124 ccb.cdbg.flags |= CAM_DEBUG_XPT;
5127 arglist |= CAM_ARG_DEBUG_CDB;
5128 ccb.cdbg.flags |= CAM_DEBUG_CDB;
5131 arglist |= CAM_ARG_DEBUG_PROBE;
5132 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
5143 warnx("you must specify \"off\", \"all\" or a bus,");
5144 warnx("bus:target, bus:target:lun or periph");
5149 while (isspace(*tstr) && (*tstr != '\0'))
5152 if (strncmp(tstr, "off", 3) == 0) {
5153 ccb.cdbg.flags = CAM_DEBUG_NONE;
5154 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
5155 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
5156 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
5158 rv = parse_btl(tstr, &bus, &target, &lun, &arglist);
5160 warnx("you must specify \"all\", \"off\", or a bus,");
5161 warnx("bus:target, bus:target:lun or periph to debug");
5166 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
5167 warnx("error opening transport layer device %s", XPT_DEVICE);
5168 warn("%s", XPT_DEVICE);
5172 ccb.ccb_h.func_code = XPT_DEBUG;
5173 ccb.ccb_h.path_id = bus;
5174 ccb.ccb_h.target_id = target;
5175 ccb.ccb_h.target_lun = lun;
5177 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
5178 warn("CAMIOCOMMAND ioctl failed");
5181 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
5182 CAM_FUNC_NOTAVAIL) {
5183 warnx("CAM debugging not available");
5184 warnx("you need to put options CAMDEBUG in"
5185 " your kernel config file!");
5187 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
5189 warnx("XPT_DEBUG CCB failed with status %#x",
5193 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
5195 "Debugging turned off\n");
5198 "Debugging enabled for "
5200 bus, target, (uintmax_t)lun);
5210 tagcontrol(struct cam_device *device, int argc, char **argv,
5220 ccb = cam_getccb(device);
5223 warnx("tagcontrol: error allocating ccb");
5227 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5230 numtags = strtol(optarg, NULL, 0);
5232 warnx("tag count %d is < 0", numtags);
5234 goto tagcontrol_bailout;
5245 cam_path_string(device, pathstr, sizeof(pathstr));
5248 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
5249 ccb->ccb_h.func_code = XPT_REL_SIMQ;
5250 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5251 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5252 ccb->crs.openings = numtags;
5255 if (cam_send_ccb(device, ccb) < 0) {
5256 perror("error sending XPT_REL_SIMQ CCB");
5258 goto tagcontrol_bailout;
5261 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5262 warnx("XPT_REL_SIMQ CCB failed");
5263 cam_error_print(device, ccb, CAM_ESF_ALL,
5264 CAM_EPF_ALL, stderr);
5266 goto tagcontrol_bailout;
5271 fprintf(stdout, "%stagged openings now %d\n",
5272 pathstr, ccb->crs.openings);
5275 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5277 ccb->ccb_h.func_code = XPT_GDEV_STATS;
5279 if (cam_send_ccb(device, ccb) < 0) {
5280 perror("error sending XPT_GDEV_STATS CCB");
5282 goto tagcontrol_bailout;
5285 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5286 warnx("XPT_GDEV_STATS CCB failed");
5287 cam_error_print(device, ccb, CAM_ESF_ALL,
5288 CAM_EPF_ALL, stderr);
5290 goto tagcontrol_bailout;
5293 if (arglist & CAM_ARG_VERBOSE) {
5294 fprintf(stdout, "%s", pathstr);
5295 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5296 fprintf(stdout, "%s", pathstr);
5297 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5298 fprintf(stdout, "%s", pathstr);
5299 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5300 fprintf(stdout, "%s", pathstr);
5301 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5302 fprintf(stdout, "%s", pathstr);
5303 fprintf(stdout, "held %d\n", ccb->cgds.held);
5304 fprintf(stdout, "%s", pathstr);
5305 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5306 fprintf(stdout, "%s", pathstr);
5307 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5310 fprintf(stdout, "%s", pathstr);
5311 fprintf(stdout, "device openings: ");
5313 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5314 ccb->cgds.dev_active);
5324 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5328 cam_path_string(device, pathstr, sizeof(pathstr));
5330 if (cts->transport == XPORT_SPI) {
5331 struct ccb_trans_settings_spi *spi =
5332 &cts->xport_specific.spi;
5334 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5336 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5339 if (spi->sync_offset != 0) {
5342 freq = scsi_calc_syncsrate(spi->sync_period);
5343 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5344 pathstr, freq / 1000, freq % 1000);
5348 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5349 fprintf(stdout, "%soffset: %d\n", pathstr,
5353 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5354 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5355 (0x01 << spi->bus_width) * 8);
5358 if (spi->valid & CTS_SPI_VALID_DISC) {
5359 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5360 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5361 "enabled" : "disabled");
5364 if (cts->transport == XPORT_FC) {
5365 struct ccb_trans_settings_fc *fc =
5366 &cts->xport_specific.fc;
5368 if (fc->valid & CTS_FC_VALID_WWNN)
5369 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5370 (long long) fc->wwnn);
5371 if (fc->valid & CTS_FC_VALID_WWPN)
5372 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5373 (long long) fc->wwpn);
5374 if (fc->valid & CTS_FC_VALID_PORT)
5375 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5376 if (fc->valid & CTS_FC_VALID_SPEED)
5377 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5378 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5380 if (cts->transport == XPORT_SAS) {
5381 struct ccb_trans_settings_sas *sas =
5382 &cts->xport_specific.sas;
5384 if (sas->valid & CTS_SAS_VALID_SPEED)
5385 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5386 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5388 if (cts->transport == XPORT_ATA) {
5389 struct ccb_trans_settings_pata *pata =
5390 &cts->xport_specific.ata;
5392 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5393 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5394 ata_mode2string(pata->mode));
5396 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5397 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5400 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5401 fprintf(stdout, "%sPIO transaction length: %d\n",
5402 pathstr, pata->bytecount);
5405 if (cts->transport == XPORT_SATA) {
5406 struct ccb_trans_settings_sata *sata =
5407 &cts->xport_specific.sata;
5409 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5410 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5413 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5414 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5415 ata_mode2string(sata->mode));
5417 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5418 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5421 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5422 fprintf(stdout, "%sPIO transaction length: %d\n",
5423 pathstr, sata->bytecount);
5425 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5426 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5429 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5430 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5433 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5434 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5438 if (cts->protocol == PROTO_ATA) {
5439 struct ccb_trans_settings_ata *ata=
5440 &cts->proto_specific.ata;
5442 if (ata->valid & CTS_ATA_VALID_TQ) {
5443 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5444 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5445 "enabled" : "disabled");
5448 if (cts->protocol == PROTO_SCSI) {
5449 struct ccb_trans_settings_scsi *scsi=
5450 &cts->proto_specific.scsi;
5452 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5453 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5454 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5455 "enabled" : "disabled");
5459 if (cts->protocol == PROTO_NVME) {
5460 struct ccb_trans_settings_nvme *nvmex =
5461 &cts->xport_specific.nvme;
5463 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5464 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5465 NVME_MAJOR(nvmex->spec),
5466 NVME_MINOR(nvmex->spec));
5468 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5469 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5470 nvmex->lanes, nvmex->max_lanes);
5471 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5472 nvmex->speed, nvmex->max_speed);
5479 * Get a path inquiry CCB for the specified device.
5482 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5487 ccb = cam_getccb(device);
5489 warnx("get_cpi: couldn't allocate CCB");
5492 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5493 ccb->ccb_h.func_code = XPT_PATH_INQ;
5494 if (cam_send_ccb(device, ccb) < 0) {
5495 warn("get_cpi: error sending Path Inquiry CCB");
5496 if (arglist & CAM_ARG_VERBOSE)
5497 cam_error_print(device, ccb, CAM_ESF_ALL,
5498 CAM_EPF_ALL, stderr);
5500 goto get_cpi_bailout;
5502 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5503 if (arglist & CAM_ARG_VERBOSE)
5504 cam_error_print(device, ccb, CAM_ESF_ALL,
5505 CAM_EPF_ALL, stderr);
5507 goto get_cpi_bailout;
5509 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5517 * Get a get device CCB for the specified device.
5520 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5525 ccb = cam_getccb(device);
5527 warnx("get_cgd: couldn't allocate CCB");
5530 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5531 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5532 if (cam_send_ccb(device, ccb) < 0) {
5533 warn("get_cgd: error sending Path Inquiry CCB");
5534 if (arglist & CAM_ARG_VERBOSE)
5535 cam_error_print(device, ccb, CAM_ESF_ALL,
5536 CAM_EPF_ALL, stderr);
5538 goto get_cgd_bailout;
5540 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5541 if (arglist & CAM_ARG_VERBOSE)
5542 cam_error_print(device, ccb, CAM_ESF_ALL,
5543 CAM_EPF_ALL, stderr);
5545 goto get_cgd_bailout;
5547 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5555 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5559 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5560 int timeout, int verbosemode)
5562 union ccb *ccb = NULL;
5563 struct scsi_vpd_supported_page_list sup_pages;
5567 ccb = cam_getccb(dev);
5569 warn("Unable to allocate CCB");
5574 /* cam_getccb cleans up the header, caller has to zero the payload */
5575 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5577 bzero(&sup_pages, sizeof(sup_pages));
5579 scsi_inquiry(&ccb->csio,
5580 /*retries*/ retry_count,
5582 /* tag_action */ MSG_SIMPLE_Q_TAG,
5583 /* inq_buf */ (u_int8_t *)&sup_pages,
5584 /* inq_len */ sizeof(sup_pages),
5586 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5587 /* sense_len */ SSD_FULL_SIZE,
5588 /* timeout */ timeout ? timeout : 5000);
5590 /* Disable freezing the device queue */
5591 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5593 if (retry_count != 0)
5594 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5596 if (cam_send_ccb(dev, ccb) < 0) {
5603 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5604 if (verbosemode != 0)
5605 cam_error_print(dev, ccb, CAM_ESF_ALL,
5606 CAM_EPF_ALL, stderr);
5611 for (i = 0; i < sup_pages.length; i++) {
5612 if (sup_pages.list[i] == page_id) {
5625 * devtype is filled in with the type of device.
5626 * Returns 0 for success, non-zero for failure.
5629 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5630 int verbosemode, camcontrol_devtype *devtype)
5632 struct ccb_getdev cgd;
5635 retval = get_cgd(dev, &cgd);
5639 switch (cgd.protocol) {
5645 *devtype = CC_DT_ATA;
5647 break; /*NOTREACHED*/
5649 *devtype = CC_DT_NVME;
5651 break; /*NOTREACHED*/
5653 *devtype = CC_DT_MMCSD;
5655 break; /*NOTREACHED*/
5657 *devtype = CC_DT_UNKNOWN;
5659 break; /*NOTREACHED*/
5662 if (retry_count == -1) {
5664 * For a retry count of -1, used only the cached data to avoid
5665 * I/O to the drive. Sending the identify command to the drive
5666 * can cause issues for SATL attachaed drives since identify is
5667 * not an NCQ command.
5669 if (cgd.ident_data.config != 0)
5670 *devtype = CC_DT_SATL;
5672 *devtype = CC_DT_SCSI;
5675 * Check for the ATA Information VPD page (0x89). If this is an
5676 * ATA device behind a SCSI to ATA translation layer (SATL),
5677 * this VPD page should be present.
5679 * If that VPD page isn't present, or we get an error back from
5680 * the INQUIRY command, we'll just treat it as a normal SCSI
5683 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5684 timeout, verbosemode);
5686 *devtype = CC_DT_SATL;
5688 *devtype = CC_DT_SCSI;
5697 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5698 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5699 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5700 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5701 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5702 int is48bit, camcontrol_devtype devtype)
5706 if (devtype == CC_DT_ATA) {
5707 cam_fill_ataio(&ccb->ataio,
5708 /*retries*/ retry_count,
5711 /*tag_action*/ tag_action,
5712 /*data_ptr*/ data_ptr,
5713 /*dxfer_len*/ dxfer_len,
5714 /*timeout*/ timeout);
5715 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5716 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5719 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5722 if (auxiliary != 0) {
5723 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5724 ccb->ataio.aux = auxiliary;
5727 if (ata_flags & AP_FLAG_CHK_COND)
5728 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5730 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5731 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5732 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5733 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5735 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5736 protocol |= AP_EXTEND;
5738 retval = scsi_ata_pass(&ccb->csio,
5739 /*retries*/ retry_count,
5742 /*tag_action*/ tag_action,
5743 /*protocol*/ protocol,
5744 /*ata_flags*/ ata_flags,
5745 /*features*/ features,
5746 /*sector_count*/ sector_count,
5748 /*command*/ command,
5751 /*auxiliary*/ auxiliary,
5753 /*data_ptr*/ data_ptr,
5754 /*dxfer_len*/ dxfer_len,
5755 /*cdb_storage*/ cdb_storage,
5756 /*cdb_storage_len*/ cdb_storage_len,
5757 /*minimum_cmd_size*/ 0,
5758 /*sense_len*/ sense_len,
5759 /*timeout*/ timeout);
5766 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5767 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5771 switch (ccb->ccb_h.func_code) {
5774 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5777 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5778 * or 16 byte, and need to see what
5780 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5781 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5783 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5784 if ((opcode != ATA_PASS_12)
5785 && (opcode != ATA_PASS_16)) {
5787 warnx("%s: unsupported opcode %02x", __func__, opcode);
5791 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5793 /* Note: the _ccb() variant returns 0 for an error */
5800 switch (error_code) {
5801 case SSD_DESC_CURRENT_ERROR:
5802 case SSD_DESC_DEFERRED_ERROR: {
5803 struct scsi_sense_data_desc *sense;
5804 struct scsi_sense_ata_ret_desc *desc;
5807 sense = (struct scsi_sense_data_desc *)
5808 &ccb->csio.sense_data;
5810 desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len -
5811 ccb->csio.sense_resid, SSD_DESC_ATA);
5812 if (desc_ptr == NULL) {
5813 cam_error_print(dev, ccb, CAM_ESF_ALL,
5814 CAM_EPF_ALL, stderr);
5818 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5820 *error = desc->error;
5821 *count = (desc->count_15_8 << 8) |
5823 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5824 ((uint64_t)desc->lba_39_32 << 32) |
5825 ((uint64_t)desc->lba_31_24 << 24) |
5826 (desc->lba_23_16 << 16) |
5827 (desc->lba_15_8 << 8) |
5829 *device = desc->device;
5830 *status = desc->status;
5833 * If the extend bit isn't set, the result is for a
5834 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5835 * command without the extend bit set. This means
5836 * that the device is supposed to return 28-bit
5837 * status. The count field is only 8 bits, and the
5838 * LBA field is only 8 bits.
5840 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5846 case SSD_CURRENT_ERROR:
5847 case SSD_DEFERRED_ERROR: {
5849 struct scsi_sense_data_fixed *sense;
5852 * XXX KDM need to support fixed sense data.
5854 warnx("%s: Fixed sense data not supported yet",
5858 break; /*NOTREACHED*/
5869 struct ata_res *res;
5872 * In this case, we have an ATA command, and we need to
5873 * fill in the requested values from the result register
5876 res = &ccb->ataio.res;
5877 *error = res->error;
5878 *status = res->status;
5879 *device = res->device;
5880 *count = res->sector_count;
5881 *lba = (res->lba_high << 16) |
5882 (res->lba_mid << 8) |
5884 if (res->flags & CAM_ATAIO_48BIT) {
5885 *count |= (res->sector_count_exp << 8);
5886 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5887 ((uint64_t)res->lba_mid_exp << 32) |
5888 ((uint64_t)res->lba_high_exp << 40);
5890 *lba |= (res->device & 0xf) << 24;
5903 cpi_print(struct ccb_pathinq *cpi)
5905 char adapter_str[1024];
5908 snprintf(adapter_str, sizeof(adapter_str),
5909 "%s%d:", cpi->dev_name, cpi->unit_number);
5911 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5914 for (i = 1; i < UINT8_MAX; i = i << 1) {
5917 if ((i & cpi->hba_inquiry) == 0)
5920 fprintf(stdout, "%s supports ", adapter_str);
5924 str = "MDP message";
5927 str = "32 bit wide SCSI";
5930 str = "16 bit wide SCSI";
5933 str = "SDTR message";
5936 str = "linked CDBs";
5939 str = "tag queue messages";
5942 str = "soft reset alternative";
5945 str = "SATA Port Multiplier";
5948 str = "unknown PI bit set";
5951 fprintf(stdout, "%s\n", str);
5954 for (i = 1; i < UINT32_MAX; i = i << 1) {
5957 if ((i & cpi->hba_misc) == 0)
5960 fprintf(stdout, "%s ", adapter_str);
5964 str = "can understand ata_ext requests";
5967 str = "64bit extended LUNs supported";
5970 str = "bus scans from high ID to low ID";
5973 str = "removable devices not included in scan";
5975 case PIM_NOINITIATOR:
5976 str = "initiator role not supported";
5978 case PIM_NOBUSRESET:
5979 str = "user has disabled initial BUS RESET or"
5980 " controller is in target/mixed mode";
5983 str = "do not send 6-byte commands";
5986 str = "scan bus sequentially";
5989 str = "unmapped I/O supported";
5992 str = "does its own scanning";
5995 str = "unknown PIM bit set";
5998 fprintf(stdout, "%s\n", str);
6001 for (i = 1; i < UINT16_MAX; i = i << 1) {
6004 if ((i & cpi->target_sprt) == 0)
6007 fprintf(stdout, "%s supports ", adapter_str);
6010 str = "target mode processor mode";
6013 str = "target mode phase cog. mode";
6015 case PIT_DISCONNECT:
6016 str = "disconnects in target mode";
6019 str = "terminate I/O message in target mode";
6022 str = "group 6 commands in target mode";
6025 str = "group 7 commands in target mode";
6028 str = "unknown PIT bit set";
6032 fprintf(stdout, "%s\n", str);
6034 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
6036 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
6038 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
6040 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
6041 adapter_str, cpi->hpath_id);
6042 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
6044 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
6045 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
6046 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
6047 adapter_str, cpi->hba_vendor);
6048 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
6049 adapter_str, cpi->hba_device);
6050 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
6051 adapter_str, cpi->hba_subvendor);
6052 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
6053 adapter_str, cpi->hba_subdevice);
6054 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
6055 fprintf(stdout, "%s base transfer speed: ", adapter_str);
6056 if (cpi->base_transfer_speed > 1000)
6057 fprintf(stdout, "%d.%03dMB/sec\n",
6058 cpi->base_transfer_speed / 1000,
6059 cpi->base_transfer_speed % 1000);
6061 fprintf(stdout, "%dKB/sec\n",
6062 (cpi->base_transfer_speed % 1000) * 1000);
6063 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
6064 adapter_str, cpi->maxio);
6068 get_print_cts(struct cam_device *device, int user_settings, int quiet,
6069 struct ccb_trans_settings *cts)
6075 ccb = cam_getccb(device);
6078 warnx("get_print_cts: error allocating ccb");
6082 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
6084 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
6086 if (user_settings == 0)
6087 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
6089 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
6091 if (cam_send_ccb(device, ccb) < 0) {
6092 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
6093 if (arglist & CAM_ARG_VERBOSE)
6094 cam_error_print(device, ccb, CAM_ESF_ALL,
6095 CAM_EPF_ALL, stderr);
6097 goto get_print_cts_bailout;
6100 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6101 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
6102 if (arglist & CAM_ARG_VERBOSE)
6103 cam_error_print(device, ccb, CAM_ESF_ALL,
6104 CAM_EPF_ALL, stderr);
6106 goto get_print_cts_bailout;
6110 cts_print(device, &ccb->cts);
6113 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
6115 get_print_cts_bailout:
6123 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
6124 int timeout, int argc, char **argv, char *combinedopt)
6128 int user_settings = 0;
6130 int disc_enable = -1, tag_enable = -1;
6133 double syncrate = -1;
6136 int change_settings = 0, send_tur = 0;
6137 struct ccb_pathinq cpi;
6139 ccb = cam_getccb(device);
6141 warnx("ratecontrol: error allocating ccb");
6144 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6153 if (strncasecmp(optarg, "enable", 6) == 0)
6155 else if (strncasecmp(optarg, "disable", 7) == 0)
6158 warnx("-D argument \"%s\" is unknown", optarg);
6160 goto ratecontrol_bailout;
6162 change_settings = 1;
6165 mode = ata_string2mode(optarg);
6167 warnx("unknown mode '%s'", optarg);
6169 goto ratecontrol_bailout;
6171 change_settings = 1;
6174 offset = strtol(optarg, NULL, 0);
6176 warnx("offset value %d is < 0", offset);
6178 goto ratecontrol_bailout;
6180 change_settings = 1;
6186 syncrate = atof(optarg);
6188 warnx("sync rate %f is < 0", syncrate);
6190 goto ratecontrol_bailout;
6192 change_settings = 1;
6195 if (strncasecmp(optarg, "enable", 6) == 0)
6197 else if (strncasecmp(optarg, "disable", 7) == 0)
6200 warnx("-T argument \"%s\" is unknown", optarg);
6202 goto ratecontrol_bailout;
6204 change_settings = 1;
6210 bus_width = strtol(optarg, NULL, 0);
6211 if (bus_width < 0) {
6212 warnx("bus width %d is < 0", bus_width);
6214 goto ratecontrol_bailout;
6216 change_settings = 1;
6222 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
6224 * Grab path inquiry information, so we can determine whether
6225 * or not the initiator is capable of the things that the user
6228 ccb->ccb_h.func_code = XPT_PATH_INQ;
6229 if (cam_send_ccb(device, ccb) < 0) {
6230 perror("error sending XPT_PATH_INQ CCB");
6231 if (arglist & CAM_ARG_VERBOSE) {
6232 cam_error_print(device, ccb, CAM_ESF_ALL,
6233 CAM_EPF_ALL, stderr);
6236 goto ratecontrol_bailout;
6238 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6239 warnx("XPT_PATH_INQ CCB failed");
6240 if (arglist & CAM_ARG_VERBOSE) {
6241 cam_error_print(device, ccb, CAM_ESF_ALL,
6242 CAM_EPF_ALL, stderr);
6245 goto ratecontrol_bailout;
6247 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
6248 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
6250 fprintf(stdout, "%s parameters:\n",
6251 user_settings ? "User" : "Current");
6253 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
6255 goto ratecontrol_bailout;
6257 if (arglist & CAM_ARG_VERBOSE)
6260 if (change_settings) {
6261 int didsettings = 0;
6262 struct ccb_trans_settings_spi *spi = NULL;
6263 struct ccb_trans_settings_pata *pata = NULL;
6264 struct ccb_trans_settings_sata *sata = NULL;
6265 struct ccb_trans_settings_ata *ata = NULL;
6266 struct ccb_trans_settings_scsi *scsi = NULL;
6268 if (ccb->cts.transport == XPORT_SPI)
6269 spi = &ccb->cts.xport_specific.spi;
6270 if (ccb->cts.transport == XPORT_ATA)
6271 pata = &ccb->cts.xport_specific.ata;
6272 if (ccb->cts.transport == XPORT_SATA)
6273 sata = &ccb->cts.xport_specific.sata;
6274 if (ccb->cts.protocol == PROTO_ATA)
6275 ata = &ccb->cts.proto_specific.ata;
6276 if (ccb->cts.protocol == PROTO_SCSI)
6277 scsi = &ccb->cts.proto_specific.scsi;
6278 ccb->cts.xport_specific.valid = 0;
6279 ccb->cts.proto_specific.valid = 0;
6280 if (spi && disc_enable != -1) {
6281 spi->valid |= CTS_SPI_VALID_DISC;
6282 if (disc_enable == 0)
6283 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6285 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6288 if (tag_enable != -1) {
6289 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6290 warnx("HBA does not support tagged queueing, "
6291 "so you cannot modify tag settings");
6293 goto ratecontrol_bailout;
6296 ata->valid |= CTS_SCSI_VALID_TQ;
6297 if (tag_enable == 0)
6298 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6300 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6303 scsi->valid |= CTS_SCSI_VALID_TQ;
6304 if (tag_enable == 0)
6305 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6307 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6311 if (spi && offset != -1) {
6312 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6313 warnx("HBA is not capable of changing offset");
6315 goto ratecontrol_bailout;
6317 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6318 spi->sync_offset = offset;
6321 if (spi && syncrate != -1) {
6322 int prelim_sync_period;
6324 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6325 warnx("HBA is not capable of changing "
6328 goto ratecontrol_bailout;
6330 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6332 * The sync rate the user gives us is in MHz.
6333 * We need to translate it into KHz for this
6338 * Next, we calculate a "preliminary" sync period
6339 * in tenths of a nanosecond.
6342 prelim_sync_period = 0;
6344 prelim_sync_period = 10000000 / syncrate;
6346 scsi_calc_syncparam(prelim_sync_period);
6349 if (sata && syncrate != -1) {
6350 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6351 warnx("HBA is not capable of changing "
6354 goto ratecontrol_bailout;
6356 if (!user_settings) {
6357 warnx("You can modify only user rate "
6358 "settings for SATA");
6360 goto ratecontrol_bailout;
6362 sata->revision = ata_speed2revision(syncrate * 100);
6363 if (sata->revision < 0) {
6364 warnx("Invalid rate %f", syncrate);
6366 goto ratecontrol_bailout;
6368 sata->valid |= CTS_SATA_VALID_REVISION;
6371 if ((pata || sata) && mode != -1) {
6372 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6373 warnx("HBA is not capable of changing "
6376 goto ratecontrol_bailout;
6378 if (!user_settings) {
6379 warnx("You can modify only user mode "
6380 "settings for ATA/SATA");
6382 goto ratecontrol_bailout;
6386 pata->valid |= CTS_ATA_VALID_MODE;
6389 sata->valid |= CTS_SATA_VALID_MODE;
6394 * The bus_width argument goes like this:
6398 * Therefore, if you shift the number of bits given on the
6399 * command line right by 4, you should get the correct
6402 if (spi && bus_width != -1) {
6404 * We might as well validate things here with a
6405 * decipherable error message, rather than what
6406 * will probably be an indecipherable error message
6407 * by the time it gets back to us.
6409 if ((bus_width == 16)
6410 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6411 warnx("HBA does not support 16 bit bus width");
6413 goto ratecontrol_bailout;
6414 } else if ((bus_width == 32)
6415 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6416 warnx("HBA does not support 32 bit bus width");
6418 goto ratecontrol_bailout;
6419 } else if ((bus_width != 8)
6420 && (bus_width != 16)
6421 && (bus_width != 32)) {
6422 warnx("Invalid bus width %d", bus_width);
6424 goto ratecontrol_bailout;
6426 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6427 spi->bus_width = bus_width >> 4;
6430 if (didsettings == 0) {
6431 goto ratecontrol_bailout;
6433 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6434 if (cam_send_ccb(device, ccb) < 0) {
6435 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
6436 if (arglist & CAM_ARG_VERBOSE) {
6437 cam_error_print(device, ccb, CAM_ESF_ALL,
6438 CAM_EPF_ALL, stderr);
6441 goto ratecontrol_bailout;
6443 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6444 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6445 if (arglist & CAM_ARG_VERBOSE) {
6446 cam_error_print(device, ccb, CAM_ESF_ALL,
6447 CAM_EPF_ALL, stderr);
6450 goto ratecontrol_bailout;
6454 retval = testunitready(device, task_attr, retry_count, timeout,
6455 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6457 * If the TUR didn't succeed, just bail.
6461 fprintf(stderr, "Test Unit Ready failed\n");
6462 goto ratecontrol_bailout;
6465 if ((change_settings || send_tur) && !quiet &&
6466 (ccb->cts.transport == XPORT_ATA ||
6467 ccb->cts.transport == XPORT_SATA || send_tur)) {
6468 fprintf(stdout, "New parameters:\n");
6469 retval = get_print_cts(device, user_settings, 0, NULL);
6472 ratecontrol_bailout:
6478 scsiformat(struct cam_device *device, int argc, char **argv,
6479 char *combinedopt, int task_attr, int retry_count, int timeout)
6483 int ycount = 0, quiet = 0;
6484 int error = 0, retval = 0;
6485 int use_timeout = 10800 * 1000;
6487 struct format_defect_list_header fh;
6488 u_int8_t *data_ptr = NULL;
6489 u_int32_t dxfer_len = 0;
6491 int num_warnings = 0;
6494 ccb = cam_getccb(device);
6497 warnx("scsiformat: error allocating ccb");
6501 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6503 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6524 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6525 "following device:\n");
6527 error = scsidoinquiry(device, argc, argv, combinedopt,
6528 task_attr, retry_count, timeout);
6531 warnx("scsiformat: error sending inquiry");
6532 goto scsiformat_bailout;
6537 if (!get_confirmation()) {
6539 goto scsiformat_bailout;
6544 use_timeout = timeout;
6547 fprintf(stdout, "Current format timeout is %d seconds\n",
6548 use_timeout / 1000);
6552 * If the user hasn't disabled questions and didn't specify a
6553 * timeout on the command line, ask them if they want the current
6557 && (timeout == 0)) {
6559 int new_timeout = 0;
6561 fprintf(stdout, "Enter new timeout in seconds or press\n"
6562 "return to keep the current timeout [%d] ",
6563 use_timeout / 1000);
6565 if (fgets(str, sizeof(str), stdin) != NULL) {
6567 new_timeout = atoi(str);
6570 if (new_timeout != 0) {
6571 use_timeout = new_timeout * 1000;
6572 fprintf(stdout, "Using new timeout value %d\n",
6573 use_timeout / 1000);
6578 * Keep this outside the if block below to silence any unused
6579 * variable warnings.
6581 bzero(&fh, sizeof(fh));
6584 * If we're in immediate mode, we've got to include the format
6587 if (immediate != 0) {
6588 fh.byte2 = FU_DLH_IMMED;
6589 data_ptr = (u_int8_t *)&fh;
6590 dxfer_len = sizeof(fh);
6591 byte2 = FU_FMT_DATA;
6592 } else if (quiet == 0) {
6593 fprintf(stdout, "Formatting...");
6597 scsi_format_unit(&ccb->csio,
6598 /* retries */ retry_count,
6600 /* tag_action */ task_attr,
6603 /* data_ptr */ data_ptr,
6604 /* dxfer_len */ dxfer_len,
6605 /* sense_len */ SSD_FULL_SIZE,
6606 /* timeout */ use_timeout);
6608 /* Disable freezing the device queue */
6609 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6611 if (arglist & CAM_ARG_ERR_RECOVER)
6612 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6614 if (((retval = cam_send_ccb(device, ccb)) < 0)
6615 || ((immediate == 0)
6616 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6617 const char errstr[] = "error sending format command";
6624 if (arglist & CAM_ARG_VERBOSE) {
6625 cam_error_print(device, ccb, CAM_ESF_ALL,
6626 CAM_EPF_ALL, stderr);
6629 goto scsiformat_bailout;
6633 * If we ran in non-immediate mode, we already checked for errors
6634 * above and printed out any necessary information. If we're in
6635 * immediate mode, we need to loop through and get status
6636 * information periodically.
6638 if (immediate == 0) {
6640 fprintf(stdout, "Format Complete\n");
6642 goto scsiformat_bailout;
6649 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6652 * There's really no need to do error recovery or
6653 * retries here, since we're just going to sit in a
6654 * loop and wait for the device to finish formatting.
6656 scsi_test_unit_ready(&ccb->csio,
6659 /* tag_action */ task_attr,
6660 /* sense_len */ SSD_FULL_SIZE,
6661 /* timeout */ 5000);
6663 /* Disable freezing the device queue */
6664 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6666 retval = cam_send_ccb(device, ccb);
6669 * If we get an error from the ioctl, bail out. SCSI
6670 * errors are expected.
6673 warn("error sending CAMIOCOMMAND ioctl");
6674 if (arglist & CAM_ARG_VERBOSE) {
6675 cam_error_print(device, ccb, CAM_ESF_ALL,
6676 CAM_EPF_ALL, stderr);
6679 goto scsiformat_bailout;
6682 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6684 if ((status != CAM_REQ_CMP)
6685 && (status == CAM_SCSI_STATUS_ERROR)
6686 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6687 struct scsi_sense_data *sense;
6688 int error_code, sense_key, asc, ascq;
6690 sense = &ccb->csio.sense_data;
6691 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6692 ccb->csio.sense_resid, &error_code, &sense_key,
6693 &asc, &ascq, /*show_errors*/ 1);
6696 * According to the SCSI-2 and SCSI-3 specs, a
6697 * drive that is in the middle of a format should
6698 * return NOT READY with an ASC of "logical unit
6699 * not ready, format in progress". The sense key
6700 * specific bytes will then be a progress indicator.
6702 if ((sense_key == SSD_KEY_NOT_READY)
6703 && (asc == 0x04) && (ascq == 0x04)) {
6706 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6707 ccb->csio.sense_resid, sks) == 0)
6710 u_int64_t percentage;
6712 val = scsi_2btoul(&sks[1]);
6713 percentage = 10000ull * val;
6716 "\rFormatting: %ju.%02u %% "
6718 (uintmax_t)(percentage /
6720 (unsigned)((percentage /
6724 } else if ((quiet == 0)
6725 && (++num_warnings <= 1)) {
6726 warnx("Unexpected SCSI Sense Key "
6727 "Specific value returned "
6729 scsi_sense_print(device, &ccb->csio,
6731 warnx("Unable to print status "
6732 "information, but format will "
6734 warnx("will exit when format is "
6739 warnx("Unexpected SCSI error during format");
6740 cam_error_print(device, ccb, CAM_ESF_ALL,
6741 CAM_EPF_ALL, stderr);
6743 goto scsiformat_bailout;
6746 } else if (status != CAM_REQ_CMP) {
6747 warnx("Unexpected CAM status %#x", status);
6748 if (arglist & CAM_ARG_VERBOSE)
6749 cam_error_print(device, ccb, CAM_ESF_ALL,
6750 CAM_EPF_ALL, stderr);
6752 goto scsiformat_bailout;
6755 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6758 fprintf(stdout, "\nFormat Complete\n");
6768 scsisanitize(struct cam_device *device, int argc, char **argv,
6769 char *combinedopt, int task_attr, int retry_count, int timeout)
6772 u_int8_t action = 0;
6774 int ycount = 0, quiet = 0;
6775 int error = 0, retval = 0;
6776 int use_timeout = 10800 * 1000;
6782 const char *pattern = NULL;
6783 u_int8_t *data_ptr = NULL;
6784 u_int32_t dxfer_len = 0;
6786 int num_warnings = 0;
6789 ccb = cam_getccb(device);
6792 warnx("scsisanitize: error allocating ccb");
6796 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6798 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6801 if (strcasecmp(optarg, "overwrite") == 0)
6802 action = SSZ_SERVICE_ACTION_OVERWRITE;
6803 else if (strcasecmp(optarg, "block") == 0)
6804 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6805 else if (strcasecmp(optarg, "crypto") == 0)
6806 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6807 else if (strcasecmp(optarg, "exitfailure") == 0)
6808 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6810 warnx("invalid service operation \"%s\"",
6813 goto scsisanitize_bailout;
6817 passes = strtol(optarg, NULL, 0);
6818 if (passes < 1 || passes > 31) {
6819 warnx("invalid passes value %d", passes);
6821 goto scsisanitize_bailout;
6852 warnx("an action is required");
6854 goto scsisanitize_bailout;
6855 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6856 struct scsi_sanitize_parameter_list *pl;
6860 if (pattern == NULL) {
6861 warnx("overwrite action requires -P argument");
6863 goto scsisanitize_bailout;
6865 fd = open(pattern, O_RDONLY);
6867 warn("cannot open pattern file %s", pattern);
6869 goto scsisanitize_bailout;
6871 if (fstat(fd, &sb) < 0) {
6872 warn("cannot stat pattern file %s", pattern);
6874 goto scsisanitize_bailout;
6877 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6878 warnx("pattern file size exceeds maximum value %d",
6879 SSZPL_MAX_PATTERN_LENGTH);
6881 goto scsisanitize_bailout;
6883 dxfer_len = sizeof(*pl) + sz;
6884 data_ptr = calloc(1, dxfer_len);
6885 if (data_ptr == NULL) {
6886 warnx("cannot allocate parameter list buffer");
6888 goto scsisanitize_bailout;
6891 amt = read(fd, data_ptr + sizeof(*pl), sz);
6893 warn("cannot read pattern file");
6895 goto scsisanitize_bailout;
6896 } else if (amt != sz) {
6897 warnx("short pattern file read");
6899 goto scsisanitize_bailout;
6902 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6908 pl->byte1 |= SSZPL_INVERT;
6909 scsi_ulto2b(sz, pl->length);
6915 else if (invert != 0)
6917 else if (pattern != NULL)
6922 warnx("%s argument only valid with overwrite "
6925 goto scsisanitize_bailout;
6930 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6931 "following device:\n");
6933 error = scsidoinquiry(device, argc, argv, combinedopt,
6934 task_attr, retry_count, timeout);
6937 warnx("scsisanitize: error sending inquiry");
6938 goto scsisanitize_bailout;
6943 if (!get_confirmation()) {
6945 goto scsisanitize_bailout;
6950 use_timeout = timeout;
6953 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6954 use_timeout / 1000);
6958 * If the user hasn't disabled questions and didn't specify a
6959 * timeout on the command line, ask them if they want the current
6963 && (timeout == 0)) {
6965 int new_timeout = 0;
6967 fprintf(stdout, "Enter new timeout in seconds or press\n"
6968 "return to keep the current timeout [%d] ",
6969 use_timeout / 1000);
6971 if (fgets(str, sizeof(str), stdin) != NULL) {
6973 new_timeout = atoi(str);
6976 if (new_timeout != 0) {
6977 use_timeout = new_timeout * 1000;
6978 fprintf(stdout, "Using new timeout value %d\n",
6979 use_timeout / 1000);
6985 byte2 |= SSZ_UNRESTRICTED_EXIT;
6989 scsi_sanitize(&ccb->csio,
6990 /* retries */ retry_count,
6992 /* tag_action */ task_attr,
6995 /* data_ptr */ data_ptr,
6996 /* dxfer_len */ dxfer_len,
6997 /* sense_len */ SSD_FULL_SIZE,
6998 /* timeout */ use_timeout);
7000 /* Disable freezing the device queue */
7001 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7003 if (arglist & CAM_ARG_ERR_RECOVER)
7004 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7006 if (cam_send_ccb(device, ccb) < 0) {
7007 warn("error sending sanitize command");
7009 goto scsisanitize_bailout;
7012 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7013 struct scsi_sense_data *sense;
7014 int error_code, sense_key, asc, ascq;
7016 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
7017 CAM_SCSI_STATUS_ERROR) {
7018 sense = &ccb->csio.sense_data;
7019 scsi_extract_sense_len(sense, ccb->csio.sense_len -
7020 ccb->csio.sense_resid, &error_code, &sense_key,
7021 &asc, &ascq, /*show_errors*/ 1);
7023 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
7024 asc == 0x20 && ascq == 0x00)
7025 warnx("sanitize is not supported by "
7028 warnx("error sanitizing this device");
7030 warnx("error sanitizing this device");
7032 if (arglist & CAM_ARG_VERBOSE) {
7033 cam_error_print(device, ccb, CAM_ESF_ALL,
7034 CAM_EPF_ALL, stderr);
7037 goto scsisanitize_bailout;
7041 * If we ran in non-immediate mode, we already checked for errors
7042 * above and printed out any necessary information. If we're in
7043 * immediate mode, we need to loop through and get status
7044 * information periodically.
7046 if (immediate == 0) {
7048 fprintf(stdout, "Sanitize Complete\n");
7050 goto scsisanitize_bailout;
7057 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7060 * There's really no need to do error recovery or
7061 * retries here, since we're just going to sit in a
7062 * loop and wait for the device to finish sanitizing.
7064 scsi_test_unit_ready(&ccb->csio,
7067 /* tag_action */ task_attr,
7068 /* sense_len */ SSD_FULL_SIZE,
7069 /* timeout */ 5000);
7071 /* Disable freezing the device queue */
7072 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7074 retval = cam_send_ccb(device, ccb);
7077 * If we get an error from the ioctl, bail out. SCSI
7078 * errors are expected.
7081 warn("error sending CAMIOCOMMAND ioctl");
7082 if (arglist & CAM_ARG_VERBOSE) {
7083 cam_error_print(device, ccb, CAM_ESF_ALL,
7084 CAM_EPF_ALL, stderr);
7087 goto scsisanitize_bailout;
7090 status = ccb->ccb_h.status & CAM_STATUS_MASK;
7092 if ((status != CAM_REQ_CMP)
7093 && (status == CAM_SCSI_STATUS_ERROR)
7094 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
7095 struct scsi_sense_data *sense;
7096 int error_code, sense_key, asc, ascq;
7098 sense = &ccb->csio.sense_data;
7099 scsi_extract_sense_len(sense, ccb->csio.sense_len -
7100 ccb->csio.sense_resid, &error_code, &sense_key,
7101 &asc, &ascq, /*show_errors*/ 1);
7104 * According to the SCSI-3 spec, a drive that is in the
7105 * middle of a sanitize should return NOT READY with an
7106 * ASC of "logical unit not ready, sanitize in
7107 * progress". The sense key specific bytes will then
7108 * be a progress indicator.
7110 if ((sense_key == SSD_KEY_NOT_READY)
7111 && (asc == 0x04) && (ascq == 0x1b)) {
7114 if ((scsi_get_sks(sense, ccb->csio.sense_len -
7115 ccb->csio.sense_resid, sks) == 0)
7118 u_int64_t percentage;
7120 val = scsi_2btoul(&sks[1]);
7121 percentage = 10000 * val;
7124 "\rSanitizing: %ju.%02u %% "
7126 (uintmax_t)(percentage /
7128 (unsigned)((percentage /
7132 } else if ((quiet == 0)
7133 && (++num_warnings <= 1)) {
7134 warnx("Unexpected SCSI Sense Key "
7135 "Specific value returned "
7136 "during sanitize:");
7137 scsi_sense_print(device, &ccb->csio,
7139 warnx("Unable to print status "
7140 "information, but sanitze will "
7142 warnx("will exit when sanitize is "
7147 warnx("Unexpected SCSI error during sanitize");
7148 cam_error_print(device, ccb, CAM_ESF_ALL,
7149 CAM_EPF_ALL, stderr);
7151 goto scsisanitize_bailout;
7154 } else if (status != CAM_REQ_CMP) {
7155 warnx("Unexpected CAM status %#x", status);
7156 if (arglist & CAM_ARG_VERBOSE)
7157 cam_error_print(device, ccb, CAM_ESF_ALL,
7158 CAM_EPF_ALL, stderr);
7160 goto scsisanitize_bailout;
7162 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
7165 fprintf(stdout, "\nSanitize Complete\n");
7167 scsisanitize_bailout:
7170 if (data_ptr != NULL)
7178 scsireportluns(struct cam_device *device, int argc, char **argv,
7179 char *combinedopt, int task_attr, int retry_count, int timeout)
7182 int c, countonly, lunsonly;
7183 struct scsi_report_luns_data *lundata;
7185 uint8_t report_type;
7186 uint32_t list_len, i, j;
7191 report_type = RPL_REPORT_DEFAULT;
7192 ccb = cam_getccb(device);
7195 warnx("%s: error allocating ccb", __func__);
7199 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7204 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7213 if (strcasecmp(optarg, "default") == 0)
7214 report_type = RPL_REPORT_DEFAULT;
7215 else if (strcasecmp(optarg, "wellknown") == 0)
7216 report_type = RPL_REPORT_WELLKNOWN;
7217 else if (strcasecmp(optarg, "all") == 0)
7218 report_type = RPL_REPORT_ALL;
7220 warnx("%s: invalid report type \"%s\"",
7231 if ((countonly != 0)
7232 && (lunsonly != 0)) {
7233 warnx("%s: you can only specify one of -c or -l", __func__);
7238 * According to SPC-4, the allocation length must be at least 16
7239 * bytes -- enough for the header and one LUN.
7241 alloc_len = sizeof(*lundata) + 8;
7245 lundata = malloc(alloc_len);
7247 if (lundata == NULL) {
7248 warn("%s: error mallocing %d bytes", __func__, alloc_len);
7253 scsi_report_luns(&ccb->csio,
7254 /*retries*/ retry_count,
7256 /*tag_action*/ task_attr,
7257 /*select_report*/ report_type,
7258 /*rpl_buf*/ lundata,
7259 /*alloc_len*/ alloc_len,
7260 /*sense_len*/ SSD_FULL_SIZE,
7261 /*timeout*/ timeout ? timeout : 5000);
7263 /* Disable freezing the device queue */
7264 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7266 if (arglist & CAM_ARG_ERR_RECOVER)
7267 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7269 if (cam_send_ccb(device, ccb) < 0) {
7270 warn("error sending REPORT LUNS command");
7272 if (arglist & CAM_ARG_VERBOSE)
7273 cam_error_print(device, ccb, CAM_ESF_ALL,
7274 CAM_EPF_ALL, stderr);
7280 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7281 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7287 list_len = scsi_4btoul(lundata->length);
7290 * If we need to list the LUNs, and our allocation
7291 * length was too short, reallocate and retry.
7293 if ((countonly == 0)
7294 && (list_len > (alloc_len - sizeof(*lundata)))) {
7295 alloc_len = list_len + sizeof(*lundata);
7301 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7302 ((list_len / 8) > 1) ? "s" : "");
7307 for (i = 0; i < (list_len / 8); i++) {
7311 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7313 fprintf(stdout, ",");
7314 switch (lundata->luns[i].lundata[j] &
7315 RPL_LUNDATA_ATYP_MASK) {
7316 case RPL_LUNDATA_ATYP_PERIPH:
7317 if ((lundata->luns[i].lundata[j] &
7318 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7319 fprintf(stdout, "%d:",
7320 lundata->luns[i].lundata[j] &
7321 RPL_LUNDATA_PERIPH_BUS_MASK);
7323 && ((lundata->luns[i].lundata[j+2] &
7324 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7327 fprintf(stdout, "%d",
7328 lundata->luns[i].lundata[j+1]);
7330 case RPL_LUNDATA_ATYP_FLAT: {
7332 tmplun[0] = lundata->luns[i].lundata[j] &
7333 RPL_LUNDATA_FLAT_LUN_MASK;
7334 tmplun[1] = lundata->luns[i].lundata[j+1];
7336 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7340 case RPL_LUNDATA_ATYP_LUN:
7341 fprintf(stdout, "%d:%d:%d",
7342 (lundata->luns[i].lundata[j+1] &
7343 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7344 lundata->luns[i].lundata[j] &
7345 RPL_LUNDATA_LUN_TARG_MASK,
7346 lundata->luns[i].lundata[j+1] &
7347 RPL_LUNDATA_LUN_LUN_MASK);
7349 case RPL_LUNDATA_ATYP_EXTLUN: {
7350 int field_len_code, eam_code;
7352 eam_code = lundata->luns[i].lundata[j] &
7353 RPL_LUNDATA_EXT_EAM_MASK;
7354 field_len_code = (lundata->luns[i].lundata[j] &
7355 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7357 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7358 && (field_len_code == 0x00)) {
7359 fprintf(stdout, "%d",
7360 lundata->luns[i].lundata[j+1]);
7361 } else if ((eam_code ==
7362 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7363 && (field_len_code == 0x03)) {
7367 * This format takes up all 8 bytes.
7368 * If we aren't starting at offset 0,
7372 fprintf(stdout, "Invalid "
7375 "specified format", j);
7379 bzero(tmp_lun, sizeof(tmp_lun));
7380 bcopy(&lundata->luns[i].lundata[j+1],
7381 &tmp_lun[1], sizeof(tmp_lun) - 1);
7382 fprintf(stdout, "%#jx",
7383 (intmax_t)scsi_8btou64(tmp_lun));
7386 fprintf(stderr, "Unknown Extended LUN"
7387 "Address method %#x, length "
7388 "code %#x", eam_code,
7395 fprintf(stderr, "Unknown LUN address method "
7396 "%#x\n", lundata->luns[i].lundata[0] &
7397 RPL_LUNDATA_ATYP_MASK);
7401 * For the flat addressing method, there are no
7402 * other levels after it.
7407 fprintf(stdout, "\n");
7420 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7421 char *combinedopt, int task_attr, int retry_count, int timeout)
7424 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7425 struct scsi_read_capacity_data rcap;
7426 struct scsi_read_capacity_data_long rcaplong;
7441 ccb = cam_getccb(device);
7444 warnx("%s: error allocating ccb", __func__);
7448 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7450 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7480 if ((blocksizeonly != 0)
7481 && (numblocks != 0)) {
7482 warnx("%s: you can only specify one of -b or -N", __func__);
7487 if ((blocksizeonly != 0)
7488 && (sizeonly != 0)) {
7489 warnx("%s: you can only specify one of -b or -s", __func__);
7496 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7502 && (blocksizeonly != 0)) {
7503 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7511 scsi_read_capacity(&ccb->csio,
7512 /*retries*/ retry_count,
7514 /*tag_action*/ task_attr,
7517 /*timeout*/ timeout ? timeout : 5000);
7519 /* Disable freezing the device queue */
7520 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7522 if (arglist & CAM_ARG_ERR_RECOVER)
7523 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7525 if (cam_send_ccb(device, ccb) < 0) {
7526 warn("error sending READ CAPACITY command");
7528 if (arglist & CAM_ARG_VERBOSE)
7529 cam_error_print(device, ccb, CAM_ESF_ALL,
7530 CAM_EPF_ALL, stderr);
7536 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7537 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7542 maxsector = scsi_4btoul(rcap.addr);
7543 block_len = scsi_4btoul(rcap.length);
7546 * A last block of 2^32-1 means that the true capacity is over 2TB,
7547 * and we need to issue the long READ CAPACITY to get the real
7548 * capacity. Otherwise, we're all set.
7550 if (maxsector != 0xffffffff)
7554 scsi_read_capacity_16(&ccb->csio,
7555 /*retries*/ retry_count,
7557 /*tag_action*/ task_attr,
7561 /*rcap_buf*/ (uint8_t *)&rcaplong,
7562 /*rcap_buf_len*/ sizeof(rcaplong),
7563 /*sense_len*/ SSD_FULL_SIZE,
7564 /*timeout*/ timeout ? timeout : 5000);
7566 /* Disable freezing the device queue */
7567 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7569 if (arglist & CAM_ARG_ERR_RECOVER)
7570 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7572 if (cam_send_ccb(device, ccb) < 0) {
7573 warn("error sending READ CAPACITY (16) command");
7575 if (arglist & CAM_ARG_VERBOSE)
7576 cam_error_print(device, ccb, CAM_ESF_ALL,
7577 CAM_EPF_ALL, stderr);
7583 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7584 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7589 maxsector = scsi_8btou64(rcaplong.addr);
7590 block_len = scsi_4btoul(rcaplong.length);
7593 if (blocksizeonly == 0) {
7595 * Humanize implies !quiet, and also implies numblocks.
7597 if (humanize != 0) {
7602 tmpbytes = (maxsector + 1) * block_len;
7603 ret = humanize_number(tmpstr, sizeof(tmpstr),
7604 tmpbytes, "", HN_AUTOSCALE,
7607 HN_DIVISOR_1000 : 0));
7609 warnx("%s: humanize_number failed!", __func__);
7613 fprintf(stdout, "Device Size: %s%s", tmpstr,
7614 (sizeonly == 0) ? ", " : "\n");
7615 } else if (numblocks != 0) {
7616 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7617 "Blocks: " : "", (uintmax_t)maxsector + 1,
7618 (sizeonly == 0) ? ", " : "\n");
7620 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7621 "Last Block: " : "", (uintmax_t)maxsector,
7622 (sizeonly == 0) ? ", " : "\n");
7626 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7627 "Block Length: " : "", block_len, (quiet == 0) ?
7636 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7637 int retry_count, int timeout)
7641 uint8_t *smp_request = NULL, *smp_response = NULL;
7642 int request_size = 0, response_size = 0;
7643 int fd_request = 0, fd_response = 0;
7644 char *datastr = NULL;
7645 struct get_hook hook;
7650 * Note that at the moment we don't support sending SMP CCBs to
7651 * devices that aren't probed by CAM.
7653 ccb = cam_getccb(device);
7655 warnx("%s: error allocating CCB", __func__);
7659 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7661 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7664 arglist |= CAM_ARG_CMD_IN;
7665 response_size = strtol(optarg, NULL, 0);
7666 if (response_size <= 0) {
7667 warnx("invalid number of response bytes %d",
7670 goto smpcmd_bailout;
7672 hook.argc = argc - optind;
7673 hook.argv = argv + optind;
7676 datastr = cget(&hook, NULL);
7678 * If the user supplied "-" instead of a format, he
7679 * wants the data to be written to stdout.
7681 if ((datastr != NULL)
7682 && (datastr[0] == '-'))
7685 smp_response = (u_int8_t *)malloc(response_size);
7686 if (smp_response == NULL) {
7687 warn("can't malloc memory for SMP response");
7689 goto smpcmd_bailout;
7693 arglist |= CAM_ARG_CMD_OUT;
7694 request_size = strtol(optarg, NULL, 0);
7695 if (request_size <= 0) {
7696 warnx("invalid number of request bytes %d",
7699 goto smpcmd_bailout;
7701 hook.argc = argc - optind;
7702 hook.argv = argv + optind;
7704 datastr = cget(&hook, NULL);
7705 smp_request = (u_int8_t *)malloc(request_size);
7706 if (smp_request == NULL) {
7707 warn("can't malloc memory for SMP request");
7709 goto smpcmd_bailout;
7711 bzero(smp_request, request_size);
7713 * If the user supplied "-" instead of a format, he
7714 * wants the data to be read from stdin.
7716 if ((datastr != NULL)
7717 && (datastr[0] == '-'))
7720 buff_encode_visit(smp_request, request_size,
7731 * If fd_data is set, and we're writing to the device, we need to
7732 * read the data the user wants written from stdin.
7734 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7736 int amt_to_read = request_size;
7737 u_int8_t *buf_ptr = smp_request;
7739 for (amt_read = 0; amt_to_read > 0;
7740 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7741 if (amt_read == -1) {
7742 warn("error reading data from stdin");
7744 goto smpcmd_bailout;
7746 amt_to_read -= amt_read;
7747 buf_ptr += amt_read;
7751 if (((arglist & CAM_ARG_CMD_IN) == 0)
7752 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7753 warnx("%s: need both the request (-r) and response (-R) "
7754 "arguments", __func__);
7756 goto smpcmd_bailout;
7759 flags |= CAM_DEV_QFRZDIS;
7761 cam_fill_smpio(&ccb->smpio,
7762 /*retries*/ retry_count,
7765 /*smp_request*/ smp_request,
7766 /*smp_request_len*/ request_size,
7767 /*smp_response*/ smp_response,
7768 /*smp_response_len*/ response_size,
7769 /*timeout*/ timeout ? timeout : 5000);
7771 ccb->smpio.flags = SMP_FLAG_NONE;
7773 if (((retval = cam_send_ccb(device, ccb)) < 0)
7774 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7775 const char warnstr[] = "error sending command";
7782 if (arglist & CAM_ARG_VERBOSE) {
7783 cam_error_print(device, ccb, CAM_ESF_ALL,
7784 CAM_EPF_ALL, stderr);
7788 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7789 && (response_size > 0)) {
7790 if (fd_response == 0) {
7791 buff_decode_visit(smp_response, response_size,
7792 datastr, arg_put, NULL);
7793 fprintf(stdout, "\n");
7795 ssize_t amt_written;
7796 int amt_to_write = response_size;
7797 u_int8_t *buf_ptr = smp_response;
7799 for (amt_written = 0; (amt_to_write > 0) &&
7800 (amt_written = write(STDOUT_FILENO, buf_ptr,
7801 amt_to_write)) > 0;){
7802 amt_to_write -= amt_written;
7803 buf_ptr += amt_written;
7805 if (amt_written == -1) {
7806 warn("error writing data to stdout");
7808 goto smpcmd_bailout;
7809 } else if ((amt_written == 0)
7810 && (amt_to_write > 0)) {
7811 warnx("only wrote %u bytes out of %u",
7812 response_size - amt_to_write,
7821 if (smp_request != NULL)
7824 if (smp_response != NULL)
7831 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7832 int retry_count, int timeout)
7836 int32_t mmc_opcode = 0, mmc_arg = 0;
7837 int32_t mmc_flags = -1;
7840 int is_bw_4 = 0, is_bw_1 = 0;
7841 int is_highspeed = 0, is_stdspeed = 0;
7842 int is_info_request = 0;
7844 uint8_t mmc_data_byte = 0;
7846 /* For IO_RW_EXTENDED command */
7847 uint8_t *mmc_data = NULL;
7848 struct mmc_data mmc_d;
7849 int mmc_data_len = 0;
7852 * Note that at the moment we don't support sending SMP CCBs to
7853 * devices that aren't probed by CAM.
7855 ccb = cam_getccb(device);
7857 warnx("%s: error allocating CCB", __func__);
7861 bzero(&(&ccb->ccb_h)[1],
7862 sizeof(union ccb) - sizeof(struct ccb_hdr));
7864 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7873 if (!strcmp(optarg, "high"))
7879 is_info_request = 1;
7882 mmc_opcode = strtol(optarg, NULL, 0);
7883 if (mmc_opcode < 0) {
7884 warnx("invalid MMC opcode %d",
7887 goto mmccmd_bailout;
7891 mmc_arg = strtol(optarg, NULL, 0);
7893 warnx("invalid MMC arg %d",
7896 goto mmccmd_bailout;
7900 mmc_flags = strtol(optarg, NULL, 0);
7901 if (mmc_flags < 0) {
7902 warnx("invalid MMC flags %d",
7905 goto mmccmd_bailout;
7909 mmc_data_len = strtol(optarg, NULL, 0);
7910 if (mmc_data_len <= 0) {
7911 warnx("invalid MMC data len %d",
7914 goto mmccmd_bailout;
7921 mmc_data_byte = strtol(optarg, NULL, 0);
7927 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7929 /* If flags are left default, supply the right flags */
7931 switch (mmc_opcode) {
7932 case MMC_GO_IDLE_STATE:
7933 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7935 case IO_SEND_OP_COND:
7936 mmc_flags = MMC_RSP_R4;
7938 case SD_SEND_RELATIVE_ADDR:
7939 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7941 case MMC_SELECT_CARD:
7942 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7943 mmc_arg = mmc_arg << 16;
7945 case SD_IO_RW_DIRECT:
7946 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7947 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7949 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7951 case SD_IO_RW_EXTENDED:
7952 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7953 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7954 int len_arg = mmc_data_len;
7955 if (mmc_data_len == 512)
7959 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7961 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7964 mmc_flags = MMC_RSP_R1;
7968 // Switch bus width instead of sending IO command
7969 if (is_bw_4 || is_bw_1) {
7970 struct ccb_trans_settings_mmc *cts;
7971 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7972 ccb->ccb_h.flags = 0;
7973 cts = &ccb->cts.proto_specific.mmc;
7974 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7975 cts->ios_valid = MMC_BW;
7976 if (((retval = cam_send_ccb(device, ccb)) < 0)
7977 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7978 warn("Error sending command");
7980 printf("Parameters set OK\n");
7986 // Switch bus speed instead of sending IO command
7987 if (is_stdspeed || is_highspeed) {
7988 struct ccb_trans_settings_mmc *cts;
7989 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7990 ccb->ccb_h.flags = 0;
7991 cts = &ccb->cts.proto_specific.mmc;
7992 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
7993 cts->ios_valid = MMC_BT;
7994 if (((retval = cam_send_ccb(device, ccb)) < 0)
7995 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7996 warn("Error sending command");
7998 printf("Speed set OK (HS: %d)\n", is_highspeed);
8004 // Get information about controller and its settings
8005 if (is_info_request) {
8006 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
8007 ccb->ccb_h.flags = 0;
8008 struct ccb_trans_settings_mmc *cts;
8009 cts = &ccb->cts.proto_specific.mmc;
8010 if (((retval = cam_send_ccb(device, ccb)) < 0)
8011 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8012 warn("Error sending command");
8015 printf("Host controller information\n");
8016 printf("Host OCR: 0x%x\n", cts->host_ocr);
8017 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
8018 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
8019 printf("Supported bus width: ");
8020 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
8022 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
8024 printf("\nCurrent settings:\n");
8025 printf("Bus width: ");
8026 switch (cts->ios.bus_width) {
8037 printf("Freq: %d.%03d MHz%s\n",
8038 cts->ios.clock / 1000000,
8039 (cts->ios.clock / 1000) % 1000,
8040 cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : "");
8044 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
8046 if (mmc_data_len > 0) {
8047 flags |= CAM_DIR_IN;
8048 mmc_data = malloc(mmc_data_len);
8049 memset(mmc_data, 0, mmc_data_len);
8050 mmc_d.len = mmc_data_len;
8051 mmc_d.data = mmc_data;
8052 mmc_d.flags = MMC_DATA_READ;
8053 } else flags |= CAM_DIR_NONE;
8055 cam_fill_mmcio(&ccb->mmcio,
8056 /*retries*/ retry_count,
8059 /*mmc_opcode*/ mmc_opcode,
8060 /*mmc_arg*/ mmc_arg,
8061 /*mmc_flags*/ mmc_flags,
8062 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
8063 /*timeout*/ timeout ? timeout : 5000);
8065 if (((retval = cam_send_ccb(device, ccb)) < 0)
8066 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8067 const char warnstr[] = "error sending command";
8074 if (arglist & CAM_ARG_VERBOSE) {
8075 cam_error_print(device, ccb, CAM_ESF_ALL,
8076 CAM_EPF_ALL, stderr);
8080 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
8081 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
8082 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
8083 ccb->mmcio.cmd.resp[1],
8084 ccb->mmcio.cmd.resp[2],
8085 ccb->mmcio.cmd.resp[3]);
8087 switch (mmc_opcode) {
8088 case SD_IO_RW_DIRECT:
8089 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
8090 SD_R5_DATA(ccb->mmcio.cmd.resp),
8091 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
8093 case SD_IO_RW_EXTENDED:
8094 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
8095 hexdump(mmc_data, mmc_data_len, NULL, 0);
8097 case SD_SEND_RELATIVE_ADDR:
8098 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
8101 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
8108 if (mmc_data_len > 0 && mmc_data != NULL)
8115 smpreportgeneral(struct cam_device *device, int argc, char **argv,
8116 char *combinedopt, int retry_count, int timeout)
8119 struct smp_report_general_request *request = NULL;
8120 struct smp_report_general_response *response = NULL;
8121 struct sbuf *sb = NULL;
8123 int c, long_response = 0;
8127 * Note that at the moment we don't support sending SMP CCBs to
8128 * devices that aren't probed by CAM.
8130 ccb = cam_getccb(device);
8132 warnx("%s: error allocating CCB", __func__);
8136 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8138 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8147 request = malloc(sizeof(*request));
8148 if (request == NULL) {
8149 warn("%s: unable to allocate %zd bytes", __func__,
8155 response = malloc(sizeof(*response));
8156 if (response == NULL) {
8157 warn("%s: unable to allocate %zd bytes", __func__,
8164 smp_report_general(&ccb->smpio,
8168 /*request_len*/ sizeof(*request),
8169 (uint8_t *)response,
8170 /*response_len*/ sizeof(*response),
8171 /*long_response*/ long_response,
8174 if (((retval = cam_send_ccb(device, ccb)) < 0)
8175 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8176 const char warnstr[] = "error sending command";
8183 if (arglist & CAM_ARG_VERBOSE) {
8184 cam_error_print(device, ccb, CAM_ESF_ALL,
8185 CAM_EPF_ALL, stderr);
8192 * If the device supports the long response bit, try again and see
8193 * if we can get all of the data.
8195 if ((response->long_response & SMP_RG_LONG_RESPONSE)
8196 && (long_response == 0)) {
8197 ccb->ccb_h.status = CAM_REQ_INPROG;
8198 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8204 * XXX KDM detect and decode SMP errors here.
8206 sb = sbuf_new_auto();
8208 warnx("%s: error allocating sbuf", __func__);
8212 smp_report_general_sbuf(response, sizeof(*response), sb);
8214 if (sbuf_finish(sb) != 0) {
8215 warnx("%s: sbuf_finish", __func__);
8219 printf("%s", sbuf_data(sb));
8225 if (request != NULL)
8228 if (response != NULL)
8237 static struct camcontrol_opts phy_ops[] = {
8238 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
8239 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
8240 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
8241 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
8242 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
8243 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
8244 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
8245 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
8246 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
8251 smpphycontrol(struct cam_device *device, int argc, char **argv,
8252 char *combinedopt, int retry_count, int timeout)
8255 struct smp_phy_control_request *request = NULL;
8256 struct smp_phy_control_response *response = NULL;
8257 int long_response = 0;
8260 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
8262 uint64_t attached_dev_name = 0;
8263 int dev_name_set = 0;
8264 uint32_t min_plr = 0, max_plr = 0;
8265 uint32_t pp_timeout_val = 0;
8266 int slumber_partial = 0;
8267 int set_pp_timeout_val = 0;
8271 * Note that at the moment we don't support sending SMP CCBs to
8272 * devices that aren't probed by CAM.
8274 ccb = cam_getccb(device);
8276 warnx("%s: error allocating CCB", __func__);
8280 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8282 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8290 if (strcasecmp(optarg, "enable") == 0)
8292 else if (strcasecmp(optarg, "disable") == 0)
8295 warnx("%s: Invalid argument %s", __func__,
8302 slumber_partial |= enable <<
8303 SMP_PC_SAS_SLUMBER_SHIFT;
8306 slumber_partial |= enable <<
8307 SMP_PC_SAS_PARTIAL_SHIFT;
8310 slumber_partial |= enable <<
8311 SMP_PC_SATA_SLUMBER_SHIFT;
8314 slumber_partial |= enable <<
8315 SMP_PC_SATA_PARTIAL_SHIFT;
8318 warnx("%s: programmer error", __func__);
8321 break; /*NOTREACHED*/
8326 attached_dev_name = (uintmax_t)strtoumax(optarg,
8335 * We don't do extensive checking here, so this
8336 * will continue to work when new speeds come out.
8338 min_plr = strtoul(optarg, NULL, 0);
8340 || (min_plr > 0xf)) {
8341 warnx("%s: invalid link rate %x",
8349 * We don't do extensive checking here, so this
8350 * will continue to work when new speeds come out.
8352 max_plr = strtoul(optarg, NULL, 0);
8354 || (max_plr > 0xf)) {
8355 warnx("%s: invalid link rate %x",
8362 camcontrol_optret optreturn;
8363 cam_argmask argnums;
8366 if (phy_op_set != 0) {
8367 warnx("%s: only one phy operation argument "
8368 "(-o) allowed", __func__);
8376 * Allow the user to specify the phy operation
8377 * numerically, as well as with a name. This will
8378 * future-proof it a bit, so options that are added
8379 * in future specs can be used.
8381 if (isdigit(optarg[0])) {
8382 phy_operation = strtoul(optarg, NULL, 0);
8383 if ((phy_operation == 0)
8384 || (phy_operation > 0xff)) {
8385 warnx("%s: invalid phy operation %#x",
8386 __func__, phy_operation);
8392 optreturn = getoption(phy_ops, optarg, &phy_operation,
8395 if (optreturn == CC_OR_AMBIGUOUS) {
8396 warnx("%s: ambiguous option %s", __func__,
8401 } else if (optreturn == CC_OR_NOT_FOUND) {
8402 warnx("%s: option %s not found", __func__,
8414 pp_timeout_val = strtoul(optarg, NULL, 0);
8415 if (pp_timeout_val > 15) {
8416 warnx("%s: invalid partial pathway timeout "
8417 "value %u, need a value less than 16",
8418 __func__, pp_timeout_val);
8422 set_pp_timeout_val = 1;
8430 warnx("%s: a PHY (-p phy) argument is required",__func__);
8435 if (((dev_name_set != 0)
8436 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8437 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8438 && (dev_name_set == 0))) {
8439 warnx("%s: -d name and -o setdevname arguments both "
8440 "required to set device name", __func__);
8445 request = malloc(sizeof(*request));
8446 if (request == NULL) {
8447 warn("%s: unable to allocate %zd bytes", __func__,
8453 response = malloc(sizeof(*response));
8454 if (response == NULL) {
8455 warn("%s: unable to allocate %zd bytes", __func__,
8461 smp_phy_control(&ccb->smpio,
8466 (uint8_t *)response,
8469 /*expected_exp_change_count*/ 0,
8472 (set_pp_timeout_val != 0) ? 1 : 0,
8480 if (((retval = cam_send_ccb(device, ccb)) < 0)
8481 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8482 const char warnstr[] = "error sending command";
8489 if (arglist & CAM_ARG_VERBOSE) {
8491 * Use CAM_EPF_NORMAL so we only get one line of
8492 * SMP command decoding.
8494 cam_error_print(device, ccb, CAM_ESF_ALL,
8495 CAM_EPF_NORMAL, stderr);
8501 /* XXX KDM print out something here for success? */
8506 if (request != NULL)
8509 if (response != NULL)
8516 smpmaninfo(struct cam_device *device, int argc, char **argv,
8517 char *combinedopt, int retry_count, int timeout)
8520 struct smp_report_manuf_info_request request;
8521 struct smp_report_manuf_info_response response;
8522 struct sbuf *sb = NULL;
8523 int long_response = 0;
8528 * Note that at the moment we don't support sending SMP CCBs to
8529 * devices that aren't probed by CAM.
8531 ccb = cam_getccb(device);
8533 warnx("%s: error allocating CCB", __func__);
8537 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8539 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8548 bzero(&request, sizeof(request));
8549 bzero(&response, sizeof(response));
8551 smp_report_manuf_info(&ccb->smpio,
8556 (uint8_t *)&response,
8561 if (((retval = cam_send_ccb(device, ccb)) < 0)
8562 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8563 const char warnstr[] = "error sending command";
8570 if (arglist & CAM_ARG_VERBOSE) {
8571 cam_error_print(device, ccb, CAM_ESF_ALL,
8572 CAM_EPF_ALL, stderr);
8578 sb = sbuf_new_auto();
8580 warnx("%s: error allocating sbuf", __func__);
8584 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8586 if (sbuf_finish(sb) != 0) {
8587 warnx("%s: sbuf_finish", __func__);
8591 printf("%s", sbuf_data(sb));
8605 getdevid(struct cam_devitem *item)
8608 union ccb *ccb = NULL;
8610 struct cam_device *dev;
8612 dev = cam_open_btl(item->dev_match.path_id,
8613 item->dev_match.target_id,
8614 item->dev_match.target_lun, O_RDWR, NULL);
8617 warnx("%s", cam_errbuf);
8622 item->device_id_len = 0;
8624 ccb = cam_getccb(dev);
8626 warnx("%s: error allocating CCB", __func__);
8631 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8634 * On the first try, we just probe for the size of the data, and
8635 * then allocate that much memory and try again.
8638 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8639 ccb->ccb_h.flags = CAM_DIR_IN;
8640 ccb->cdai.flags = CDAI_FLAG_NONE;
8641 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8642 ccb->cdai.bufsiz = item->device_id_len;
8643 if (item->device_id_len != 0)
8644 ccb->cdai.buf = (uint8_t *)item->device_id;
8646 if (cam_send_ccb(dev, ccb) < 0) {
8647 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8652 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8653 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8658 if (item->device_id_len == 0) {
8660 * This is our first time through. Allocate the buffer,
8661 * and then go back to get the data.
8663 if (ccb->cdai.provsiz == 0) {
8664 warnx("%s: invalid .provsiz field returned with "
8665 "XPT_GDEV_ADVINFO CCB", __func__);
8669 item->device_id_len = ccb->cdai.provsiz;
8670 item->device_id = malloc(item->device_id_len);
8671 if (item->device_id == NULL) {
8672 warn("%s: unable to allocate %d bytes", __func__,
8673 item->device_id_len);
8677 ccb->ccb_h.status = CAM_REQ_INPROG;
8683 cam_close_device(dev);
8692 * XXX KDM merge this code with getdevtree()?
8695 buildbusdevlist(struct cam_devlist *devlist)
8698 int bufsize, fd = -1;
8699 struct dev_match_pattern *patterns;
8700 struct cam_devitem *item = NULL;
8701 int skip_device = 0;
8704 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8705 warn("couldn't open %s", XPT_DEVICE);
8709 bzero(&ccb, sizeof(union ccb));
8711 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8712 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8713 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8715 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8716 bufsize = sizeof(struct dev_match_result) * 100;
8717 ccb.cdm.match_buf_len = bufsize;
8718 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8719 if (ccb.cdm.matches == NULL) {
8720 warnx("can't malloc memory for matches");
8724 ccb.cdm.num_matches = 0;
8725 ccb.cdm.num_patterns = 2;
8726 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8727 ccb.cdm.num_patterns;
8729 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8730 if (patterns == NULL) {
8731 warnx("can't malloc memory for patterns");
8736 ccb.cdm.patterns = patterns;
8737 bzero(patterns, ccb.cdm.pattern_buf_len);
8739 patterns[0].type = DEV_MATCH_DEVICE;
8740 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8741 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8742 patterns[1].type = DEV_MATCH_PERIPH;
8743 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8744 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8747 * We do the ioctl multiple times if necessary, in case there are
8748 * more than 100 nodes in the EDT.
8753 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8754 warn("error sending CAMIOCOMMAND ioctl");
8759 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8760 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8761 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8762 warnx("got CAM error %#x, CDM error %d\n",
8763 ccb.ccb_h.status, ccb.cdm.status);
8768 for (i = 0; i < ccb.cdm.num_matches; i++) {
8769 switch (ccb.cdm.matches[i].type) {
8770 case DEV_MATCH_DEVICE: {
8771 struct device_match_result *dev_result;
8774 &ccb.cdm.matches[i].result.device_result;
8776 if (dev_result->flags &
8777 DEV_RESULT_UNCONFIGURED) {
8783 item = malloc(sizeof(*item));
8785 warn("%s: unable to allocate %zd bytes",
8786 __func__, sizeof(*item));
8790 bzero(item, sizeof(*item));
8791 bcopy(dev_result, &item->dev_match,
8792 sizeof(*dev_result));
8793 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8796 if (getdevid(item) != 0) {
8802 case DEV_MATCH_PERIPH: {
8803 struct periph_match_result *periph_result;
8806 &ccb.cdm.matches[i].result.periph_result;
8808 if (skip_device != 0)
8810 item->num_periphs++;
8811 item->periph_matches = realloc(
8812 item->periph_matches,
8814 sizeof(struct periph_match_result));
8815 if (item->periph_matches == NULL) {
8816 warn("%s: error allocating periph "
8821 bcopy(periph_result, &item->periph_matches[
8822 item->num_periphs - 1],
8823 sizeof(*periph_result));
8827 fprintf(stderr, "%s: unexpected match "
8828 "type %d\n", __func__,
8829 ccb.cdm.matches[i].type);
8832 break; /*NOTREACHED*/
8835 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8836 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8844 free(ccb.cdm.matches);
8847 freebusdevlist(devlist);
8853 freebusdevlist(struct cam_devlist *devlist)
8855 struct cam_devitem *item, *item2;
8857 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8858 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8860 free(item->device_id);
8861 free(item->periph_matches);
8866 static struct cam_devitem *
8867 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8869 struct cam_devitem *item;
8871 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8872 struct scsi_vpd_id_descriptor *idd;
8875 * XXX KDM look for LUN IDs as well?
8877 idd = scsi_get_devid(item->device_id,
8878 item->device_id_len,
8879 scsi_devid_is_sas_target);
8883 if (scsi_8btou64(idd->identifier) == sasaddr)
8891 smpphylist(struct cam_device *device, int argc, char **argv,
8892 char *combinedopt, int retry_count, int timeout)
8894 struct smp_report_general_request *rgrequest = NULL;
8895 struct smp_report_general_response *rgresponse = NULL;
8896 struct smp_discover_request *disrequest = NULL;
8897 struct smp_discover_response *disresponse = NULL;
8898 struct cam_devlist devlist;
8900 int long_response = 0;
8907 * Note that at the moment we don't support sending SMP CCBs to
8908 * devices that aren't probed by CAM.
8910 ccb = cam_getccb(device);
8912 warnx("%s: error allocating CCB", __func__);
8916 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8917 STAILQ_INIT(&devlist.dev_queue);
8919 rgrequest = malloc(sizeof(*rgrequest));
8920 if (rgrequest == NULL) {
8921 warn("%s: unable to allocate %zd bytes", __func__,
8922 sizeof(*rgrequest));
8927 rgresponse = malloc(sizeof(*rgresponse));
8928 if (rgresponse == NULL) {
8929 warn("%s: unable to allocate %zd bytes", __func__,
8930 sizeof(*rgresponse));
8935 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8948 smp_report_general(&ccb->smpio,
8952 /*request_len*/ sizeof(*rgrequest),
8953 (uint8_t *)rgresponse,
8954 /*response_len*/ sizeof(*rgresponse),
8955 /*long_response*/ long_response,
8958 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8960 if (((retval = cam_send_ccb(device, ccb)) < 0)
8961 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8962 const char warnstr[] = "error sending command";
8969 if (arglist & CAM_ARG_VERBOSE) {
8970 cam_error_print(device, ccb, CAM_ESF_ALL,
8971 CAM_EPF_ALL, stderr);
8977 num_phys = rgresponse->num_phys;
8979 if (num_phys == 0) {
8981 fprintf(stdout, "%s: No Phys reported\n", __func__);
8986 devlist.path_id = device->path_id;
8988 retval = buildbusdevlist(&devlist);
8993 fprintf(stdout, "%d PHYs:\n", num_phys);
8994 fprintf(stdout, "PHY Attached SAS Address\n");
8997 disrequest = malloc(sizeof(*disrequest));
8998 if (disrequest == NULL) {
8999 warn("%s: unable to allocate %zd bytes", __func__,
9000 sizeof(*disrequest));
9005 disresponse = malloc(sizeof(*disresponse));
9006 if (disresponse == NULL) {
9007 warn("%s: unable to allocate %zd bytes", __func__,
9008 sizeof(*disresponse));
9013 for (i = 0; i < num_phys; i++) {
9014 struct cam_devitem *item;
9015 struct device_match_result *dev_match;
9016 char vendor[16], product[48], revision[16];
9020 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
9022 ccb->ccb_h.status = CAM_REQ_INPROG;
9023 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9025 smp_discover(&ccb->smpio,
9029 sizeof(*disrequest),
9030 (uint8_t *)disresponse,
9031 sizeof(*disresponse),
9033 /*ignore_zone_group*/ 0,
9037 if (((retval = cam_send_ccb(device, ccb)) < 0)
9038 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
9039 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
9040 const char warnstr[] = "error sending command";
9047 if (arglist & CAM_ARG_VERBOSE) {
9048 cam_error_print(device, ccb, CAM_ESF_ALL,
9049 CAM_EPF_ALL, stderr);
9055 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
9057 fprintf(stdout, "%3d <vacant>\n", i);
9061 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
9064 item = findsasdevice(&devlist,
9065 scsi_8btou64(disresponse->attached_sas_address));
9069 || (item != NULL)) {
9070 fprintf(stdout, "%3d 0x%016jx", i,
9071 (uintmax_t)scsi_8btou64(
9072 disresponse->attached_sas_address));
9074 fprintf(stdout, "\n");
9077 } else if (quiet != 0)
9080 dev_match = &item->dev_match;
9082 if (dev_match->protocol == PROTO_SCSI) {
9083 cam_strvis(vendor, dev_match->inq_data.vendor,
9084 sizeof(dev_match->inq_data.vendor),
9086 cam_strvis(product, dev_match->inq_data.product,
9087 sizeof(dev_match->inq_data.product),
9089 cam_strvis(revision, dev_match->inq_data.revision,
9090 sizeof(dev_match->inq_data.revision),
9092 sprintf(tmpstr, "<%s %s %s>", vendor, product,
9094 } else if ((dev_match->protocol == PROTO_ATA)
9095 || (dev_match->protocol == PROTO_SATAPM)) {
9096 cam_strvis(product, dev_match->ident_data.model,
9097 sizeof(dev_match->ident_data.model),
9099 cam_strvis(revision, dev_match->ident_data.revision,
9100 sizeof(dev_match->ident_data.revision),
9102 sprintf(tmpstr, "<%s %s>", product, revision);
9104 sprintf(tmpstr, "<>");
9106 fprintf(stdout, " %-33s ", tmpstr);
9109 * If we have 0 periphs, that's a bug...
9111 if (item->num_periphs == 0) {
9112 fprintf(stdout, "\n");
9116 fprintf(stdout, "(");
9117 for (j = 0; j < item->num_periphs; j++) {
9119 fprintf(stdout, ",");
9121 fprintf(stdout, "%s%d",
9122 item->periph_matches[j].periph_name,
9123 item->periph_matches[j].unit_number);
9126 fprintf(stdout, ")\n");
9140 freebusdevlist(&devlist);
9146 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
9148 struct ata_res *res;
9150 res = &ccb->ataio.res;
9151 if (res->status & ATA_STATUS_ERROR) {
9152 if (arglist & CAM_ARG_VERBOSE) {
9153 cam_error_print(device, ccb, CAM_ESF_ALL,
9154 CAM_EPF_ALL, stderr);
9155 printf("error = 0x%02x, sector_count = 0x%04x, "
9156 "device = 0x%02x, status = 0x%02x\n",
9157 res->error, res->sector_count,
9158 res->device, res->status);
9164 if (arglist & CAM_ARG_VERBOSE) {
9165 fprintf(stdout, "%s%d: Raw native check power data:\n",
9166 device->device_name, device->dev_unit_num);
9167 /* res is 4 byte aligned */
9168 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
9170 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
9171 "status = 0x%02x\n", res->error, res->sector_count,
9172 res->device, res->status);
9175 printf("%s%d: ", device->device_name, device->dev_unit_num);
9176 switch (res->sector_count) {
9178 printf("Standby mode\n");
9181 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
9184 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
9187 printf("Idle mode\n");
9190 printf("Active or Idle mode\n");
9193 printf("Unknown mode 0x%02x\n", res->sector_count);
9201 atapm(struct cam_device *device, int argc, char **argv,
9202 char *combinedopt, int retry_count, int timeout)
9208 u_int8_t ata_flags = 0;
9211 ccb = cam_getccb(device);
9214 warnx("%s: error allocating ccb", __func__);
9218 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9227 if (strcmp(argv[1], "idle") == 0) {
9229 cmd = ATA_IDLE_IMMEDIATE;
9232 } else if (strcmp(argv[1], "standby") == 0) {
9234 cmd = ATA_STANDBY_IMMEDIATE;
9236 cmd = ATA_STANDBY_CMD;
9237 } else if (strcmp(argv[1], "powermode") == 0) {
9238 cmd = ATA_CHECK_POWER_MODE;
9239 ata_flags = AP_FLAG_CHK_COND;
9248 else if (t <= (240 * 5))
9250 else if (t <= (252 * 5))
9251 /* special encoding for 21 minutes */
9253 else if (t <= (11 * 30 * 60))
9254 sc = (t - 1) / (30 * 60) + 241;
9258 retval = ata_do_cmd(device,
9260 /*retries*/retry_count,
9261 /*flags*/CAM_DIR_NONE,
9262 /*protocol*/AP_PROTO_NON_DATA,
9263 /*ata_flags*/ata_flags,
9264 /*tag_action*/MSG_SIMPLE_Q_TAG,
9271 /*timeout*/timeout ? timeout : 30 * 1000,
9276 if (retval || cmd != ATA_CHECK_POWER_MODE)
9279 return (atapm_proc_resp(device, ccb));
9283 ataaxm(struct cam_device *device, int argc, char **argv,
9284 char *combinedopt, int retry_count, int timeout)
9292 ccb = cam_getccb(device);
9295 warnx("%s: error allocating ccb", __func__);
9299 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9309 if (strcmp(argv[1], "apm") == 0) {
9325 retval = ata_do_28bit_cmd(device,
9327 /*retries*/retry_count,
9328 /*flags*/CAM_DIR_NONE,
9329 /*protocol*/AP_PROTO_NON_DATA,
9330 /*tag_action*/MSG_SIMPLE_Q_TAG,
9331 /*command*/ATA_SETFEATURES,
9337 /*timeout*/timeout ? timeout : 30 * 1000,
9345 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9346 int show_sa_errors, int sa_set, int service_action,
9347 int timeout_desc, int task_attr, int retry_count, int timeout,
9348 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9350 union ccb *ccb = NULL;
9351 uint8_t *buf = NULL;
9352 uint32_t alloc_len = 0, num_opcodes;
9353 uint32_t valid_len = 0;
9354 uint32_t avail_len = 0;
9355 struct scsi_report_supported_opcodes_all *all_hdr;
9356 struct scsi_report_supported_opcodes_one *one;
9361 * Make it clear that we haven't yet allocated or filled anything.
9366 ccb = cam_getccb(device);
9368 warnx("couldn't allocate CCB");
9373 /* cam_getccb cleans up the header, caller has to zero the payload */
9374 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9376 if (opcode_set != 0) {
9377 options |= RSO_OPTIONS_OC;
9379 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9382 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9383 sizeof(struct scsi_report_supported_opcodes_descr));
9386 if (timeout_desc != 0) {
9387 options |= RSO_RCTD;
9388 alloc_len += num_opcodes *
9389 sizeof(struct scsi_report_supported_opcodes_timeout);
9393 options |= RSO_OPTIONS_OC_SA;
9394 if (show_sa_errors != 0)
9395 options &= ~RSO_OPTIONS_OC;
9404 buf = malloc(alloc_len);
9406 warn("Unable to allocate %u bytes", alloc_len);
9410 bzero(buf, alloc_len);
9412 scsi_report_supported_opcodes(&ccb->csio,
9413 /*retries*/ retry_count,
9415 /*tag_action*/ task_attr,
9416 /*options*/ options,
9417 /*req_opcode*/ opcode,
9418 /*req_service_action*/ service_action,
9420 /*dxfer_len*/ alloc_len,
9421 /*sense_len*/ SSD_FULL_SIZE,
9422 /*timeout*/ timeout ? timeout : 10000);
9424 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9426 if (retry_count != 0)
9427 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9429 if (cam_send_ccb(device, ccb) < 0) {
9430 perror("error sending REPORT SUPPORTED OPERATION CODES");
9435 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9436 if (verbosemode != 0)
9437 cam_error_print(device, ccb, CAM_ESF_ALL,
9438 CAM_EPF_ALL, stderr);
9443 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9445 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9446 && (valid_len >= sizeof(*all_hdr))) {
9447 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9448 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9449 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9450 && (valid_len >= sizeof(*one))) {
9451 uint32_t cdb_length;
9453 one = (struct scsi_report_supported_opcodes_one *)buf;
9454 cdb_length = scsi_2btoul(one->cdb_length);
9455 avail_len = sizeof(*one) + cdb_length;
9456 if (one->support & RSO_ONE_CTDP) {
9457 struct scsi_report_supported_opcodes_timeout *td;
9459 td = (struct scsi_report_supported_opcodes_timeout *)
9461 if (valid_len >= (avail_len + sizeof(td->length))) {
9462 avail_len += scsi_2btoul(td->length) +
9465 avail_len += sizeof(*td);
9471 * avail_len could be zero if we didn't get enough data back from
9472 * thet target to determine
9474 if ((avail_len != 0)
9475 && (avail_len > valid_len)) {
9476 alloc_len = avail_len;
9480 *fill_len = valid_len;
9492 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9493 int req_sa, uint8_t *buf, uint32_t valid_len)
9495 struct scsi_report_supported_opcodes_one *one;
9496 struct scsi_report_supported_opcodes_timeout *td;
9497 uint32_t cdb_len = 0, td_len = 0;
9498 const char *op_desc = NULL;
9502 one = (struct scsi_report_supported_opcodes_one *)buf;
9505 * If we don't have the full single opcode descriptor, no point in
9508 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9510 warnx("Only %u bytes returned, not enough to verify support",
9516 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9518 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9521 printf(", SA 0x%x", req_sa);
9524 switch (one->support & RSO_ONE_SUP_MASK) {
9525 case RSO_ONE_SUP_UNAVAIL:
9526 printf("No command support information currently available\n");
9528 case RSO_ONE_SUP_NOT_SUP:
9529 printf("Command not supported\n");
9532 break; /*NOTREACHED*/
9533 case RSO_ONE_SUP_AVAIL:
9534 printf("Command is supported, complies with a SCSI standard\n");
9536 case RSO_ONE_SUP_VENDOR:
9537 printf("Command is supported, vendor-specific "
9538 "implementation\n");
9541 printf("Unknown command support flags 0x%#x\n",
9542 one->support & RSO_ONE_SUP_MASK);
9547 * If we don't have the CDB length, it isn't exactly an error, the
9548 * command probably isn't supported.
9550 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9554 cdb_len = scsi_2btoul(one->cdb_length);
9557 * If our valid data doesn't include the full reported length,
9558 * return. The caller should have detected this and adjusted his
9559 * allocation length to get all of the available data.
9561 if (valid_len < sizeof(*one) + cdb_len) {
9567 * If all we have is the opcode, there is no point in printing out
9575 printf("CDB usage bitmap:");
9576 for (i = 0; i < cdb_len; i++) {
9577 printf(" %02x", one->cdb_usage[i]);
9582 * If we don't have a timeout descriptor, we're done.
9584 if ((one->support & RSO_ONE_CTDP) == 0)
9588 * If we don't have enough valid length to include the timeout
9589 * descriptor length, we're done.
9591 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9594 td = (struct scsi_report_supported_opcodes_timeout *)
9595 &buf[sizeof(*one) + cdb_len];
9596 td_len = scsi_2btoul(td->length);
9597 td_len += sizeof(td->length);
9600 * If we don't have the full timeout descriptor, we're done.
9602 if (td_len < sizeof(*td))
9606 * If we don't have enough valid length to contain the full timeout
9607 * descriptor, we're done.
9609 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9612 printf("Timeout information:\n");
9613 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9614 printf("Nominal timeout: %u seconds\n",
9615 scsi_4btoul(td->nominal_time));
9616 printf("Recommended timeout: %u seconds\n",
9617 scsi_4btoul(td->recommended_time));
9624 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9627 struct scsi_report_supported_opcodes_all *hdr;
9628 struct scsi_report_supported_opcodes_descr *desc;
9629 uint32_t avail_len = 0, used_len = 0;
9633 if (valid_len < sizeof(*hdr)) {
9634 warnx("%s: not enough returned data (%u bytes) opcode list",
9635 __func__, valid_len);
9639 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9640 avail_len = scsi_4btoul(hdr->length);
9641 avail_len += sizeof(hdr->length);
9643 * Take the lesser of the amount of data the drive claims is
9644 * available, and the amount of data the HBA says was returned.
9646 avail_len = MIN(avail_len, valid_len);
9648 used_len = sizeof(hdr->length);
9650 printf("%-6s %4s %8s ",
9651 "Opcode", "SA", "CDB len" );
9654 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9655 printf(" Description\n");
9657 while ((avail_len - used_len) > sizeof(*desc)) {
9658 struct scsi_report_supported_opcodes_timeout *td;
9660 const char *op_desc = NULL;
9662 cur_ptr = &buf[used_len];
9663 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9665 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9666 if (op_desc == NULL)
9667 op_desc = "UNKNOWN";
9669 printf("0x%02x %#4x %8u ", desc->opcode,
9670 scsi_2btoul(desc->service_action),
9671 scsi_2btoul(desc->cdb_length));
9673 used_len += sizeof(*desc);
9675 if ((desc->flags & RSO_CTDP) == 0) {
9676 printf(" %s\n", op_desc);
9681 * If we don't have enough space to fit a timeout
9682 * descriptor, then we're done.
9684 if (avail_len - used_len < sizeof(*td)) {
9685 used_len = avail_len;
9686 printf(" %s\n", op_desc);
9689 cur_ptr = &buf[used_len];
9690 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9691 td_len = scsi_2btoul(td->length);
9692 td_len += sizeof(td->length);
9696 * If the given timeout descriptor length is less than what
9697 * we understand, skip it.
9699 if (td_len < sizeof(*td)) {
9700 printf(" %s\n", op_desc);
9704 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9705 scsi_4btoul(td->nominal_time),
9706 scsi_4btoul(td->recommended_time), op_desc);
9713 scsiopcodes(struct cam_device *device, int argc, char **argv,
9714 char *combinedopt, int task_attr, int retry_count, int timeout,
9718 uint32_t opcode = 0, service_action = 0;
9719 int td_set = 0, opcode_set = 0, sa_set = 0;
9720 int show_sa_errors = 1;
9721 uint32_t valid_len = 0;
9722 uint8_t *buf = NULL;
9726 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9732 opcode = strtoul(optarg, &endptr, 0);
9733 if (*endptr != '\0') {
9734 warnx("Invalid opcode \"%s\", must be a number",
9739 if (opcode > 0xff) {
9740 warnx("Invalid opcode 0x%#x, must be between"
9741 "0 and 0xff inclusive", opcode);
9748 service_action = strtoul(optarg, &endptr, 0);
9749 if (*endptr != '\0') {
9750 warnx("Invalid service action \"%s\", must "
9751 "be a number", optarg);
9755 if (service_action > 0xffff) {
9756 warnx("Invalid service action 0x%#x, must "
9757 "be between 0 and 0xffff inclusive",
9772 && (opcode_set == 0)) {
9773 warnx("You must specify an opcode with -o if a service "
9778 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9779 sa_set, service_action, td_set, task_attr,
9780 retry_count, timeout, verbosemode, &valid_len,
9785 if ((opcode_set != 0)
9787 retval = scsiprintoneopcode(device, opcode, sa_set,
9788 service_action, buf, valid_len);
9790 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9799 #endif /* MINIMALISTIC */
9802 scsireprobe(struct cam_device *device)
9807 ccb = cam_getccb(device);
9810 warnx("%s: error allocating ccb", __func__);
9814 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9816 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9818 if (cam_send_ccb(device, ccb) < 0) {
9819 warn("error sending XPT_REPROBE_LUN CCB");
9824 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9825 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9837 usage(int printlong)
9840 fprintf(printlong ? stdout : stderr,
9841 "usage: camcontrol <command> [device id][generic args][command args]\n"
9842 " camcontrol devlist [-b] [-v]\n"
9843 #ifndef MINIMALISTIC
9844 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9845 " camcontrol tur [dev_id][generic args]\n"
9846 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9847 " camcontrol identify [dev_id][generic args] [-v]\n"
9848 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9849 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9851 " camcontrol start [dev_id][generic args]\n"
9852 " camcontrol stop [dev_id][generic args]\n"
9853 " camcontrol load [dev_id][generic args]\n"
9854 " camcontrol eject [dev_id][generic args]\n"
9855 " camcontrol reprobe [dev_id][generic args]\n"
9856 #endif /* MINIMALISTIC */
9857 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9858 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9859 #ifndef MINIMALISTIC
9860 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9861 " [-q][-s][-S offset][-X]\n"
9862 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9863 " [-P pagectl][-e | -b][-d]\n"
9864 " camcontrol cmd [dev_id][generic args]\n"
9865 " <-a cmd [args] | -c cmd [args]>\n"
9866 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9867 " camcontrol smpcmd [dev_id][generic args]\n"
9868 " <-r len fmt [args]> <-R len fmt [args]>\n"
9869 " camcontrol smprg [dev_id][generic args][-l]\n"
9870 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9871 " [-o operation][-d name][-m rate][-M rate]\n"
9872 " [-T pp_timeout][-a enable|disable]\n"
9873 " [-A enable|disable][-s enable|disable]\n"
9874 " [-S enable|disable]\n"
9875 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9876 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9877 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9878 " <all|dev_id|bus[:target[:lun]]|off>\n"
9879 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9880 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9881 " [-D <enable|disable>][-M mode][-O offset]\n"
9882 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9883 " [-U][-W bus_width]\n"
9884 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9885 " camcontrol sanitize [dev_id][generic args]\n"
9886 " [-a overwrite|block|crypto|exitfailure]\n"
9887 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9889 " camcontrol idle [dev_id][generic args][-t time]\n"
9890 " camcontrol standby [dev_id][generic args][-t time]\n"
9891 " camcontrol sleep [dev_id][generic args]\n"
9892 " camcontrol powermode [dev_id][generic args]\n"
9893 " camcontrol apm [dev_id][generic args][-l level]\n"
9894 " camcontrol aam [dev_id][generic args][-l level]\n"
9895 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9897 " camcontrol security [dev_id][generic args]\n"
9898 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9899 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9900 " [-U <user|master>] [-y]\n"
9901 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9902 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9903 " camcontrol ama [dev_id][generic args] [-f] [-q] [-s max_sectors]\n"
9904 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9905 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9906 " [-s scope][-S][-T type][-U]\n"
9907 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9908 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9909 " [-p part][-s start][-T type][-V vol]\n"
9910 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9912 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9913 " [-o rep_opts] [-P print_opts]\n"
9914 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9915 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9916 " [-S power_src] [-T timer]\n"
9917 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9918 " <-s <-f format -T time | -U >>\n"
9919 " camcontrol devtype [dev_id]\n"
9921 #endif /* MINIMALISTIC */
9922 " camcontrol help\n");
9925 #ifndef MINIMALISTIC
9927 "Specify one of the following options:\n"
9928 "devlist list all CAM devices\n"
9929 "periphlist list all CAM peripheral drivers attached to a device\n"
9930 "tur send a test unit ready to the named device\n"
9931 "inquiry send a SCSI inquiry command to the named device\n"
9932 "identify send a ATA identify command to the named device\n"
9933 "reportluns send a SCSI report luns command to the device\n"
9934 "readcap send a SCSI read capacity command to the device\n"
9935 "start send a Start Unit command to the device\n"
9936 "stop send a Stop Unit command to the device\n"
9937 "load send a Start Unit command to the device with the load bit set\n"
9938 "eject send a Stop Unit command to the device with the eject bit set\n"
9939 "reprobe update capacity information of the given device\n"
9940 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9941 "reset reset all buses, the given bus, bus:target:lun or device\n"
9942 "defects read the defect list of the specified device\n"
9943 "modepage display or edit (-e) the given mode page\n"
9944 "cmd send the given SCSI command, may need -i or -o as well\n"
9945 "smpcmd send the given SMP command, requires -o and -i\n"
9946 "smprg send the SMP Report General command\n"
9947 "smppc send the SMP PHY Control command, requires -p\n"
9948 "smpphylist display phys attached to a SAS expander\n"
9949 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9950 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9951 "tags report or set the number of transaction slots for a device\n"
9952 "negotiate report or set device negotiation parameters\n"
9953 "format send the SCSI FORMAT UNIT command to the named device\n"
9954 "sanitize send the SCSI SANITIZE command to the named device\n"
9955 "idle send the ATA IDLE command to the named device\n"
9956 "standby send the ATA STANDBY command to the named device\n"
9957 "sleep send the ATA SLEEP command to the named device\n"
9958 "powermode send the ATA CHECK POWER MODE command to the named device\n"
9959 "fwdownload program firmware of the named device with the given image\n"
9960 "security report or send ATA security commands to the named device\n"
9961 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9962 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9963 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9964 "zone manage Zoned Block (Shingled) devices\n"
9965 "epc send ATA Extended Power Conditions commands\n"
9966 "timestamp report or set the device's timestamp\n"
9967 "devtype report the type of device\n"
9968 "help this message\n"
9969 "Device Identifiers:\n"
9970 "bus:target specify the bus and target, lun defaults to 0\n"
9971 "bus:target:lun specify the bus, target and lun\n"
9972 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
9973 "Generic arguments:\n"
9974 "-v be verbose, print out sense information\n"
9975 "-t timeout command timeout in seconds, overrides default timeout\n"
9976 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
9977 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
9978 "-E have the kernel attempt to perform SCSI error recovery\n"
9979 "-C count specify the SCSI command retry count (needs -E to work)\n"
9980 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
9981 "modepage arguments:\n"
9982 "-l list all available mode pages\n"
9983 "-m page specify the mode page to view or edit\n"
9984 "-e edit the specified mode page\n"
9985 "-b force view to binary mode\n"
9986 "-d disable block descriptors for mode sense\n"
9987 "-P pgctl page control field 0-3\n"
9988 "defects arguments:\n"
9989 "-f format specify defect list format (block, bfi or phys)\n"
9990 "-G get the grown defect list\n"
9991 "-P get the permanent defect list\n"
9992 "inquiry arguments:\n"
9993 "-D get the standard inquiry data\n"
9994 "-S get the serial number\n"
9995 "-R get the transfer rate, etc.\n"
9996 "reportluns arguments:\n"
9997 "-c only report a count of available LUNs\n"
9998 "-l only print out luns, and not a count\n"
9999 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
10000 "readcap arguments\n"
10001 "-b only report the blocksize\n"
10002 "-h human readable device size, base 2\n"
10003 "-H human readable device size, base 10\n"
10004 "-N print the number of blocks instead of last block\n"
10005 "-q quiet, print numbers only\n"
10006 "-s only report the last block/device size\n"
10008 "-c cdb [args] specify the SCSI CDB\n"
10009 "-i len fmt specify input data and input data format\n"
10010 "-o len fmt [args] specify output data and output data fmt\n"
10011 "smpcmd arguments:\n"
10012 "-r len fmt [args] specify the SMP command to be sent\n"
10013 "-R len fmt [args] specify SMP response format\n"
10014 "smprg arguments:\n"
10015 "-l specify the long response format\n"
10016 "smppc arguments:\n"
10017 "-p phy specify the PHY to operate on\n"
10018 "-l specify the long request/response format\n"
10019 "-o operation specify the phy control operation\n"
10020 "-d name set the attached device name\n"
10021 "-m rate set the minimum physical link rate\n"
10022 "-M rate set the maximum physical link rate\n"
10023 "-T pp_timeout set the partial pathway timeout value\n"
10024 "-a enable|disable enable or disable SATA slumber\n"
10025 "-A enable|disable enable or disable SATA partial phy power\n"
10026 "-s enable|disable enable or disable SAS slumber\n"
10027 "-S enable|disable enable or disable SAS partial phy power\n"
10028 "smpphylist arguments:\n"
10029 "-l specify the long response format\n"
10030 "-q only print phys with attached devices\n"
10031 "smpmaninfo arguments:\n"
10032 "-l specify the long response format\n"
10033 "debug arguments:\n"
10034 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
10035 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
10036 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
10037 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
10038 "tags arguments:\n"
10039 "-N tags specify the number of tags to use for this device\n"
10040 "-q be quiet, don't report the number of tags\n"
10041 "-v report a number of tag-related parameters\n"
10042 "negotiate arguments:\n"
10043 "-a send a test unit ready after negotiation\n"
10044 "-c report/set current negotiation settings\n"
10045 "-D <arg> \"enable\" or \"disable\" disconnection\n"
10046 "-M mode set ATA mode\n"
10047 "-O offset set command delay offset\n"
10048 "-q be quiet, don't report anything\n"
10049 "-R syncrate synchronization rate in MHz\n"
10050 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
10051 "-U report/set user negotiation settings\n"
10052 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
10053 "-v also print a Path Inquiry CCB for the controller\n"
10054 "format arguments:\n"
10055 "-q be quiet, don't print status messages\n"
10056 "-r run in report only mode\n"
10057 "-w don't send immediate format command\n"
10058 "-y don't ask any questions\n"
10059 "sanitize arguments:\n"
10060 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
10061 "-c passes overwrite passes to perform (1 to 31)\n"
10062 "-I invert overwrite pattern after each pass\n"
10063 "-P pattern path to overwrite pattern file\n"
10064 "-q be quiet, don't print status messages\n"
10065 "-r run in report only mode\n"
10066 "-U run operation in unrestricted completion exit mode\n"
10067 "-w don't send immediate sanitize command\n"
10068 "-y don't ask any questions\n"
10069 "idle/standby arguments:\n"
10070 "-t <arg> number of seconds before respective state.\n"
10071 "fwdownload arguments:\n"
10072 "-f fw_image path to firmware image file\n"
10073 "-q don't print informational messages, only errors\n"
10074 "-s run in simulation mode\n"
10075 "-v print info for every firmware segment sent to device\n"
10076 "-y don't ask any questions\n"
10077 "security arguments:\n"
10078 "-d pwd disable security using the given password for the selected\n"
10080 "-e pwd erase the device using the given pwd for the selected user\n"
10081 "-f freeze the security configuration of the specified device\n"
10082 "-h pwd enhanced erase the device using the given pwd for the\n"
10084 "-k pwd unlock the device using the given pwd for the selected\n"
10086 "-l <high|maximum> specifies which security level to set: high or maximum\n"
10087 "-q be quiet, do not print any status messages\n"
10088 "-s pwd password the device (enable security) using the given\n"
10089 " pwd for the selected user\n"
10090 "-T timeout overrides the timeout (seconds) used for erase operation\n"
10091 "-U <user|master> specifies which user to set: user or master\n"
10092 "-y don't ask any questions\n"
10094 "-f freeze the HPA configuration of the device\n"
10095 "-l lock the HPA configuration of the device\n"
10096 "-P make the HPA max sectors persist\n"
10097 "-p pwd Set the HPA configuration password required for unlock\n"
10099 "-q be quiet, do not print any status messages\n"
10100 "-s sectors configures the maximum user accessible sectors of the\n"
10102 "-U pwd unlock the HPA configuration of the device\n"
10103 "-y don't ask any questions\n"
10105 "-f freeze the AMA configuration of the device\n"
10106 "-q be quiet, do not print any status messages\n"
10107 "-s sectors configures the maximum user accessible sectors of the\n"
10109 "persist arguments:\n"
10110 "-i action specify read_keys, read_reservation, report_cap, or\n"
10111 " read_full_status\n"
10112 "-o action specify register, register_ignore, reserve, release,\n"
10113 " clear, preempt, preempt_abort, register_move, replace_lost\n"
10114 "-a set the All Target Ports (ALL_TG_PT) bit\n"
10115 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
10116 "-k key specify the Reservation Key\n"
10117 "-K sa_key specify the Service Action Reservation Key\n"
10118 "-p set the Activate Persist Through Power Loss bit\n"
10119 "-R rtp specify the Relative Target Port\n"
10120 "-s scope specify the scope: lun, extent, element or a number\n"
10121 "-S specify Transport ID for register, requires -I\n"
10122 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
10123 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
10124 "-U unregister the current initiator for register_move\n"
10125 "attrib arguments:\n"
10126 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
10128 "-w attr specify an attribute to write, one -w argument per attr\n"
10129 "-a attr_num only display this attribute number\n"
10130 "-c get cached attributes\n"
10131 "-e elem_addr request attributes for the given element in a changer\n"
10132 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
10133 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
10134 " field_none, field_desc, field_num, field_size, field_rw\n"
10135 "-p partition request attributes for the given partition\n"
10136 "-s start_attr request attributes starting at the given number\n"
10137 "-T elem_type specify the element type (used with -e)\n"
10138 "-V logical_vol specify the logical volume ID\n"
10139 "opcodes arguments:\n"
10140 "-o opcode specify the individual opcode to list\n"
10141 "-s service_action specify the service action for the opcode\n"
10142 "-N do not return SCSI error for unsupported SA\n"
10143 "-T request nominal and recommended timeout values\n"
10144 "zone arguments:\n"
10145 "-c cmd required: rz, open, close, finish, or rwp\n"
10146 "-a apply the action to all zones\n"
10147 "-l LBA specify the zone starting LBA\n"
10148 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
10149 " closed, full, ro, offline, reset, nonseq, nonwp\n"
10150 "-P print_opt report zones printing: normal, summary, script\n"
10152 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
10153 " source, status, list\n"
10154 "-d disable power mode (timer, state)\n"
10155 "-D delayed entry (goto)\n"
10156 "-e enable power mode (timer, state)\n"
10157 "-H hold power mode (goto)\n"
10158 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
10160 "-P only display power mode (status)\n"
10161 "-r rst_src restore settings from: default, saved (restore)\n"
10162 "-s save mode (timer, state, restore)\n"
10163 "-S power_src set power source: battery, nonbattery (source)\n"
10164 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
10165 "timestamp arguments:\n"
10166 "-r report the timestamp of the device\n"
10167 "-f format report the timestamp of the device with the given\n"
10168 " strftime(3) format string\n"
10169 "-m report the timestamp of the device as milliseconds since\n"
10170 " January 1st, 1970\n"
10171 "-U report the time with UTC instead of the local time zone\n"
10172 "-s set the timestamp of the device\n"
10173 "-f format the format of the time string passed into strptime(3)\n"
10174 "-T time the time value passed into strptime(3)\n"
10175 "-U set the timestamp of the device to UTC time\n"
10177 #endif /* MINIMALISTIC */
10181 main(int argc, char **argv)
10184 char *device = NULL;
10186 struct cam_device *cam_dev = NULL;
10187 int timeout = 0, retry_count = 1;
10188 camcontrol_optret optreturn;
10190 const char *mainopt = "C:En:Q:t:u:v";
10191 const char *subopt = NULL;
10192 char combinedopt[256];
10193 int error = 0, optstart = 2;
10194 int task_attr = MSG_SIMPLE_Q_TAG;
10196 #ifndef MINIMALISTIC
10198 target_id_t target;
10200 #endif /* MINIMALISTIC */
10202 cmdlist = CAM_CMD_NONE;
10203 arglist = CAM_ARG_NONE;
10211 * Get the base option.
10213 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
10215 if (optreturn == CC_OR_AMBIGUOUS) {
10216 warnx("ambiguous option %s", argv[1]);
10219 } else if (optreturn == CC_OR_NOT_FOUND) {
10220 warnx("option %s not found", argv[1]);
10226 * Ahh, getopt(3) is a pain.
10228 * This is a gross hack. There really aren't many other good
10229 * options (excuse the pun) for parsing options in a situation like
10230 * this. getopt is kinda braindead, so you end up having to run
10231 * through the options twice, and give each invocation of getopt
10232 * the option string for the other invocation.
10234 * You would think that you could just have two groups of options.
10235 * The first group would get parsed by the first invocation of
10236 * getopt, and the second group would get parsed by the second
10237 * invocation of getopt. It doesn't quite work out that way. When
10238 * the first invocation of getopt finishes, it leaves optind pointing
10239 * to the argument _after_ the first argument in the second group.
10240 * So when the second invocation of getopt comes around, it doesn't
10241 * recognize the first argument it gets and then bails out.
10243 * A nice alternative would be to have a flag for getopt that says
10244 * "just keep parsing arguments even when you encounter an unknown
10245 * argument", but there isn't one. So there's no real clean way to
10246 * easily parse two sets of arguments without having one invocation
10247 * of getopt know about the other.
10249 * Without this hack, the first invocation of getopt would work as
10250 * long as the generic arguments are first, but the second invocation
10251 * (in the subfunction) would fail in one of two ways. In the case
10252 * where you don't set optreset, it would fail because optind may be
10253 * pointing to the argument after the one it should be pointing at.
10254 * In the case where you do set optreset, and reset optind, it would
10255 * fail because getopt would run into the first set of options, which
10256 * it doesn't understand.
10258 * All of this would "sort of" work if you could somehow figure out
10259 * whether optind had been incremented one option too far. The
10260 * mechanics of that, however, are more daunting than just giving
10261 * both invocations all of the expect options for either invocation.
10263 * Needless to say, I wouldn't mind if someone invented a better
10264 * (non-GPL!) command line parsing interface than getopt. I
10265 * wouldn't mind if someone added more knobs to getopt to make it
10266 * work better. Who knows, I may talk myself into doing it someday,
10267 * if the standards weenies let me. As it is, it just leads to
10268 * hackery like this and causes people to avoid it in some cases.
10270 * KDM, September 8th, 1998
10272 if (subopt != NULL)
10273 sprintf(combinedopt, "%s%s", mainopt, subopt);
10275 sprintf(combinedopt, "%s", mainopt);
10278 * For these options we do not parse optional device arguments and
10279 * we do not open a passthrough device.
10281 if ((cmdlist == CAM_CMD_RESCAN)
10282 || (cmdlist == CAM_CMD_RESET)
10283 || (cmdlist == CAM_CMD_DEVTREE)
10284 || (cmdlist == CAM_CMD_USAGE)
10285 || (cmdlist == CAM_CMD_DEBUG))
10288 #ifndef MINIMALISTIC
10290 && (argc > 2 && argv[2][0] != '-')) {
10294 if (isdigit(argv[2][0])) {
10295 /* device specified as bus:target[:lun] */
10296 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10298 errx(1, "numeric device specification must "
10299 "be either bus:target, or "
10301 /* default to 0 if lun was not specified */
10302 if ((arglist & CAM_ARG_LUN) == 0) {
10304 arglist |= CAM_ARG_LUN;
10308 if (cam_get_device(argv[2], name, sizeof name, &unit)
10310 errx(1, "%s", cam_errbuf);
10311 device = strdup(name);
10312 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10316 #endif /* MINIMALISTIC */
10318 * Start getopt processing at argv[2/3], since we've already
10319 * accepted argv[1..2] as the command name, and as a possible
10325 * Now we run through the argument list looking for generic
10326 * options, and ignoring options that possibly belong to
10329 while ((c = getopt(argc, argv, combinedopt))!= -1){
10332 retry_count = strtol(optarg, NULL, 0);
10333 if (retry_count < 0)
10334 errx(1, "retry count %d is < 0",
10336 arglist |= CAM_ARG_RETRIES;
10339 arglist |= CAM_ARG_ERR_RECOVER;
10342 arglist |= CAM_ARG_DEVICE;
10344 while (isspace(*tstr) && (*tstr != '\0'))
10346 device = (char *)strdup(tstr);
10350 int table_entry = 0;
10353 while (isspace(*tstr) && (*tstr != '\0'))
10355 if (isdigit(*tstr)) {
10356 task_attr = strtol(tstr, &endptr, 0);
10357 if (*endptr != '\0') {
10358 errx(1, "Invalid queue option "
10363 scsi_nv_status status;
10365 table_size = sizeof(task_attrs) /
10366 sizeof(task_attrs[0]);
10367 status = scsi_get_nv(task_attrs,
10368 table_size, tstr, &table_entry,
10369 SCSI_NV_FLAG_IG_CASE);
10370 if (status == SCSI_NV_FOUND)
10371 task_attr = task_attrs[
10372 table_entry].value;
10374 errx(1, "%s option %s",
10375 (status == SCSI_NV_AMBIGUOUS)?
10376 "ambiguous" : "invalid",
10383 timeout = strtol(optarg, NULL, 0);
10385 errx(1, "invalid timeout %d", timeout);
10386 /* Convert the timeout from seconds to ms */
10388 arglist |= CAM_ARG_TIMEOUT;
10391 arglist |= CAM_ARG_UNIT;
10392 unit = strtol(optarg, NULL, 0);
10395 arglist |= CAM_ARG_VERBOSE;
10402 #ifndef MINIMALISTIC
10404 * For most commands we'll want to open the passthrough device
10405 * associated with the specified device. In the case of the rescan
10406 * commands, we don't use a passthrough device at all, just the
10407 * transport layer device.
10409 if (devopen == 1) {
10410 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10411 && (((arglist & CAM_ARG_DEVICE) == 0)
10412 || ((arglist & CAM_ARG_UNIT) == 0))) {
10413 errx(1, "subcommand \"%s\" requires a valid device "
10414 "identifier", argv[1]);
10417 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10418 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10419 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10421 errx(1,"%s", cam_errbuf);
10423 #endif /* MINIMALISTIC */
10426 * Reset optind to 2, and reset getopt, so these routines can parse
10427 * the arguments again.
10433 #ifndef MINIMALISTIC
10434 case CAM_CMD_DEVLIST:
10435 error = getdevlist(cam_dev);
10438 error = atahpa(cam_dev, retry_count, timeout,
10439 argc, argv, combinedopt);
10442 error = ataama(cam_dev, retry_count, timeout,
10443 argc, argv, combinedopt);
10445 #endif /* MINIMALISTIC */
10446 case CAM_CMD_DEVTREE:
10447 error = getdevtree(argc, argv, combinedopt);
10449 case CAM_CMD_DEVTYPE:
10450 error = getdevtype(cam_dev);
10452 #ifndef MINIMALISTIC
10454 error = testunitready(cam_dev, task_attr, retry_count,
10457 case CAM_CMD_INQUIRY:
10458 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10459 task_attr, retry_count, timeout);
10461 case CAM_CMD_IDENTIFY:
10462 error = identify(cam_dev, retry_count, timeout);
10464 case CAM_CMD_STARTSTOP:
10465 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10466 arglist & CAM_ARG_EJECT, task_attr,
10467 retry_count, timeout);
10469 #endif /* MINIMALISTIC */
10470 case CAM_CMD_RESCAN:
10471 error = dorescan_or_reset(argc, argv, 1);
10473 case CAM_CMD_RESET:
10474 error = dorescan_or_reset(argc, argv, 0);
10476 #ifndef MINIMALISTIC
10477 case CAM_CMD_READ_DEFECTS:
10478 error = readdefects(cam_dev, argc, argv, combinedopt,
10479 task_attr, retry_count, timeout);
10481 case CAM_CMD_MODE_PAGE:
10482 modepage(cam_dev, argc, argv, combinedopt,
10483 task_attr, retry_count, timeout);
10485 case CAM_CMD_SCSI_CMD:
10486 error = scsicmd(cam_dev, argc, argv, combinedopt,
10487 task_attr, retry_count, timeout);
10489 case CAM_CMD_MMCSD_CMD:
10490 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10491 retry_count, timeout);
10493 case CAM_CMD_SMP_CMD:
10494 error = smpcmd(cam_dev, argc, argv, combinedopt,
10495 retry_count, timeout);
10497 case CAM_CMD_SMP_RG:
10498 error = smpreportgeneral(cam_dev, argc, argv,
10499 combinedopt, retry_count,
10502 case CAM_CMD_SMP_PC:
10503 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10504 retry_count, timeout);
10506 case CAM_CMD_SMP_PHYLIST:
10507 error = smpphylist(cam_dev, argc, argv, combinedopt,
10508 retry_count, timeout);
10510 case CAM_CMD_SMP_MANINFO:
10511 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10512 retry_count, timeout);
10514 case CAM_CMD_DEBUG:
10515 error = camdebug(argc, argv, combinedopt);
10518 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10521 error = ratecontrol(cam_dev, task_attr, retry_count,
10522 timeout, argc, argv, combinedopt);
10524 case CAM_CMD_FORMAT:
10525 error = scsiformat(cam_dev, argc, argv,
10526 combinedopt, task_attr, retry_count,
10529 case CAM_CMD_REPORTLUNS:
10530 error = scsireportluns(cam_dev, argc, argv,
10531 combinedopt, task_attr,
10532 retry_count, timeout);
10534 case CAM_CMD_READCAP:
10535 error = scsireadcapacity(cam_dev, argc, argv,
10536 combinedopt, task_attr,
10537 retry_count, timeout);
10540 case CAM_CMD_STANDBY:
10541 case CAM_CMD_SLEEP:
10542 case CAM_CMD_POWER_MODE:
10543 error = atapm(cam_dev, argc, argv,
10544 combinedopt, retry_count, timeout);
10548 error = ataaxm(cam_dev, argc, argv,
10549 combinedopt, retry_count, timeout);
10551 case CAM_CMD_SECURITY:
10552 error = atasecurity(cam_dev, retry_count, timeout,
10553 argc, argv, combinedopt);
10555 case CAM_CMD_DOWNLOAD_FW:
10556 error = fwdownload(cam_dev, argc, argv, combinedopt,
10557 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10560 case CAM_CMD_SANITIZE:
10561 error = scsisanitize(cam_dev, argc, argv,
10562 combinedopt, task_attr,
10563 retry_count, timeout);
10565 case CAM_CMD_PERSIST:
10566 error = scsipersist(cam_dev, argc, argv, combinedopt,
10567 task_attr, retry_count, timeout,
10568 arglist & CAM_ARG_VERBOSE,
10569 arglist & CAM_ARG_ERR_RECOVER);
10571 case CAM_CMD_ATTRIB:
10572 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10573 task_attr, retry_count, timeout,
10574 arglist & CAM_ARG_VERBOSE,
10575 arglist & CAM_ARG_ERR_RECOVER);
10577 case CAM_CMD_OPCODES:
10578 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10579 task_attr, retry_count, timeout,
10580 arglist & CAM_ARG_VERBOSE);
10582 case CAM_CMD_REPROBE:
10583 error = scsireprobe(cam_dev);
10586 error = zone(cam_dev, argc, argv, combinedopt,
10587 task_attr, retry_count, timeout,
10588 arglist & CAM_ARG_VERBOSE);
10591 error = epc(cam_dev, argc, argv, combinedopt,
10592 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10594 case CAM_CMD_TIMESTAMP:
10595 error = timestamp(cam_dev, argc, argv, combinedopt,
10596 task_attr, retry_count, timeout,
10597 arglist & CAM_ARG_VERBOSE);
10599 #endif /* MINIMALISTIC */
10600 case CAM_CMD_USAGE:
10609 if (cam_dev != NULL)
10610 cam_close_device(cam_dev);