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,
117 CAM_ARG_NONE = 0x00000000,
118 CAM_ARG_VERBOSE = 0x00000001,
119 CAM_ARG_DEVICE = 0x00000002,
120 CAM_ARG_BUS = 0x00000004,
121 CAM_ARG_TARGET = 0x00000008,
122 CAM_ARG_LUN = 0x00000010,
123 CAM_ARG_EJECT = 0x00000020,
124 CAM_ARG_UNIT = 0x00000040,
125 CAM_ARG_FORMAT_BLOCK = 0x00000080,
126 CAM_ARG_FORMAT_BFI = 0x00000100,
127 CAM_ARG_FORMAT_PHYS = 0x00000200,
128 CAM_ARG_PLIST = 0x00000400,
129 CAM_ARG_GLIST = 0x00000800,
130 CAM_ARG_GET_SERIAL = 0x00001000,
131 CAM_ARG_GET_STDINQ = 0x00002000,
132 CAM_ARG_GET_XFERRATE = 0x00004000,
133 CAM_ARG_INQ_MASK = 0x00007000,
134 CAM_ARG_TIMEOUT = 0x00020000,
135 CAM_ARG_CMD_IN = 0x00040000,
136 CAM_ARG_CMD_OUT = 0x00080000,
137 CAM_ARG_ERR_RECOVER = 0x00200000,
138 CAM_ARG_RETRIES = 0x00400000,
139 CAM_ARG_START_UNIT = 0x00800000,
140 CAM_ARG_DEBUG_INFO = 0x01000000,
141 CAM_ARG_DEBUG_TRACE = 0x02000000,
142 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
143 CAM_ARG_DEBUG_CDB = 0x08000000,
144 CAM_ARG_DEBUG_XPT = 0x10000000,
145 CAM_ARG_DEBUG_PERIPH = 0x20000000,
146 CAM_ARG_DEBUG_PROBE = 0x40000000,
149 struct camcontrol_opts {
157 struct ata_res_pass16 {
158 u_int16_t reserved[5];
161 u_int8_t sector_count_exp;
162 u_int8_t sector_count;
163 u_int8_t lba_low_exp;
165 u_int8_t lba_mid_exp;
167 u_int8_t lba_high_exp;
173 struct ata_set_max_pwd
176 u_int8_t password[32];
177 u_int16_t reserved2[239];
180 static struct scsi_nv task_attrs[] = {
181 { "simple", MSG_SIMPLE_Q_TAG },
182 { "head", MSG_HEAD_OF_Q_TAG },
183 { "ordered", MSG_ORDERED_Q_TAG },
184 { "iwr", MSG_IGN_WIDE_RESIDUE },
185 { "aca", MSG_ACA_TASK }
188 static const char scsicmd_opts[] = "a:c:dfi:o:r";
189 static const char readdefect_opts[] = "f:GPqsS:X";
190 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
191 static const char smprg_opts[] = "l";
192 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
193 static const char smpphylist_opts[] = "lq";
197 static struct camcontrol_opts option_table[] = {
199 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
200 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
201 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
202 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
203 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
204 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
205 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
206 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
207 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHlNqs"},
208 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
209 #endif /* MINIMALISTIC */
210 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
211 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
213 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
214 {"mmcsdcmd", CAM_CMD_MMCSD_CMD, CAM_ARG_NONE, "c:a:f:Wb:l:41S:I"},
215 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
216 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
217 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
218 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
219 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
220 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
221 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
222 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
223 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
224 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
225 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
226 #endif /* MINIMALISTIC */
227 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
229 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
230 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
231 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
232 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
233 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
234 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
235 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
236 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
237 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
238 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
239 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
240 {"powermode", CAM_CMD_POWER_MODE, CAM_ARG_NONE, ""},
241 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
242 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
243 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
244 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
245 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
246 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
247 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
248 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
249 {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
250 {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
251 {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
252 #endif /* MINIMALISTIC */
253 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
254 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
255 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
260 struct device_match_result dev_match;
262 struct periph_match_result *periph_matches;
263 struct scsi_vpd_device_id *device_id;
265 STAILQ_ENTRY(cam_devitem) links;
269 STAILQ_HEAD(, cam_devitem) dev_queue;
273 static cam_cmdmask cmdlist;
274 static cam_argmask arglist;
276 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
277 uint32_t *cmdnum, cam_argmask *argnum,
278 const char **subopt);
280 static int getdevlist(struct cam_device *device);
281 #endif /* MINIMALISTIC */
282 static int getdevtree(int argc, char **argv, char *combinedopt);
283 static int print_dev_scsi(struct device_match_result *dev_result, char *tmpstr);
284 static int print_dev_ata(struct device_match_result *dev_result, char *tmpstr);
285 static int print_dev_semb(struct device_match_result *dev_result, char *tmpstr);
286 static int print_dev_mmcsd(struct device_match_result *dev_result,
289 static int print_dev_nvme(struct device_match_result *dev_result, char *tmpstr);
292 static int testunitready(struct cam_device *device, int task_attr,
293 int retry_count, int timeout, int quiet);
294 static int scsistart(struct cam_device *device, int startstop, int loadeject,
295 int task_attr, int retry_count, int timeout);
296 static int scsiinquiry(struct cam_device *device, int task_attr,
297 int retry_count, int timeout);
298 static int scsiserial(struct cam_device *device, int task_attr,
299 int retry_count, int timeout);
300 #endif /* MINIMALISTIC */
301 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
302 lun_id_t *lun, cam_argmask *arglst);
303 static int dorescan_or_reset(int argc, char **argv, int rescan);
304 static int rescan_or_reset_bus(path_id_t bus, int rescan);
305 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
306 lun_id_t lun, int scan);
308 static int readdefects(struct cam_device *device, int argc, char **argv,
309 char *combinedopt, int task_attr, int retry_count,
311 static void modepage(struct cam_device *device, int argc, char **argv,
312 char *combinedopt, int task_attr, int retry_count,
314 static int scsicmd(struct cam_device *device, int argc, char **argv,
315 char *combinedopt, int task_attr, int retry_count,
317 static int smpcmd(struct cam_device *device, int argc, char **argv,
318 char *combinedopt, int retry_count, int timeout);
319 static int mmcsdcmd(struct cam_device *device, int argc, char **argv,
320 char *combinedopt, int retry_count, int timeout);
321 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
322 char *combinedopt, int retry_count, int timeout);
323 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
324 char *combinedopt, int retry_count, int timeout);
325 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
326 char *combinedopt, int retry_count, int timeout);
327 static int getdevid(struct cam_devitem *item);
328 static int buildbusdevlist(struct cam_devlist *devlist);
329 static void freebusdevlist(struct cam_devlist *devlist);
330 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
332 static int smpphylist(struct cam_device *device, int argc, char **argv,
333 char *combinedopt, int retry_count, int timeout);
334 static int tagcontrol(struct cam_device *device, int argc, char **argv,
336 static void cts_print(struct cam_device *device,
337 struct ccb_trans_settings *cts);
338 static void cpi_print(struct ccb_pathinq *cpi);
339 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
340 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
341 static int get_print_cts(struct cam_device *device, int user_settings,
342 int quiet, struct ccb_trans_settings *cts);
343 static int ratecontrol(struct cam_device *device, int task_attr,
344 int retry_count, int timeout, int argc, char **argv,
346 static int scsiformat(struct cam_device *device, int argc, char **argv,
347 char *combinedopt, int task_attr, int retry_count,
349 static int scsisanitize(struct cam_device *device, int argc, char **argv,
350 char *combinedopt, int task_attr, int retry_count,
352 static int scsireportluns(struct cam_device *device, int argc, char **argv,
353 char *combinedopt, int task_attr, int retry_count,
355 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
356 char *combinedopt, int task_attr, int retry_count,
358 static int atapm(struct cam_device *device, int argc, char **argv,
359 char *combinedopt, int retry_count, int timeout);
360 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
361 int argc, char **argv, char *combinedopt);
362 static int atahpa(struct cam_device *device, int retry_count, int timeout,
363 int argc, char **argv, char *combinedopt);
364 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
365 int sa_set, int req_sa, uint8_t *buf,
367 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
369 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
370 char *combinedopt, int task_attr, int retry_count,
371 int timeout, int verbose);
372 static int scsireprobe(struct cam_device *device);
374 #endif /* MINIMALISTIC */
376 #define min(a,b) (((a)<(b))?(a):(b))
379 #define max(a,b) (((a)>(b))?(a):(b))
383 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
384 cam_argmask *argnum, const char **subopt)
386 struct camcontrol_opts *opts;
389 for (opts = table; (opts != NULL) && (opts->optname != NULL);
391 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
392 *cmdnum = opts->cmdnum;
393 *argnum = opts->argnum;
394 *subopt = opts->subopt;
395 if (++num_matches > 1)
396 return (CC_OR_AMBIGUOUS);
401 return (CC_OR_FOUND);
403 return (CC_OR_NOT_FOUND);
408 getdevlist(struct cam_device *device)
414 ccb = cam_getccb(device);
416 ccb->ccb_h.func_code = XPT_GDEVLIST;
417 ccb->ccb_h.flags = CAM_DIR_NONE;
418 ccb->ccb_h.retry_count = 1;
420 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
421 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
422 if (cam_send_ccb(device, ccb) < 0) {
423 perror("error getting device list");
430 switch (ccb->cgdl.status) {
431 case CAM_GDEVLIST_MORE_DEVS:
432 strcpy(status, "MORE");
434 case CAM_GDEVLIST_LAST_DEVICE:
435 strcpy(status, "LAST");
437 case CAM_GDEVLIST_LIST_CHANGED:
438 strcpy(status, "CHANGED");
440 case CAM_GDEVLIST_ERROR:
441 strcpy(status, "ERROR");
446 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
447 ccb->cgdl.periph_name,
448 ccb->cgdl.unit_number,
449 ccb->cgdl.generation,
454 * If the list has changed, we need to start over from the
457 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
465 #endif /* MINIMALISTIC */
468 getdevtree(int argc, char **argv, char *combinedopt)
479 while ((c = getopt(argc, argv, combinedopt)) != -1) {
482 if ((arglist & CAM_ARG_VERBOSE) == 0)
490 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
491 warn("couldn't open %s", XPT_DEVICE);
495 bzero(&ccb, sizeof(union ccb));
497 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
498 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
499 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
501 ccb.ccb_h.func_code = XPT_DEV_MATCH;
502 bufsize = sizeof(struct dev_match_result) * 100;
503 ccb.cdm.match_buf_len = bufsize;
504 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
505 if (ccb.cdm.matches == NULL) {
506 warnx("can't malloc memory for matches");
510 ccb.cdm.num_matches = 0;
513 * We fetch all nodes, since we display most of them in the default
514 * case, and all in the verbose case.
516 ccb.cdm.num_patterns = 0;
517 ccb.cdm.pattern_buf_len = 0;
520 * We do the ioctl multiple times if necessary, in case there are
521 * more than 100 nodes in the EDT.
524 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
525 warn("error sending CAMIOCOMMAND ioctl");
530 if ((ccb.ccb_h.status != CAM_REQ_CMP)
531 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
532 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
533 warnx("got CAM error %#x, CDM error %d\n",
534 ccb.ccb_h.status, ccb.cdm.status);
539 for (i = 0; i < ccb.cdm.num_matches; i++) {
540 switch (ccb.cdm.matches[i].type) {
541 case DEV_MATCH_BUS: {
542 struct bus_match_result *bus_result;
545 * Only print the bus information if the
546 * user turns on the verbose flag.
548 if ((busonly == 0) &&
549 (arglist & CAM_ARG_VERBOSE) == 0)
553 &ccb.cdm.matches[i].result.bus_result;
556 fprintf(stdout, ")\n");
560 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
562 bus_result->dev_name,
563 bus_result->unit_number,
565 (busonly ? "" : ":"));
568 case DEV_MATCH_DEVICE: {
569 struct device_match_result *dev_result;
576 &ccb.cdm.matches[i].result.device_result;
578 if ((dev_result->flags
579 & DEV_RESULT_UNCONFIGURED)
580 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
586 if (dev_result->protocol == PROTO_SCSI) {
587 if (print_dev_scsi(dev_result,
592 } else if (dev_result->protocol == PROTO_ATA ||
593 dev_result->protocol == PROTO_SATAPM) {
594 if (print_dev_ata(dev_result,
599 } else if (dev_result->protocol == PROTO_MMCSD){
600 if (print_dev_mmcsd(dev_result,
605 } else if (dev_result->protocol == PROTO_SEMB) {
606 if (print_dev_semb(dev_result,
612 } else if (dev_result->protocol == PROTO_NVME) {
613 if (print_dev_nvme(dev_result,
620 sprintf(tmpstr, "<>");
623 fprintf(stdout, ")\n");
627 fprintf(stdout, "%-33s at scbus%d "
628 "target %d lun %jx (",
631 dev_result->target_id,
632 (uintmax_t)dev_result->target_lun);
638 case DEV_MATCH_PERIPH: {
639 struct periph_match_result *periph_result;
642 &ccb.cdm.matches[i].result.periph_result;
644 if (busonly || skip_device != 0)
648 fprintf(stdout, ",");
650 fprintf(stdout, "%s%d",
651 periph_result->periph_name,
652 periph_result->unit_number);
658 fprintf(stdout, "unknown match type\n");
663 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
664 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
667 fprintf(stdout, ")\n");
675 print_dev_scsi(struct device_match_result *dev_result, char *tmpstr)
677 char vendor[16], product[48], revision[16];
679 cam_strvis(vendor, dev_result->inq_data.vendor,
680 sizeof(dev_result->inq_data.vendor), sizeof(vendor));
681 cam_strvis(product, dev_result->inq_data.product,
682 sizeof(dev_result->inq_data.product), sizeof(product));
683 cam_strvis(revision, dev_result->inq_data.revision,
684 sizeof(dev_result->inq_data.revision), sizeof(revision));
685 sprintf(tmpstr, "<%s %s %s>", vendor, product, revision);
691 print_dev_ata(struct device_match_result *dev_result, char *tmpstr)
693 char product[48], revision[16];
695 cam_strvis(product, dev_result->ident_data.model,
696 sizeof(dev_result->ident_data.model), sizeof(product));
697 cam_strvis(revision, dev_result->ident_data.revision,
698 sizeof(dev_result->ident_data.revision), sizeof(revision));
699 sprintf(tmpstr, "<%s %s>", product, revision);
705 print_dev_semb(struct device_match_result *dev_result, char *tmpstr)
707 struct sep_identify_data *sid;
708 char vendor[16], product[48], revision[16], fw[5];
710 sid = (struct sep_identify_data *)&dev_result->ident_data;
711 cam_strvis(vendor, sid->vendor_id,
712 sizeof(sid->vendor_id), sizeof(vendor));
713 cam_strvis(product, sid->product_id,
714 sizeof(sid->product_id), sizeof(product));
715 cam_strvis(revision, sid->product_rev,
716 sizeof(sid->product_rev), sizeof(revision));
717 cam_strvis(fw, sid->firmware_rev,
718 sizeof(sid->firmware_rev), sizeof(fw));
719 sprintf(tmpstr, "<%s %s %s %s>", vendor, product, revision, fw);
725 print_dev_mmcsd(struct device_match_result *dev_result, char *tmpstr)
728 struct ccb_dev_advinfo *advi;
729 struct cam_device *dev;
730 struct mmc_params mmc_ident_data;
732 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
733 dev_result->target_lun, O_RDWR, NULL);
735 warnx("%s", cam_errbuf);
739 ccb = cam_getccb(dev);
741 warnx("couldn't allocate CCB");
742 cam_close_device(dev);
747 advi->ccb_h.flags = CAM_DIR_IN;
748 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
749 advi->flags = CDAI_FLAG_NONE;
750 advi->buftype = CDAI_TYPE_MMC_PARAMS;
751 advi->bufsiz = sizeof(struct mmc_params);
752 advi->buf = (uint8_t *)&mmc_ident_data;
754 if (cam_send_ccb(dev, ccb) < 0) {
755 warn("error sending CAMIOCOMMAND ioctl");
757 cam_close_device(dev);
761 if (strlen(mmc_ident_data.model) > 0) {
762 sprintf(tmpstr, "<%s>", mmc_ident_data.model);
764 sprintf(tmpstr, "<%s card>",
765 mmc_ident_data.card_features &
766 CARD_FEATURE_SDIO ? "SDIO" : "unknown");
770 cam_close_device(dev);
776 nvme_get_cdata(struct cam_device *dev, struct nvme_controller_data *cdata)
779 struct ccb_dev_advinfo *advi;
781 ccb = cam_getccb(dev);
783 warnx("couldn't allocate CCB");
784 cam_close_device(dev);
789 advi->ccb_h.flags = CAM_DIR_IN;
790 advi->ccb_h.func_code = XPT_DEV_ADVINFO;
791 advi->flags = CDAI_FLAG_NONE;
792 advi->buftype = CDAI_TYPE_NVME_CNTRL;
793 advi->bufsiz = sizeof(struct nvme_controller_data);
794 advi->buf = (uint8_t *)cdata;
796 if (cam_send_ccb(dev, ccb) < 0) {
797 warn("error sending CAMIOCOMMAND ioctl");
799 cam_close_device(dev);
802 if (advi->ccb_h.status != CAM_REQ_CMP) {
803 warnx("got CAM error %#x", advi->ccb_h.status);
805 cam_close_device(dev);
813 print_dev_nvme(struct device_match_result *dev_result, char *tmpstr)
815 struct cam_device *dev;
816 struct nvme_controller_data cdata;
817 char vendor[64], product[64];
819 dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
820 dev_result->target_lun, O_RDWR, NULL);
822 warnx("%s", cam_errbuf);
826 if (nvme_get_cdata(dev, &cdata))
829 cam_strvis(vendor, cdata.mn, sizeof(cdata.mn), sizeof(vendor));
830 cam_strvis(product, cdata.fr, sizeof(cdata.fr), sizeof(product));
831 sprintf(tmpstr, "<%s %s>", vendor, product);
833 cam_close_device(dev);
840 testunitready(struct cam_device *device, int task_attr, int retry_count,
841 int timeout, int quiet)
846 ccb = cam_getccb(device);
848 scsi_test_unit_ready(&ccb->csio,
849 /* retries */ retry_count,
851 /* tag_action */ task_attr,
852 /* sense_len */ SSD_FULL_SIZE,
853 /* timeout */ timeout ? timeout : 5000);
855 /* Disable freezing the device queue */
856 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
858 if (arglist & CAM_ARG_ERR_RECOVER)
859 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
861 if (cam_send_ccb(device, ccb) < 0) {
863 perror("error sending test unit ready");
865 if (arglist & CAM_ARG_VERBOSE) {
866 cam_error_print(device, ccb, CAM_ESF_ALL,
867 CAM_EPF_ALL, stderr);
874 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
876 fprintf(stdout, "Unit is ready\n");
879 fprintf(stdout, "Unit is not ready\n");
882 if (arglist & CAM_ARG_VERBOSE) {
883 cam_error_print(device, ccb, CAM_ESF_ALL,
884 CAM_EPF_ALL, stderr);
894 scsistart(struct cam_device *device, int startstop, int loadeject,
895 int task_attr, int retry_count, int timeout)
900 ccb = cam_getccb(device);
903 * If we're stopping, send an ordered tag so the drive in question
904 * will finish any previously queued writes before stopping. If
905 * the device isn't capable of tagged queueing, or if tagged
906 * queueing is turned off, the tag action is a no-op. We override
907 * the default simple tag, although this also has the effect of
908 * overriding the user's wishes if he wanted to specify a simple
912 && (task_attr == MSG_SIMPLE_Q_TAG))
913 task_attr = MSG_ORDERED_Q_TAG;
915 scsi_start_stop(&ccb->csio,
916 /* retries */ retry_count,
918 /* tag_action */ task_attr,
919 /* start/stop */ startstop,
920 /* load_eject */ loadeject,
922 /* sense_len */ SSD_FULL_SIZE,
923 /* timeout */ timeout ? timeout : 120000);
925 /* Disable freezing the device queue */
926 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
928 if (arglist & CAM_ARG_ERR_RECOVER)
929 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
931 if (cam_send_ccb(device, ccb) < 0) {
932 perror("error sending start unit");
934 if (arglist & CAM_ARG_VERBOSE) {
935 cam_error_print(device, ccb, CAM_ESF_ALL,
936 CAM_EPF_ALL, stderr);
943 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
945 fprintf(stdout, "Unit started successfully");
947 fprintf(stdout,", Media loaded\n");
949 fprintf(stdout,"\n");
951 fprintf(stdout, "Unit stopped successfully");
953 fprintf(stdout, ", Media ejected\n");
955 fprintf(stdout, "\n");
961 "Error received from start unit command\n");
964 "Error received from stop unit command\n");
966 if (arglist & CAM_ARG_VERBOSE) {
967 cam_error_print(device, ccb, CAM_ESF_ALL,
968 CAM_EPF_ALL, stderr);
978 scsidoinquiry(struct cam_device *device, int argc, char **argv,
979 char *combinedopt, int task_attr, int retry_count, int timeout)
984 while ((c = getopt(argc, argv, combinedopt)) != -1) {
987 arglist |= CAM_ARG_GET_STDINQ;
990 arglist |= CAM_ARG_GET_XFERRATE;
993 arglist |= CAM_ARG_GET_SERIAL;
1001 * If the user didn't specify any inquiry options, he wants all of
1004 if ((arglist & CAM_ARG_INQ_MASK) == 0)
1005 arglist |= CAM_ARG_INQ_MASK;
1007 if (arglist & CAM_ARG_GET_STDINQ)
1008 error = scsiinquiry(device, task_attr, retry_count, timeout);
1013 if (arglist & CAM_ARG_GET_SERIAL)
1014 scsiserial(device, task_attr, retry_count, timeout);
1016 if (arglist & CAM_ARG_GET_XFERRATE)
1017 error = camxferrate(device);
1023 scsiinquiry(struct cam_device *device, int task_attr, int retry_count,
1027 struct scsi_inquiry_data *inq_buf;
1030 ccb = cam_getccb(device);
1033 warnx("couldn't allocate CCB");
1037 /* cam_getccb cleans up the header, caller has to zero the payload */
1038 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1040 inq_buf = (struct scsi_inquiry_data *)malloc(
1041 sizeof(struct scsi_inquiry_data));
1043 if (inq_buf == NULL) {
1045 warnx("can't malloc memory for inquiry\n");
1048 bzero(inq_buf, sizeof(*inq_buf));
1051 * Note that although the size of the inquiry buffer is the full
1052 * 256 bytes specified in the SCSI spec, we only tell the device
1053 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
1054 * two reasons for this:
1056 * - The SCSI spec says that when a length field is only 1 byte,
1057 * a value of 0 will be interpreted as 256. Therefore
1058 * scsi_inquiry() will convert an inq_len (which is passed in as
1059 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
1060 * to 0. Evidently, very few devices meet the spec in that
1061 * regard. Some devices, like many Seagate disks, take the 0 as
1062 * 0, and don't return any data. One Pioneer DVD-R drive
1063 * returns more data than the command asked for.
1065 * So, since there are numerous devices that just don't work
1066 * right with the full inquiry size, we don't send the full size.
1068 * - The second reason not to use the full inquiry data length is
1069 * that we don't need it here. The only reason we issue a
1070 * standard inquiry is to get the vendor name, device name,
1071 * and revision so scsi_print_inquiry() can print them.
1073 * If, at some point in the future, more inquiry data is needed for
1074 * some reason, this code should use a procedure similar to the
1075 * probe code. i.e., issue a short inquiry, and determine from
1076 * the additional length passed back from the device how much
1077 * inquiry data the device supports. Once the amount the device
1078 * supports is determined, issue an inquiry for that amount and no
1083 scsi_inquiry(&ccb->csio,
1084 /* retries */ retry_count,
1086 /* tag_action */ task_attr,
1087 /* inq_buf */ (u_int8_t *)inq_buf,
1088 /* inq_len */ SHORT_INQUIRY_LENGTH,
1091 /* sense_len */ SSD_FULL_SIZE,
1092 /* timeout */ timeout ? timeout : 5000);
1094 /* Disable freezing the device queue */
1095 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1097 if (arglist & CAM_ARG_ERR_RECOVER)
1098 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1100 if (cam_send_ccb(device, ccb) < 0) {
1101 perror("error sending SCSI inquiry");
1103 if (arglist & CAM_ARG_VERBOSE) {
1104 cam_error_print(device, ccb, CAM_ESF_ALL,
1105 CAM_EPF_ALL, stderr);
1112 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1115 if (arglist & CAM_ARG_VERBOSE) {
1116 cam_error_print(device, ccb, CAM_ESF_ALL,
1117 CAM_EPF_ALL, stderr);
1128 fprintf(stdout, "%s%d: ", device->device_name,
1129 device->dev_unit_num);
1130 scsi_print_inquiry(inq_buf);
1138 scsiserial(struct cam_device *device, int task_attr, int retry_count,
1142 struct scsi_vpd_unit_serial_number *serial_buf;
1143 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
1146 ccb = cam_getccb(device);
1149 warnx("couldn't allocate CCB");
1153 /* cam_getccb cleans up the header, caller has to zero the payload */
1154 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1156 serial_buf = (struct scsi_vpd_unit_serial_number *)
1157 malloc(sizeof(*serial_buf));
1159 if (serial_buf == NULL) {
1161 warnx("can't malloc memory for serial number");
1165 scsi_inquiry(&ccb->csio,
1166 /*retries*/ retry_count,
1168 /* tag_action */ task_attr,
1169 /* inq_buf */ (u_int8_t *)serial_buf,
1170 /* inq_len */ sizeof(*serial_buf),
1172 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
1173 /* sense_len */ SSD_FULL_SIZE,
1174 /* timeout */ timeout ? timeout : 5000);
1176 /* Disable freezing the device queue */
1177 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1179 if (arglist & CAM_ARG_ERR_RECOVER)
1180 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1182 if (cam_send_ccb(device, ccb) < 0) {
1183 warn("error getting serial number");
1185 if (arglist & CAM_ARG_VERBOSE) {
1186 cam_error_print(device, ccb, CAM_ESF_ALL,
1187 CAM_EPF_ALL, stderr);
1195 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1198 if (arglist & CAM_ARG_VERBOSE) {
1199 cam_error_print(device, ccb, CAM_ESF_ALL,
1200 CAM_EPF_ALL, stderr);
1211 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1212 serial_num[serial_buf->length] = '\0';
1214 if ((arglist & CAM_ARG_GET_STDINQ)
1215 || (arglist & CAM_ARG_GET_XFERRATE))
1216 fprintf(stdout, "%s%d: Serial Number ",
1217 device->device_name, device->dev_unit_num);
1219 fprintf(stdout, "%.60s\n", serial_num);
1227 camxferrate(struct cam_device *device)
1229 struct ccb_pathinq cpi;
1231 u_int32_t speed = 0;
1236 if ((retval = get_cpi(device, &cpi)) != 0)
1239 ccb = cam_getccb(device);
1242 warnx("couldn't allocate CCB");
1246 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
1248 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1249 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1251 if (((retval = cam_send_ccb(device, ccb)) < 0)
1252 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1253 const char error_string[] = "error getting transfer settings";
1258 warnx(error_string);
1260 if (arglist & CAM_ARG_VERBOSE)
1261 cam_error_print(device, ccb, CAM_ESF_ALL,
1262 CAM_EPF_ALL, stderr);
1266 goto xferrate_bailout;
1270 speed = cpi.base_transfer_speed;
1272 if (ccb->cts.transport == XPORT_SPI) {
1273 struct ccb_trans_settings_spi *spi =
1274 &ccb->cts.xport_specific.spi;
1276 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1277 freq = scsi_calc_syncsrate(spi->sync_period);
1280 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1281 speed *= (0x01 << spi->bus_width);
1283 } else if (ccb->cts.transport == XPORT_FC) {
1284 struct ccb_trans_settings_fc *fc =
1285 &ccb->cts.xport_specific.fc;
1287 if (fc->valid & CTS_FC_VALID_SPEED)
1288 speed = fc->bitrate;
1289 } else if (ccb->cts.transport == XPORT_SAS) {
1290 struct ccb_trans_settings_sas *sas =
1291 &ccb->cts.xport_specific.sas;
1293 if (sas->valid & CTS_SAS_VALID_SPEED)
1294 speed = sas->bitrate;
1295 } else if (ccb->cts.transport == XPORT_ATA) {
1296 struct ccb_trans_settings_pata *pata =
1297 &ccb->cts.xport_specific.ata;
1299 if (pata->valid & CTS_ATA_VALID_MODE)
1300 speed = ata_mode2speed(pata->mode);
1301 } else if (ccb->cts.transport == XPORT_SATA) {
1302 struct ccb_trans_settings_sata *sata =
1303 &ccb->cts.xport_specific.sata;
1305 if (sata->valid & CTS_SATA_VALID_REVISION)
1306 speed = ata_revision2speed(sata->revision);
1311 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1312 device->device_name, device->dev_unit_num,
1315 fprintf(stdout, "%s%d: %dKB/s transfers",
1316 device->device_name, device->dev_unit_num,
1320 if (ccb->cts.transport == XPORT_SPI) {
1321 struct ccb_trans_settings_spi *spi =
1322 &ccb->cts.xport_specific.spi;
1324 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1325 && (spi->sync_offset != 0))
1326 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1327 freq % 1000, spi->sync_offset);
1329 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1330 && (spi->bus_width > 0)) {
1331 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1332 && (spi->sync_offset != 0)) {
1333 fprintf(stdout, ", ");
1335 fprintf(stdout, " (");
1337 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1338 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1339 && (spi->sync_offset != 0)) {
1340 fprintf(stdout, ")");
1342 } else if (ccb->cts.transport == XPORT_ATA) {
1343 struct ccb_trans_settings_pata *pata =
1344 &ccb->cts.xport_specific.ata;
1347 if (pata->valid & CTS_ATA_VALID_MODE)
1348 printf("%s, ", ata_mode2string(pata->mode));
1349 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1350 printf("ATAPI %dbytes, ", pata->atapi);
1351 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1352 printf("PIO %dbytes", pata->bytecount);
1354 } else if (ccb->cts.transport == XPORT_SATA) {
1355 struct ccb_trans_settings_sata *sata =
1356 &ccb->cts.xport_specific.sata;
1359 if (sata->valid & CTS_SATA_VALID_REVISION)
1360 printf("SATA %d.x, ", sata->revision);
1363 if (sata->valid & CTS_SATA_VALID_MODE)
1364 printf("%s, ", ata_mode2string(sata->mode));
1365 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1366 printf("ATAPI %dbytes, ", sata->atapi);
1367 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1368 printf("PIO %dbytes", sata->bytecount);
1372 if (ccb->cts.protocol == PROTO_SCSI) {
1373 struct ccb_trans_settings_scsi *scsi =
1374 &ccb->cts.proto_specific.scsi;
1375 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1376 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1377 fprintf(stdout, ", Command Queueing Enabled");
1382 fprintf(stdout, "\n");
1392 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1394 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1395 ((u_int32_t)parm->lba_size_2 << 16);
1397 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1398 ((u_int64_t)parm->lba_size48_2 << 16) |
1399 ((u_int64_t)parm->lba_size48_3 << 32) |
1400 ((u_int64_t)parm->lba_size48_4 << 48);
1404 "Support Enabled Value\n");
1407 printf("Host Protected Area (HPA) ");
1408 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1409 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1410 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1413 printf("HPA - Security ");
1414 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1424 atasata(struct ata_params *parm)
1428 if (parm->satacapabilities != 0xffff &&
1429 parm->satacapabilities != 0x0000)
1436 atacapprint(struct ata_params *parm)
1438 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1439 ((u_int32_t)parm->lba_size_2 << 16);
1441 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1442 ((u_int64_t)parm->lba_size48_2 << 16) |
1443 ((u_int64_t)parm->lba_size48_3 << 32) |
1444 ((u_int64_t)parm->lba_size48_4 << 48);
1447 printf("protocol ");
1448 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1449 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1450 if (parm->satacapabilities & ATA_SATA_GEN3)
1451 printf(" SATA 3.x\n");
1452 else if (parm->satacapabilities & ATA_SATA_GEN2)
1453 printf(" SATA 2.x\n");
1454 else if (parm->satacapabilities & ATA_SATA_GEN1)
1455 printf(" SATA 1.x\n");
1461 printf("device model %.40s\n", parm->model);
1462 printf("firmware revision %.8s\n", parm->revision);
1463 printf("serial number %.20s\n", parm->serial);
1464 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1465 printf("WWN %04x%04x%04x%04x\n",
1466 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1468 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1469 printf("media serial number %.30s\n",
1470 parm->media_serial);
1473 printf("cylinders %d\n", parm->cylinders);
1474 printf("heads %d\n", parm->heads);
1475 printf("sectors/track %d\n", parm->sectors);
1476 printf("sector size logical %u, physical %lu, offset %lu\n",
1477 ata_logical_sector_size(parm),
1478 (unsigned long)ata_physical_sector_size(parm),
1479 (unsigned long)ata_logical_sector_offset(parm));
1481 if (parm->config == ATA_PROTO_CFA ||
1482 (parm->support.command2 & ATA_SUPPORT_CFA))
1483 printf("CFA supported\n");
1485 printf("LBA%ssupported ",
1486 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1488 printf("%d sectors\n", lbasize);
1492 printf("LBA48%ssupported ",
1493 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1495 printf("%ju sectors\n", (uintmax_t)lbasize48);
1499 printf("PIO supported PIO");
1500 switch (ata_max_pmode(parm)) {
1516 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1517 printf(" w/o IORDY");
1520 printf("DMA%ssupported ",
1521 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1522 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1523 if (parm->mwdmamodes & 0xff) {
1525 if (parm->mwdmamodes & 0x04)
1527 else if (parm->mwdmamodes & 0x02)
1529 else if (parm->mwdmamodes & 0x01)
1533 if ((parm->atavalid & ATA_FLAG_88) &&
1534 (parm->udmamodes & 0xff)) {
1536 if (parm->udmamodes & 0x40)
1538 else if (parm->udmamodes & 0x20)
1540 else if (parm->udmamodes & 0x10)
1542 else if (parm->udmamodes & 0x08)
1544 else if (parm->udmamodes & 0x04)
1546 else if (parm->udmamodes & 0x02)
1548 else if (parm->udmamodes & 0x01)
1555 if (parm->media_rotation_rate == 1) {
1556 printf("media RPM non-rotating\n");
1557 } else if (parm->media_rotation_rate >= 0x0401 &&
1558 parm->media_rotation_rate <= 0xFFFE) {
1559 printf("media RPM %d\n",
1560 parm->media_rotation_rate);
1563 printf("Zoned-Device Commands ");
1564 switch (parm->support3 & ATA_SUPPORT_ZONE_MASK) {
1565 case ATA_SUPPORT_ZONE_DEV_MANAGED:
1566 printf("device managed\n");
1568 case ATA_SUPPORT_ZONE_HOST_AWARE:
1569 printf("host aware\n");
1576 "Support Enabled Value Vendor\n");
1577 printf("read ahead %s %s\n",
1578 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1579 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1580 printf("write cache %s %s\n",
1581 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1582 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1583 printf("flush cache %s %s\n",
1584 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1585 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1586 printf("overlap %s\n",
1587 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1588 printf("Tagged Command Queuing (TCQ) %s %s",
1589 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1590 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1591 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1592 printf(" %d tags\n",
1593 ATA_QUEUE_LEN(parm->queue) + 1);
1596 printf("Native Command Queuing (NCQ) ");
1597 if (parm->satacapabilities != 0xffff &&
1598 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1599 printf("yes %d tags\n",
1600 ATA_QUEUE_LEN(parm->queue) + 1);
1604 printf("NCQ Queue Management %s\n", atasata(parm) &&
1605 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1607 printf("NCQ Streaming %s\n", atasata(parm) &&
1608 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1610 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1611 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1614 printf("SMART %s %s\n",
1615 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1616 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1617 printf("microcode download %s %s\n",
1618 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1619 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1620 printf("security %s %s\n",
1621 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1622 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1623 printf("power management %s %s\n",
1624 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1625 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1626 printf("advanced power management %s %s",
1627 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1628 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1629 if (parm->support.command2 & ATA_SUPPORT_APM) {
1630 printf(" %d/0x%02X\n",
1631 parm->apm_value & 0xff, parm->apm_value & 0xff);
1634 printf("automatic acoustic management %s %s",
1635 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1636 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1637 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1638 printf(" %d/0x%02X %d/0x%02X\n",
1639 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1640 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1641 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1642 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1645 printf("media status notification %s %s\n",
1646 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1647 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1648 printf("power-up in Standby %s %s\n",
1649 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1650 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1651 printf("write-read-verify %s %s",
1652 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1653 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1654 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1655 printf(" %d/0x%x\n",
1656 parm->wrv_mode, parm->wrv_mode);
1659 printf("unload %s %s\n",
1660 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1661 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1662 printf("general purpose logging %s %s\n",
1663 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1664 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1665 printf("free-fall %s %s\n",
1666 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1667 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1668 printf("Data Set Management (DSM/TRIM) ");
1669 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1671 printf("DSM - max 512byte blocks ");
1672 if (parm->max_dsm_blocks == 0x00)
1673 printf("yes not specified\n");
1676 parm->max_dsm_blocks);
1678 printf("DSM - deterministic read ");
1679 if (parm->support3 & ATA_SUPPORT_DRAT) {
1680 if (parm->support3 & ATA_SUPPORT_RZAT)
1681 printf("yes zeroed\n");
1683 printf("yes any value\n");
1693 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1695 struct ata_pass_16 *ata_pass_16;
1696 struct ata_cmd ata_cmd;
1698 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1699 ata_cmd.command = ata_pass_16->command;
1700 ata_cmd.control = ata_pass_16->control;
1701 ata_cmd.features = ata_pass_16->features;
1703 if (arglist & CAM_ARG_VERBOSE) {
1704 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1705 ata_op_string(&ata_cmd),
1706 ccb->csio.ccb_h.timeout);
1709 /* Disable freezing the device queue */
1710 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1712 if (arglist & CAM_ARG_ERR_RECOVER)
1713 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1715 if (cam_send_ccb(device, ccb) < 0) {
1716 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1717 warn("error sending ATA %s via pass_16",
1718 ata_op_string(&ata_cmd));
1721 if (arglist & CAM_ARG_VERBOSE) {
1722 cam_error_print(device, ccb, CAM_ESF_ALL,
1723 CAM_EPF_ALL, stderr);
1729 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1730 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1731 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1732 warnx("ATA %s via pass_16 failed",
1733 ata_op_string(&ata_cmd));
1735 if (arglist & CAM_ARG_VERBOSE) {
1736 cam_error_print(device, ccb, CAM_ESF_ALL,
1737 CAM_EPF_ALL, stderr);
1748 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1750 if (arglist & CAM_ARG_VERBOSE) {
1751 warnx("sending ATA %s with timeout of %u msecs",
1752 ata_op_string(&(ccb->ataio.cmd)),
1753 ccb->ataio.ccb_h.timeout);
1756 /* Disable freezing the device queue */
1757 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1759 if (arglist & CAM_ARG_ERR_RECOVER)
1760 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1762 if (cam_send_ccb(device, ccb) < 0) {
1763 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1764 warn("error sending ATA %s",
1765 ata_op_string(&(ccb->ataio.cmd)));
1768 if (arglist & CAM_ARG_VERBOSE) {
1769 cam_error_print(device, ccb, CAM_ESF_ALL,
1770 CAM_EPF_ALL, stderr);
1776 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1777 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1778 warnx("ATA %s failed: %d",
1779 ata_op_string(&(ccb->ataio.cmd)), quiet);
1782 if (arglist & CAM_ARG_VERBOSE) {
1783 cam_error_print(device, ccb, CAM_ESF_ALL,
1784 CAM_EPF_ALL, stderr);
1794 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1795 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1796 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1797 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1798 u_int16_t dxfer_len, int timeout, int quiet)
1800 if (data_ptr != NULL) {
1801 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1802 AP_FLAG_TLEN_SECT_CNT;
1803 if (flags & CAM_DIR_OUT)
1804 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1806 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1808 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1811 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1813 scsi_ata_pass_16(&ccb->csio,
1827 /*sense_len*/SSD_FULL_SIZE,
1830 return scsi_cam_pass_16_send(device, ccb, quiet);
1834 ata_try_pass_16(struct cam_device *device)
1836 struct ccb_pathinq cpi;
1838 if (get_cpi(device, &cpi) != 0) {
1839 warnx("couldn't get CPI");
1843 if (cpi.protocol == PROTO_SCSI) {
1844 /* possibly compatible with pass_16 */
1848 /* likely not compatible with pass_16 */
1853 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1854 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1855 u_int8_t command, u_int8_t features, u_int32_t lba,
1856 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1857 int timeout, int quiet)
1861 switch (ata_try_pass_16(device)) {
1865 /* Try using SCSI Passthrough */
1866 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1867 0, tag_action, command, features, lba,
1868 sector_count, data_ptr, dxfer_len,
1872 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1873 cam_fill_ataio(&ccb->ataio,
1882 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1883 return ata_cam_send(device, ccb, quiet);
1887 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1888 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1889 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1890 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1891 u_int16_t dxfer_len, int timeout, int force48bit)
1895 retval = ata_try_pass_16(device);
1902 /* Try using SCSI Passthrough */
1903 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1904 ata_flags, tag_action, command, features,
1905 lba, sector_count, data_ptr, dxfer_len,
1908 if (ata_flags & AP_FLAG_CHK_COND) {
1909 /* Decode ata_res from sense data */
1910 struct ata_res_pass16 *res_pass16;
1911 struct ata_res *res;
1915 /* sense_data is 4 byte aligned */
1916 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1917 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1918 ptr[i] = le16toh(ptr[i]);
1920 /* sense_data is 4 byte aligned */
1921 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1922 &ccb->csio.sense_data;
1923 res = &ccb->ataio.res;
1924 res->flags = res_pass16->flags;
1925 res->status = res_pass16->status;
1926 res->error = res_pass16->error;
1927 res->lba_low = res_pass16->lba_low;
1928 res->lba_mid = res_pass16->lba_mid;
1929 res->lba_high = res_pass16->lba_high;
1930 res->device = res_pass16->device;
1931 res->lba_low_exp = res_pass16->lba_low_exp;
1932 res->lba_mid_exp = res_pass16->lba_mid_exp;
1933 res->lba_high_exp = res_pass16->lba_high_exp;
1934 res->sector_count = res_pass16->sector_count;
1935 res->sector_count_exp = res_pass16->sector_count_exp;
1941 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1942 cam_fill_ataio(&ccb->ataio,
1951 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1952 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1954 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1956 if (ata_flags & AP_FLAG_CHK_COND)
1957 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1959 return ata_cam_send(device, ccb, 0);
1963 dump_data(uint16_t *ptr, uint32_t len)
1967 for (i = 0; i < len / 2; i++) {
1969 printf(" %3d: ", i);
1970 printf("%04hx ", ptr[i]);
1979 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1980 int is48bit, u_int64_t *hpasize)
1982 struct ata_res *res;
1984 res = &ccb->ataio.res;
1985 if (res->status & ATA_STATUS_ERROR) {
1986 if (arglist & CAM_ARG_VERBOSE) {
1987 cam_error_print(device, ccb, CAM_ESF_ALL,
1988 CAM_EPF_ALL, stderr);
1989 printf("error = 0x%02x, sector_count = 0x%04x, "
1990 "device = 0x%02x, status = 0x%02x\n",
1991 res->error, res->sector_count,
1992 res->device, res->status);
1995 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1996 warnx("Max address has already been set since "
1997 "last power-on or hardware reset");
2003 if (arglist & CAM_ARG_VERBOSE) {
2004 fprintf(stdout, "%s%d: Raw native max data:\n",
2005 device->device_name, device->dev_unit_num);
2006 /* res is 4 byte aligned */
2007 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
2009 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
2010 "status = 0x%02x\n", res->error, res->sector_count,
2011 res->device, res->status);
2014 if (hpasize != NULL) {
2016 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
2017 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
2018 ((res->lba_high << 16) | (res->lba_mid << 8) |
2021 *hpasize = (((res->device & 0x0f) << 24) |
2022 (res->lba_high << 16) | (res->lba_mid << 8) |
2031 ata_read_native_max(struct cam_device *device, int retry_count,
2032 u_int32_t timeout, union ccb *ccb,
2033 struct ata_params *parm, u_int64_t *hpasize)
2039 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
2040 protocol = AP_PROTO_NON_DATA;
2043 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
2044 protocol |= AP_EXTEND;
2046 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
2049 error = ata_do_cmd(device,
2052 /*flags*/CAM_DIR_NONE,
2053 /*protocol*/protocol,
2054 /*ata_flags*/AP_FLAG_CHK_COND,
2055 /*tag_action*/MSG_SIMPLE_Q_TAG,
2062 timeout ? timeout : 1000,
2068 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
2072 atahpa_set_max(struct cam_device *device, int retry_count,
2073 u_int32_t timeout, union ccb *ccb,
2074 int is48bit, u_int64_t maxsize, int persist)
2080 protocol = AP_PROTO_NON_DATA;
2083 cmd = ATA_SET_MAX_ADDRESS48;
2084 protocol |= AP_EXTEND;
2086 cmd = ATA_SET_MAX_ADDRESS;
2089 /* lba's are zero indexed so the max lba is requested max - 1 */
2093 error = ata_do_cmd(device,
2096 /*flags*/CAM_DIR_NONE,
2097 /*protocol*/protocol,
2098 /*ata_flags*/AP_FLAG_CHK_COND,
2099 /*tag_action*/MSG_SIMPLE_Q_TAG,
2101 /*features*/ATA_HPA_FEAT_MAX_ADDR,
2103 /*sector_count*/persist,
2106 timeout ? timeout : 1000,
2112 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2116 atahpa_password(struct cam_device *device, int retry_count,
2117 u_int32_t timeout, union ccb *ccb,
2118 int is48bit, struct ata_set_max_pwd *pwd)
2124 protocol = AP_PROTO_PIO_OUT;
2125 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2127 error = ata_do_cmd(device,
2130 /*flags*/CAM_DIR_OUT,
2131 /*protocol*/protocol,
2132 /*ata_flags*/AP_FLAG_CHK_COND,
2133 /*tag_action*/MSG_SIMPLE_Q_TAG,
2135 /*features*/ATA_HPA_FEAT_SET_PWD,
2138 /*data_ptr*/(u_int8_t*)pwd,
2139 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2140 timeout ? timeout : 1000,
2146 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2150 atahpa_lock(struct cam_device *device, int retry_count,
2151 u_int32_t timeout, union ccb *ccb, int is48bit)
2157 protocol = AP_PROTO_NON_DATA;
2158 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2160 error = ata_do_cmd(device,
2163 /*flags*/CAM_DIR_NONE,
2164 /*protocol*/protocol,
2165 /*ata_flags*/AP_FLAG_CHK_COND,
2166 /*tag_action*/MSG_SIMPLE_Q_TAG,
2168 /*features*/ATA_HPA_FEAT_LOCK,
2173 timeout ? timeout : 1000,
2179 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2183 atahpa_unlock(struct cam_device *device, int retry_count,
2184 u_int32_t timeout, union ccb *ccb,
2185 int is48bit, struct ata_set_max_pwd *pwd)
2191 protocol = AP_PROTO_PIO_OUT;
2192 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2194 error = ata_do_cmd(device,
2197 /*flags*/CAM_DIR_OUT,
2198 /*protocol*/protocol,
2199 /*ata_flags*/AP_FLAG_CHK_COND,
2200 /*tag_action*/MSG_SIMPLE_Q_TAG,
2202 /*features*/ATA_HPA_FEAT_UNLOCK,
2205 /*data_ptr*/(u_int8_t*)pwd,
2206 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2207 timeout ? timeout : 1000,
2213 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2217 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2218 u_int32_t timeout, union ccb *ccb, int is48bit)
2224 protocol = AP_PROTO_NON_DATA;
2225 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2227 error = ata_do_cmd(device,
2230 /*flags*/CAM_DIR_NONE,
2231 /*protocol*/protocol,
2232 /*ata_flags*/AP_FLAG_CHK_COND,
2233 /*tag_action*/MSG_SIMPLE_Q_TAG,
2235 /*features*/ATA_HPA_FEAT_FREEZE,
2240 timeout ? timeout : 1000,
2246 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2251 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2252 union ccb *ccb, struct ata_params** ident_bufp)
2254 struct ata_params *ident_buf;
2255 struct ccb_pathinq cpi;
2256 struct ccb_getdev cgd;
2259 u_int8_t command, retry_command;
2261 if (get_cpi(device, &cpi) != 0) {
2262 warnx("couldn't get CPI");
2266 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2267 if (cpi.protocol == PROTO_ATA) {
2268 if (get_cgd(device, &cgd) != 0) {
2269 warnx("couldn't get CGD");
2273 command = (cgd.protocol == PROTO_ATA) ?
2274 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2277 /* We don't know which for sure so try both */
2278 command = ATA_ATA_IDENTIFY;
2279 retry_command = ATA_ATAPI_IDENTIFY;
2282 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2284 warnx("can't calloc memory for identify\n");
2288 error = ata_do_28bit_cmd(device,
2290 /*retries*/retry_count,
2291 /*flags*/CAM_DIR_IN,
2292 /*protocol*/AP_PROTO_PIO_IN,
2293 /*tag_action*/MSG_SIMPLE_Q_TAG,
2298 /*data_ptr*/(u_int8_t *)ptr,
2299 /*dxfer_len*/sizeof(struct ata_params),
2300 /*timeout*/timeout ? timeout : 30 * 1000,
2304 if (retry_command == 0) {
2308 error = ata_do_28bit_cmd(device,
2310 /*retries*/retry_count,
2311 /*flags*/CAM_DIR_IN,
2312 /*protocol*/AP_PROTO_PIO_IN,
2313 /*tag_action*/MSG_SIMPLE_Q_TAG,
2314 /*command*/retry_command,
2318 /*data_ptr*/(u_int8_t *)ptr,
2319 /*dxfer_len*/sizeof(struct ata_params),
2320 /*timeout*/timeout ? timeout : 30 * 1000,
2330 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2331 ptr[i] = le16toh(ptr[i]);
2336 if (arglist & CAM_ARG_VERBOSE) {
2337 fprintf(stdout, "%s%d: Raw identify data:\n",
2338 device->device_name, device->dev_unit_num);
2339 dump_data(ptr, sizeof(struct ata_params));
2342 /* check for invalid (all zero) response */
2344 warnx("Invalid identify response detected");
2349 ident_buf = (struct ata_params *)ptr;
2350 if (strncmp(ident_buf->model, "FX", 2) &&
2351 strncmp(ident_buf->model, "NEC", 3) &&
2352 strncmp(ident_buf->model, "Pioneer", 7) &&
2353 strncmp(ident_buf->model, "SHARP", 5)) {
2354 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2355 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2356 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2357 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2359 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2360 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2361 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2362 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2363 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2364 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2365 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2366 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2367 sizeof(ident_buf->media_serial));
2369 *ident_bufp = ident_buf;
2376 ataidentify(struct cam_device *device, int retry_count, int timeout)
2379 struct ata_params *ident_buf;
2382 if ((ccb = cam_getccb(device)) == NULL) {
2383 warnx("couldn't allocate CCB");
2387 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2392 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2393 if (ata_read_native_max(device, retry_count, timeout, ccb,
2394 ident_buf, &hpasize) != 0) {
2402 printf("%s%d: ", device->device_name, device->dev_unit_num);
2403 ata_print_ident(ident_buf);
2404 camxferrate(device);
2405 atacapprint(ident_buf);
2406 atahpa_print(ident_buf, hpasize, 0);
2416 nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused)
2418 struct nvme_controller_data cdata;
2420 if (nvme_get_cdata(device, &cdata))
2422 nvme_print_controller(&cdata);
2429 identify(struct cam_device *device, int retry_count, int timeout)
2432 struct ccb_pathinq cpi;
2434 if (get_cpi(device, &cpi) != 0) {
2435 warnx("couldn't get CPI");
2439 if (cpi.protocol == PROTO_NVME) {
2440 return (nvmeidentify(device, retry_count, timeout));
2443 return (ataidentify(device, retry_count, timeout));
2445 #endif /* MINIMALISTIC */
2448 #ifndef MINIMALISTIC
2450 ATA_SECURITY_ACTION_PRINT,
2451 ATA_SECURITY_ACTION_FREEZE,
2452 ATA_SECURITY_ACTION_UNLOCK,
2453 ATA_SECURITY_ACTION_DISABLE,
2454 ATA_SECURITY_ACTION_ERASE,
2455 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2456 ATA_SECURITY_ACTION_SET_PASSWORD
2460 atasecurity_print_time(u_int16_t tw)
2464 printf("unspecified");
2466 printf("> 508 min");
2468 printf("%i min", 2 * tw);
2472 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2476 return 2 * 3600 * 1000; /* default: two hours */
2477 else if (timeout > 255)
2478 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2480 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2485 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2489 bzero(&cmd, sizeof(cmd));
2490 cmd.command = command;
2491 printf("Issuing %s", ata_op_string(&cmd));
2494 char pass[sizeof(pwd->password)+1];
2496 /* pwd->password may not be null terminated */
2497 pass[sizeof(pwd->password)] = '\0';
2498 strncpy(pass, pwd->password, sizeof(pwd->password));
2499 printf(" password='%s', user='%s'",
2501 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2504 if (command == ATA_SECURITY_SET_PASSWORD) {
2505 printf(", mode='%s'",
2506 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2507 "maximum" : "high");
2515 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2516 int retry_count, u_int32_t timeout, int quiet)
2520 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2522 return ata_do_28bit_cmd(device,
2525 /*flags*/CAM_DIR_NONE,
2526 /*protocol*/AP_PROTO_NON_DATA,
2527 /*tag_action*/MSG_SIMPLE_Q_TAG,
2528 /*command*/ATA_SECURITY_FREEZE_LOCK,
2539 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2540 int retry_count, u_int32_t timeout,
2541 struct ata_security_password *pwd, int quiet)
2545 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2547 return ata_do_28bit_cmd(device,
2550 /*flags*/CAM_DIR_OUT,
2551 /*protocol*/AP_PROTO_PIO_OUT,
2552 /*tag_action*/MSG_SIMPLE_Q_TAG,
2553 /*command*/ATA_SECURITY_UNLOCK,
2557 /*data_ptr*/(u_int8_t *)pwd,
2558 /*dxfer_len*/sizeof(*pwd),
2564 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2565 int retry_count, u_int32_t timeout,
2566 struct ata_security_password *pwd, int quiet)
2570 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2571 return ata_do_28bit_cmd(device,
2574 /*flags*/CAM_DIR_OUT,
2575 /*protocol*/AP_PROTO_PIO_OUT,
2576 /*tag_action*/MSG_SIMPLE_Q_TAG,
2577 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2581 /*data_ptr*/(u_int8_t *)pwd,
2582 /*dxfer_len*/sizeof(*pwd),
2589 atasecurity_erase_confirm(struct cam_device *device,
2590 struct ata_params* ident_buf)
2593 printf("\nYou are about to ERASE ALL DATA from the following"
2594 " device:\n%s%d,%s%d: ", device->device_name,
2595 device->dev_unit_num, device->given_dev_name,
2596 device->given_unit_number);
2597 ata_print_ident(ident_buf);
2601 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2603 if (fgets(str, sizeof(str), stdin) != NULL) {
2604 if (strncasecmp(str, "yes", 3) == 0) {
2606 } else if (strncasecmp(str, "no", 2) == 0) {
2609 printf("Please answer \"yes\" or "
2620 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2621 int retry_count, u_int32_t timeout,
2622 u_int32_t erase_timeout,
2623 struct ata_security_password *pwd, int quiet)
2628 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2630 error = ata_do_28bit_cmd(device,
2633 /*flags*/CAM_DIR_NONE,
2634 /*protocol*/AP_PROTO_NON_DATA,
2635 /*tag_action*/MSG_SIMPLE_Q_TAG,
2636 /*command*/ATA_SECURITY_ERASE_PREPARE,
2649 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2651 error = ata_do_28bit_cmd(device,
2654 /*flags*/CAM_DIR_OUT,
2655 /*protocol*/AP_PROTO_PIO_OUT,
2656 /*tag_action*/MSG_SIMPLE_Q_TAG,
2657 /*command*/ATA_SECURITY_ERASE_UNIT,
2661 /*data_ptr*/(u_int8_t *)pwd,
2662 /*dxfer_len*/sizeof(*pwd),
2663 /*timeout*/erase_timeout,
2666 if (error == 0 && quiet == 0)
2667 printf("\nErase Complete\n");
2673 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2674 int retry_count, u_int32_t timeout,
2675 struct ata_security_password *pwd, int quiet)
2679 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2681 return ata_do_28bit_cmd(device,
2684 /*flags*/CAM_DIR_OUT,
2685 /*protocol*/AP_PROTO_PIO_OUT,
2686 /*tag_action*/MSG_SIMPLE_Q_TAG,
2687 /*command*/ATA_SECURITY_SET_PASSWORD,
2691 /*data_ptr*/(u_int8_t *)pwd,
2692 /*dxfer_len*/sizeof(*pwd),
2698 atasecurity_print(struct ata_params *parm)
2701 printf("\nSecurity Option Value\n");
2702 if (arglist & CAM_ARG_VERBOSE) {
2703 printf("status %04x\n",
2704 parm->security_status);
2706 printf("supported %s\n",
2707 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2708 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2710 printf("enabled %s\n",
2711 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2712 printf("drive locked %s\n",
2713 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2714 printf("security config frozen %s\n",
2715 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2716 printf("count expired %s\n",
2717 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2718 printf("security level %s\n",
2719 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2720 printf("enhanced erase supported %s\n",
2721 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2722 printf("erase time ");
2723 atasecurity_print_time(parm->erase_time);
2725 printf("enhanced erase time ");
2726 atasecurity_print_time(parm->enhanced_erase_time);
2728 printf("master password rev %04x%s\n",
2729 parm->master_passwd_revision,
2730 parm->master_passwd_revision == 0x0000 ||
2731 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2735 * Validates and copies the password in optarg to the passed buffer.
2736 * If the password in optarg is the same length as the buffer then
2737 * the data will still be copied but no null termination will occur.
2740 ata_getpwd(u_int8_t *passwd, int max, char opt)
2744 len = strlen(optarg);
2746 warnx("-%c password is too long", opt);
2748 } else if (len == 0) {
2749 warnx("-%c password is missing", opt);
2751 } else if (optarg[0] == '-'){
2752 warnx("-%c password starts with '-' (generic arg?)", opt);
2754 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2755 warnx("-%c password conflicts with existing password from -%c",
2760 /* Callers pass in a buffer which does NOT need to be terminated */
2761 strncpy(passwd, optarg, max);
2768 ATA_HPA_ACTION_PRINT,
2769 ATA_HPA_ACTION_SET_MAX,
2770 ATA_HPA_ACTION_SET_PWD,
2771 ATA_HPA_ACTION_LOCK,
2772 ATA_HPA_ACTION_UNLOCK,
2773 ATA_HPA_ACTION_FREEZE_LOCK
2777 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2778 u_int64_t maxsize, int persist)
2780 printf("\nYou are about to configure HPA to limit the user accessible\n"
2781 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2782 persist ? "persistently" : "temporarily",
2783 device->device_name, device->dev_unit_num,
2784 device->given_dev_name, device->given_unit_number);
2785 ata_print_ident(ident_buf);
2789 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2791 if (NULL != fgets(str, sizeof(str), stdin)) {
2792 if (0 == strncasecmp(str, "yes", 3)) {
2794 } else if (0 == strncasecmp(str, "no", 2)) {
2797 printf("Please answer \"yes\" or "
2808 atahpa(struct cam_device *device, int retry_count, int timeout,
2809 int argc, char **argv, char *combinedopt)
2812 struct ata_params *ident_buf;
2813 struct ccb_getdev cgd;
2814 struct ata_set_max_pwd pwd;
2815 int error, confirm, quiet, c, action, actions, persist;
2816 int security, is48bit, pwdsize;
2817 u_int64_t hpasize, maxsize;
2826 memset(&pwd, 0, sizeof(pwd));
2828 /* default action is to print hpa information */
2829 action = ATA_HPA_ACTION_PRINT;
2830 pwdsize = sizeof(pwd.password);
2832 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2835 action = ATA_HPA_ACTION_SET_MAX;
2836 maxsize = strtoumax(optarg, NULL, 0);
2841 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2843 action = ATA_HPA_ACTION_SET_PWD;
2849 action = ATA_HPA_ACTION_LOCK;
2855 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2857 action = ATA_HPA_ACTION_UNLOCK;
2863 action = ATA_HPA_ACTION_FREEZE_LOCK;
2883 warnx("too many hpa actions specified");
2887 if (get_cgd(device, &cgd) != 0) {
2888 warnx("couldn't get CGD");
2892 ccb = cam_getccb(device);
2894 warnx("couldn't allocate CCB");
2898 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2905 printf("%s%d: ", device->device_name, device->dev_unit_num);
2906 ata_print_ident(ident_buf);
2907 camxferrate(device);
2910 if (action == ATA_HPA_ACTION_PRINT) {
2911 error = ata_read_native_max(device, retry_count, timeout, ccb,
2912 ident_buf, &hpasize);
2914 atahpa_print(ident_buf, hpasize, 1);
2921 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2922 warnx("HPA is not supported by this device");
2928 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2929 warnx("HPA Security is not supported by this device");
2935 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2938 * The ATA spec requires:
2939 * 1. Read native max addr is called directly before set max addr
2940 * 2. Read native max addr is NOT called before any other set max call
2943 case ATA_HPA_ACTION_SET_MAX:
2945 atahpa_set_confirm(device, ident_buf, maxsize,
2952 error = ata_read_native_max(device, retry_count, timeout,
2953 ccb, ident_buf, &hpasize);
2955 error = atahpa_set_max(device, retry_count, timeout,
2956 ccb, is48bit, maxsize, persist);
2958 /* redo identify to get new lba values */
2959 error = ata_do_identify(device, retry_count,
2962 atahpa_print(ident_buf, hpasize, 1);
2967 case ATA_HPA_ACTION_SET_PWD:
2968 error = atahpa_password(device, retry_count, timeout,
2969 ccb, is48bit, &pwd);
2971 printf("HPA password has been set\n");
2974 case ATA_HPA_ACTION_LOCK:
2975 error = atahpa_lock(device, retry_count, timeout,
2978 printf("HPA has been locked\n");
2981 case ATA_HPA_ACTION_UNLOCK:
2982 error = atahpa_unlock(device, retry_count, timeout,
2983 ccb, is48bit, &pwd);
2985 printf("HPA has been unlocked\n");
2988 case ATA_HPA_ACTION_FREEZE_LOCK:
2989 error = atahpa_freeze_lock(device, retry_count, timeout,
2992 printf("HPA has been frozen\n");
2996 errx(1, "Option currently not supported");
3006 atasecurity(struct cam_device *device, int retry_count, int timeout,
3007 int argc, char **argv, char *combinedopt)
3010 struct ata_params *ident_buf;
3011 int error, confirm, quiet, c, action, actions, setpwd;
3012 int security_enabled, erase_timeout, pwdsize;
3013 struct ata_security_password pwd;
3021 memset(&pwd, 0, sizeof(pwd));
3023 /* default action is to print security information */
3024 action = ATA_SECURITY_ACTION_PRINT;
3026 /* user is master by default as its safer that way */
3027 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3028 pwdsize = sizeof(pwd.password);
3030 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3033 action = ATA_SECURITY_ACTION_FREEZE;
3038 if (strcasecmp(optarg, "user") == 0) {
3039 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
3040 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
3041 } else if (strcasecmp(optarg, "master") == 0) {
3042 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3043 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
3045 warnx("-U argument '%s' is invalid (must be "
3046 "'user' or 'master')", optarg);
3052 if (strcasecmp(optarg, "high") == 0) {
3053 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3054 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3055 } else if (strcasecmp(optarg, "maximum") == 0) {
3056 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3057 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3059 warnx("-l argument '%s' is unknown (must be "
3060 "'high' or 'maximum')", optarg);
3066 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3068 action = ATA_SECURITY_ACTION_UNLOCK;
3073 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3075 action = ATA_SECURITY_ACTION_DISABLE;
3080 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3082 action = ATA_SECURITY_ACTION_ERASE;
3087 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3089 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3090 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3095 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3098 if (action == ATA_SECURITY_ACTION_PRINT)
3099 action = ATA_SECURITY_ACTION_SET_PASSWORD;
3101 * Don't increment action as this can be combined
3102 * with other actions.
3115 erase_timeout = atoi(optarg) * 1000;
3121 warnx("too many security actions specified");
3125 if ((ccb = cam_getccb(device)) == NULL) {
3126 warnx("couldn't allocate CCB");
3130 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3137 printf("%s%d: ", device->device_name, device->dev_unit_num);
3138 ata_print_ident(ident_buf);
3139 camxferrate(device);
3142 if (action == ATA_SECURITY_ACTION_PRINT) {
3143 atasecurity_print(ident_buf);
3149 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3150 warnx("Security not supported");
3156 /* default timeout 15 seconds the same as linux hdparm */
3157 timeout = timeout ? timeout : 15 * 1000;
3159 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3161 /* first set the password if requested */
3163 /* confirm we can erase before setting the password if erasing */
3165 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3166 action == ATA_SECURITY_ACTION_ERASE) &&
3167 atasecurity_erase_confirm(device, ident_buf) == 0) {
3173 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3174 pwd.revision = ident_buf->master_passwd_revision;
3175 if (pwd.revision != 0 && pwd.revision != 0xfff &&
3176 --pwd.revision == 0) {
3177 pwd.revision = 0xfffe;
3180 error = atasecurity_set_password(device, ccb, retry_count,
3181 timeout, &pwd, quiet);
3187 security_enabled = 1;
3191 case ATA_SECURITY_ACTION_FREEZE:
3192 error = atasecurity_freeze(device, ccb, retry_count,
3196 case ATA_SECURITY_ACTION_UNLOCK:
3197 if (security_enabled) {
3198 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3199 error = atasecurity_unlock(device, ccb,
3200 retry_count, timeout, &pwd, quiet);
3202 warnx("Can't unlock, drive is not locked");
3206 warnx("Can't unlock, security is disabled");
3211 case ATA_SECURITY_ACTION_DISABLE:
3212 if (security_enabled) {
3213 /* First unlock the drive if its locked */
3214 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3215 error = atasecurity_unlock(device, ccb,
3223 error = atasecurity_disable(device,
3231 warnx("Can't disable security (already disabled)");
3236 case ATA_SECURITY_ACTION_ERASE:
3237 if (security_enabled) {
3238 if (erase_timeout == 0) {
3239 erase_timeout = atasecurity_erase_timeout_msecs(
3240 ident_buf->erase_time);
3243 error = atasecurity_erase(device, ccb, retry_count,
3244 timeout, erase_timeout, &pwd, quiet);
3246 warnx("Can't secure erase (security is disabled)");
3251 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3252 if (security_enabled) {
3253 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3254 if (erase_timeout == 0) {
3256 atasecurity_erase_timeout_msecs(
3257 ident_buf->enhanced_erase_time);
3260 error = atasecurity_erase(device, ccb,
3261 retry_count, timeout,
3262 erase_timeout, &pwd,
3265 warnx("Enhanced erase is not supported");
3269 warnx("Can't secure erase (enhanced), "
3270 "(security is disabled)");
3281 #endif /* MINIMALISTIC */
3284 * Parse out a bus, or a bus, target and lun in the following
3290 * Returns the number of parsed components, or 0.
3293 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3294 cam_argmask *arglst)
3299 while (isspace(*tstr) && (*tstr != '\0'))
3302 tmpstr = (char *)strtok(tstr, ":");
3303 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3304 *bus = strtol(tmpstr, NULL, 0);
3305 *arglst |= CAM_ARG_BUS;
3307 tmpstr = (char *)strtok(NULL, ":");
3308 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3309 *target = strtol(tmpstr, NULL, 0);
3310 *arglst |= CAM_ARG_TARGET;
3312 tmpstr = (char *)strtok(NULL, ":");
3313 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3314 *lun = strtol(tmpstr, NULL, 0);
3315 *arglst |= CAM_ARG_LUN;
3325 dorescan_or_reset(int argc, char **argv, int rescan)
3327 static const char must[] =
3328 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3330 path_id_t bus = CAM_BUS_WILDCARD;
3331 target_id_t target = CAM_TARGET_WILDCARD;
3332 lun_id_t lun = CAM_LUN_WILDCARD;
3336 warnx(must, rescan? "rescan" : "reset");
3340 tstr = argv[optind];
3341 while (isspace(*tstr) && (*tstr != '\0'))
3343 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3344 arglist |= CAM_ARG_BUS;
3345 else if (isdigit(*tstr)) {
3346 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3347 if (rv != 1 && rv != 3) {
3348 warnx(must, rescan? "rescan" : "reset");
3358 * Note that resetting or rescanning a device used to
3359 * require a bus or bus:target:lun. This is because the
3360 * device in question may not exist and you're trying to
3361 * get the controller to rescan to find it. It may also be
3362 * because the device is hung / unresponsive, and opening
3363 * an unresponsive device is not desireable.
3365 * It can be more convenient to reference a device by
3366 * peripheral name and unit number, though, and it is
3367 * possible to get the bus:target:lun for devices that
3368 * currently exist in the EDT. So this can work for
3369 * devices that we want to reset, or devices that exist
3370 * that we want to rescan, but not devices that do not
3373 * So, we are careful here to look up the bus/target/lun
3374 * for the device the user wants to operate on, specified
3375 * by peripheral instance (e.g. da0, pass32) without
3376 * actually opening that device. The process is similar to
3377 * what cam_lookup_pass() does, except that we don't
3378 * actually open the passthrough driver instance in the end.
3381 if (cam_get_device(tstr, name, sizeof(name), &unit) == -1) {
3382 warnx("%s", cam_errbuf);
3387 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3388 warn("Unable to open %s", XPT_DEVICE);
3393 bzero(&ccb, sizeof(ccb));
3396 * The function code isn't strictly necessary for the
3397 * GETPASSTHRU ioctl.
3399 ccb.ccb_h.func_code = XPT_GDEVLIST;
3402 * These two are necessary for the GETPASSTHRU ioctl to
3405 strlcpy(ccb.cgdl.periph_name, name,
3406 sizeof(ccb.cgdl.periph_name));
3407 ccb.cgdl.unit_number = unit;
3410 * Attempt to get the passthrough device. This ioctl will
3411 * fail if the device name is null, if the device doesn't
3412 * exist, or if the passthrough driver isn't in the kernel.
3414 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3415 warn("Unable to find bus:target:lun for device %s%d",
3421 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3422 const struct cam_status_entry *entry;
3424 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3425 warnx("Unable to find bus:target_lun for device %s%d, "
3426 "CAM status: %s (%#x)", name, unit,
3427 entry ? entry->status_text : "Unknown",
3435 * The kernel fills in the bus/target/lun. We don't
3436 * need the passthrough device name and unit number since
3437 * we aren't going to open it.
3439 bus = ccb.ccb_h.path_id;
3440 target = ccb.ccb_h.target_id;
3441 lun = ccb.ccb_h.target_lun;
3443 arglist |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3448 if ((arglist & CAM_ARG_BUS)
3449 && (arglist & CAM_ARG_TARGET)
3450 && (arglist & CAM_ARG_LUN))
3451 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3453 error = rescan_or_reset_bus(bus, rescan);
3461 rescan_or_reset_bus(path_id_t bus, int rescan)
3463 union ccb *ccb = NULL, *matchccb = NULL;
3464 int fd = -1, retval;
3469 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3470 warnx("error opening transport layer device %s", XPT_DEVICE);
3471 warn("%s", XPT_DEVICE);
3475 ccb = malloc(sizeof(*ccb));
3477 warn("failed to allocate CCB");
3481 bzero(ccb, sizeof(*ccb));
3483 if (bus != CAM_BUS_WILDCARD) {
3484 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3485 ccb->ccb_h.path_id = bus;
3486 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3487 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3488 ccb->crcn.flags = CAM_FLAG_NONE;
3490 /* run this at a low priority */
3491 ccb->ccb_h.pinfo.priority = 5;
3493 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3494 warn("CAMIOCOMMAND ioctl failed");
3499 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3500 fprintf(stdout, "%s of bus %d was successful\n",
3501 rescan ? "Re-scan" : "Reset", bus);
3503 fprintf(stdout, "%s of bus %d returned error %#x\n",
3504 rescan ? "Re-scan" : "Reset", bus,
3505 ccb->ccb_h.status & CAM_STATUS_MASK);
3514 * The right way to handle this is to modify the xpt so that it can
3515 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3516 * that isn't implemented, so instead we enumerate the buses and
3517 * send the rescan or reset to those buses in the case where the
3518 * given bus is -1 (wildcard). We don't send a rescan or reset
3519 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3520 * no-op, sending a rescan to the xpt bus would result in a status of
3523 matchccb = malloc(sizeof(*matchccb));
3524 if (matchccb == NULL) {
3525 warn("failed to allocate CCB");
3529 bzero(matchccb, sizeof(*matchccb));
3530 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3531 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3532 bufsize = sizeof(struct dev_match_result) * 20;
3533 matchccb->cdm.match_buf_len = bufsize;
3534 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3535 if (matchccb->cdm.matches == NULL) {
3536 warnx("can't malloc memory for matches");
3540 matchccb->cdm.num_matches = 0;
3542 matchccb->cdm.num_patterns = 1;
3543 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3545 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3546 matchccb->cdm.pattern_buf_len);
3547 if (matchccb->cdm.patterns == NULL) {
3548 warnx("can't malloc memory for patterns");
3552 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3553 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3558 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3559 warn("CAMIOCOMMAND ioctl failed");
3564 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3565 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3566 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3567 warnx("got CAM error %#x, CDM error %d\n",
3568 matchccb->ccb_h.status, matchccb->cdm.status);
3573 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3574 struct bus_match_result *bus_result;
3576 /* This shouldn't happen. */
3577 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3580 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3583 * We don't want to rescan or reset the xpt bus.
3586 if (bus_result->path_id == CAM_XPT_PATH_ID)
3589 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3591 ccb->ccb_h.path_id = bus_result->path_id;
3592 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3593 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3594 ccb->crcn.flags = CAM_FLAG_NONE;
3596 /* run this at a low priority */
3597 ccb->ccb_h.pinfo.priority = 5;
3599 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3600 warn("CAMIOCOMMAND ioctl failed");
3605 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3606 fprintf(stdout, "%s of bus %d was successful\n",
3607 rescan? "Re-scan" : "Reset",
3608 bus_result->path_id);
3611 * Don't bail out just yet, maybe the other
3612 * rescan or reset commands will complete
3615 fprintf(stderr, "%s of bus %d returned error "
3616 "%#x\n", rescan? "Re-scan" : "Reset",
3617 bus_result->path_id,
3618 ccb->ccb_h.status & CAM_STATUS_MASK);
3622 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3623 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3630 if (matchccb != NULL) {
3631 free(matchccb->cdm.patterns);
3632 free(matchccb->cdm.matches);
3641 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3644 struct cam_device *device;
3649 if (bus == CAM_BUS_WILDCARD) {
3650 warnx("invalid bus number %d", bus);
3654 if (target == CAM_TARGET_WILDCARD) {
3655 warnx("invalid target number %d", target);
3659 if (lun == CAM_LUN_WILDCARD) {
3660 warnx("invalid lun number %jx", (uintmax_t)lun);
3666 bzero(&ccb, sizeof(union ccb));
3669 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3670 warnx("error opening transport layer device %s\n",
3672 warn("%s", XPT_DEVICE);
3676 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3677 if (device == NULL) {
3678 warnx("%s", cam_errbuf);
3683 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3684 ccb.ccb_h.path_id = bus;
3685 ccb.ccb_h.target_id = target;
3686 ccb.ccb_h.target_lun = lun;
3687 ccb.ccb_h.timeout = 5000;
3688 ccb.crcn.flags = CAM_FLAG_NONE;
3690 /* run this at a low priority */
3691 ccb.ccb_h.pinfo.priority = 5;
3694 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3695 warn("CAMIOCOMMAND ioctl failed");
3700 if (cam_send_ccb(device, &ccb) < 0) {
3701 warn("error sending XPT_RESET_DEV CCB");
3702 cam_close_device(device);
3710 cam_close_device(device);
3713 * An error code of CAM_BDR_SENT is normal for a BDR request.
3715 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3717 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3718 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3719 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3722 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3723 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3724 ccb.ccb_h.status & CAM_STATUS_MASK);
3729 #ifndef MINIMALISTIC
3731 static struct scsi_nv defect_list_type_map[] = {
3732 { "block", SRDD10_BLOCK_FORMAT },
3733 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3734 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3735 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3736 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3737 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3741 readdefects(struct cam_device *device, int argc, char **argv,
3742 char *combinedopt, int task_attr, int retry_count, int timeout)
3744 union ccb *ccb = NULL;
3745 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3746 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3747 size_t hdr_size = 0, entry_size = 0;
3750 u_int8_t *defect_list = NULL;
3751 u_int8_t list_format = 0;
3752 int list_type_set = 0;
3753 u_int32_t dlist_length = 0;
3754 u_int32_t returned_length = 0, valid_len = 0;
3755 u_int32_t num_returned = 0, num_valid = 0;
3756 u_int32_t max_possible_size = 0, hdr_max = 0;
3757 u_int32_t starting_offset = 0;
3758 u_int8_t returned_format, returned_type;
3760 int summary = 0, quiet = 0;
3762 int lists_specified = 0;
3763 int get_length = 1, first_pass = 1;
3766 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3770 scsi_nv_status status;
3773 status = scsi_get_nv(defect_list_type_map,
3774 sizeof(defect_list_type_map) /
3775 sizeof(defect_list_type_map[0]), optarg,
3776 &entry_num, SCSI_NV_FLAG_IG_CASE);
3778 if (status == SCSI_NV_FOUND) {
3779 list_format = defect_list_type_map[
3783 warnx("%s: %s %s option %s", __func__,
3784 (status == SCSI_NV_AMBIGUOUS) ?
3785 "ambiguous" : "invalid", "defect list type",
3788 goto defect_bailout;
3793 arglist |= CAM_ARG_GLIST;
3796 arglist |= CAM_ARG_PLIST;
3807 starting_offset = strtoul(optarg, &endptr, 0);
3808 if (*endptr != '\0') {
3810 warnx("invalid starting offset %s", optarg);
3811 goto defect_bailout;
3823 if (list_type_set == 0) {
3825 warnx("no defect list format specified");
3826 goto defect_bailout;
3829 if (arglist & CAM_ARG_PLIST) {
3830 list_format |= SRDD10_PLIST;
3834 if (arglist & CAM_ARG_GLIST) {
3835 list_format |= SRDD10_GLIST;
3840 * This implies a summary, and was the previous behavior.
3842 if (lists_specified == 0)
3845 ccb = cam_getccb(device);
3850 * We start off asking for just the header to determine how much
3851 * defect data is available. Some Hitachi drives return an error
3852 * if you ask for more data than the drive has. Once we know the
3853 * length, we retry the command with the returned length.
3855 if (use_12byte == 0)
3856 dlist_length = sizeof(*hdr10);
3858 dlist_length = sizeof(*hdr12);
3861 if (defect_list != NULL) {
3865 defect_list = malloc(dlist_length);
3866 if (defect_list == NULL) {
3867 warnx("can't malloc memory for defect list");
3869 goto defect_bailout;
3873 bzero(defect_list, dlist_length);
3876 * cam_getccb() zeros the CCB header only. So we need to zero the
3877 * payload portion of the ccb.
3879 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3881 scsi_read_defects(&ccb->csio,
3882 /*retries*/ retry_count,
3884 /*tag_action*/ task_attr,
3885 /*list_format*/ list_format,
3886 /*addr_desc_index*/ starting_offset,
3887 /*data_ptr*/ defect_list,
3888 /*dxfer_len*/ dlist_length,
3889 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3890 /*sense_len*/ SSD_FULL_SIZE,
3891 /*timeout*/ timeout ? timeout : 5000);
3893 /* Disable freezing the device queue */
3894 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3896 if (cam_send_ccb(device, ccb) < 0) {
3897 perror("error reading defect list");
3899 if (arglist & CAM_ARG_VERBOSE) {
3900 cam_error_print(device, ccb, CAM_ESF_ALL,
3901 CAM_EPF_ALL, stderr);
3905 goto defect_bailout;
3908 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3910 if (use_12byte == 0) {
3911 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3912 hdr_size = sizeof(*hdr10);
3913 hdr_max = SRDDH10_MAX_LENGTH;
3915 if (valid_len >= hdr_size) {
3916 returned_length = scsi_2btoul(hdr10->length);
3917 returned_format = hdr10->format;
3919 returned_length = 0;
3920 returned_format = 0;
3923 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3924 hdr_size = sizeof(*hdr12);
3925 hdr_max = SRDDH12_MAX_LENGTH;
3927 if (valid_len >= hdr_size) {
3928 returned_length = scsi_4btoul(hdr12->length);
3929 returned_format = hdr12->format;
3931 returned_length = 0;
3932 returned_format = 0;
3936 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3937 switch (returned_type) {
3938 case SRDD10_BLOCK_FORMAT:
3939 entry_size = sizeof(struct scsi_defect_desc_block);
3941 case SRDD10_LONG_BLOCK_FORMAT:
3942 entry_size = sizeof(struct scsi_defect_desc_long_block);
3944 case SRDD10_EXT_PHYS_FORMAT:
3945 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3946 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3948 case SRDD10_EXT_BFI_FORMAT:
3949 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3950 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3953 warnx("Unknown defect format 0x%x\n", returned_type);
3955 goto defect_bailout;
3959 max_possible_size = (hdr_max / entry_size) * entry_size;
3960 num_returned = returned_length / entry_size;
3961 num_valid = min(returned_length, valid_len - hdr_size);
3962 num_valid /= entry_size;
3964 if (get_length != 0) {
3967 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3968 CAM_SCSI_STATUS_ERROR) {
3969 struct scsi_sense_data *sense;
3970 int error_code, sense_key, asc, ascq;
3972 sense = &ccb->csio.sense_data;
3973 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3974 ccb->csio.sense_resid, &error_code, &sense_key,
3975 &asc, &ascq, /*show_errors*/ 1);
3978 * If the drive is reporting that it just doesn't
3979 * support the defect list format, go ahead and use
3980 * the length it reported. Otherwise, the length
3981 * may not be valid, so use the maximum.
3983 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3984 && (asc == 0x1c) && (ascq == 0x00)
3985 && (returned_length > 0)) {
3986 if ((use_12byte == 0)
3987 && (returned_length >= max_possible_size)) {
3992 dlist_length = returned_length + hdr_size;
3993 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3994 && (asc == 0x1f) && (ascq == 0x00)
3995 && (returned_length > 0)) {
3996 /* Partial defect list transfer */
3998 * Hitachi drives return this error
3999 * along with a partial defect list if they
4000 * have more defects than the 10 byte
4001 * command can support. Retry with the 12
4004 if (use_12byte == 0) {
4009 dlist_length = returned_length + hdr_size;
4010 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
4011 && (asc == 0x24) && (ascq == 0x00)) {
4012 /* Invalid field in CDB */
4014 * SBC-3 says that if the drive has more
4015 * defects than can be reported with the
4016 * 10 byte command, it should return this
4017 * error and no data. Retry with the 12
4020 if (use_12byte == 0) {
4025 dlist_length = returned_length + hdr_size;
4028 * If we got a SCSI error and no valid length,
4029 * just use the 10 byte maximum. The 12
4030 * byte maximum is too large.
4032 if (returned_length == 0)
4033 dlist_length = SRDD10_MAX_LENGTH;
4035 if ((use_12byte == 0)
4036 && (returned_length >=
4037 max_possible_size)) {
4042 dlist_length = returned_length +
4046 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4049 warnx("Error reading defect header");
4050 if (arglist & CAM_ARG_VERBOSE)
4051 cam_error_print(device, ccb, CAM_ESF_ALL,
4052 CAM_EPF_ALL, stderr);
4053 goto defect_bailout;
4055 if ((use_12byte == 0)
4056 && (returned_length >= max_possible_size)) {
4061 dlist_length = returned_length + hdr_size;
4064 fprintf(stdout, "%u", num_returned);
4066 fprintf(stdout, " defect%s",
4067 (num_returned != 1) ? "s" : "");
4069 fprintf(stdout, "\n");
4071 goto defect_bailout;
4075 * We always limit the list length to the 10-byte maximum
4076 * length (0xffff). The reason is that some controllers
4077 * can't handle larger I/Os, and we can transfer the entire
4078 * 10 byte list in one shot. For drives that support the 12
4079 * byte read defects command, we'll step through the list
4080 * by specifying a starting offset. For drives that don't
4081 * support the 12 byte command's starting offset, we'll
4082 * just display the first 64K.
4084 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4090 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4091 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4092 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4093 struct scsi_sense_data *sense;
4094 int error_code, sense_key, asc, ascq;
4096 sense = &ccb->csio.sense_data;
4097 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4098 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4099 &ascq, /*show_errors*/ 1);
4102 * According to the SCSI spec, if the disk doesn't support
4103 * the requested format, it will generally return a sense
4104 * key of RECOVERED ERROR, and an additional sense code
4105 * of "DEFECT LIST NOT FOUND". HGST drives also return
4106 * Primary/Grown defect list not found errors. So just
4107 * check for an ASC of 0x1c.
4109 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4111 const char *format_str;
4113 format_str = scsi_nv_to_str(defect_list_type_map,
4114 sizeof(defect_list_type_map) /
4115 sizeof(defect_list_type_map[0]),
4116 list_format & SRDD10_DLIST_FORMAT_MASK);
4117 warnx("requested defect format %s not available",
4118 format_str ? format_str : "unknown");
4120 format_str = scsi_nv_to_str(defect_list_type_map,
4121 sizeof(defect_list_type_map) /
4122 sizeof(defect_list_type_map[0]), returned_type);
4123 if (format_str != NULL) {
4124 warnx("Device returned %s format",
4128 warnx("Device returned unknown defect"
4129 " data format %#x", returned_type);
4130 goto defect_bailout;
4134 warnx("Error returned from read defect data command");
4135 if (arglist & CAM_ARG_VERBOSE)
4136 cam_error_print(device, ccb, CAM_ESF_ALL,
4137 CAM_EPF_ALL, stderr);
4138 goto defect_bailout;
4140 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4142 warnx("Error returned from read defect data command");
4143 if (arglist & CAM_ARG_VERBOSE)
4144 cam_error_print(device, ccb, CAM_ESF_ALL,
4145 CAM_EPF_ALL, stderr);
4146 goto defect_bailout;
4149 if (first_pass != 0) {
4150 fprintf(stderr, "Got %d defect", num_returned);
4152 if ((lists_specified == 0) || (num_returned == 0)) {
4153 fprintf(stderr, "s.\n");
4154 goto defect_bailout;
4155 } else if (num_returned == 1)
4156 fprintf(stderr, ":\n");
4158 fprintf(stderr, "s:\n");
4164 * XXX KDM I should probably clean up the printout format for the
4167 switch (returned_type) {
4168 case SRDD10_PHYSICAL_SECTOR_FORMAT:
4169 case SRDD10_EXT_PHYS_FORMAT:
4171 struct scsi_defect_desc_phys_sector *dlist;
4173 dlist = (struct scsi_defect_desc_phys_sector *)
4174 (defect_list + hdr_size);
4176 for (i = 0; i < num_valid; i++) {
4179 sector = scsi_4btoul(dlist[i].sector);
4180 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4181 mads = (sector & SDD_EXT_PHYS_MADS) ?
4183 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4185 if (hex_format == 0)
4186 fprintf(stdout, "%d:%d:%d%s",
4187 scsi_3btoul(dlist[i].cylinder),
4189 scsi_4btoul(dlist[i].sector),
4190 mads ? " - " : "\n");
4192 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4193 scsi_3btoul(dlist[i].cylinder),
4195 scsi_4btoul(dlist[i].sector),
4196 mads ? " - " : "\n");
4199 if (num_valid < num_returned) {
4200 starting_offset += num_valid;
4205 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4206 case SRDD10_EXT_BFI_FORMAT:
4208 struct scsi_defect_desc_bytes_from_index *dlist;
4210 dlist = (struct scsi_defect_desc_bytes_from_index *)
4211 (defect_list + hdr_size);
4213 for (i = 0; i < num_valid; i++) {
4216 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4217 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4218 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4219 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4221 if (hex_format == 0)
4222 fprintf(stdout, "%d:%d:%d%s",
4223 scsi_3btoul(dlist[i].cylinder),
4225 scsi_4btoul(dlist[i].bytes_from_index),
4226 mads ? " - " : "\n");
4228 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4229 scsi_3btoul(dlist[i].cylinder),
4231 scsi_4btoul(dlist[i].bytes_from_index),
4232 mads ? " - " : "\n");
4236 if (num_valid < num_returned) {
4237 starting_offset += num_valid;
4242 case SRDDH10_BLOCK_FORMAT:
4244 struct scsi_defect_desc_block *dlist;
4246 dlist = (struct scsi_defect_desc_block *)
4247 (defect_list + hdr_size);
4249 for (i = 0; i < num_valid; i++) {
4250 if (hex_format == 0)
4251 fprintf(stdout, "%u\n",
4252 scsi_4btoul(dlist[i].address));
4254 fprintf(stdout, "0x%x\n",
4255 scsi_4btoul(dlist[i].address));
4258 if (num_valid < num_returned) {
4259 starting_offset += num_valid;
4265 case SRDD10_LONG_BLOCK_FORMAT:
4267 struct scsi_defect_desc_long_block *dlist;
4269 dlist = (struct scsi_defect_desc_long_block *)
4270 (defect_list + hdr_size);
4272 for (i = 0; i < num_valid; i++) {
4273 if (hex_format == 0)
4274 fprintf(stdout, "%ju\n",
4275 (uintmax_t)scsi_8btou64(
4278 fprintf(stdout, "0x%jx\n",
4279 (uintmax_t)scsi_8btou64(
4283 if (num_valid < num_returned) {
4284 starting_offset += num_valid;
4290 fprintf(stderr, "Unknown defect format 0x%x\n",
4297 if (defect_list != NULL)
4305 #endif /* MINIMALISTIC */
4309 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4313 ccb = cam_getccb(device);
4319 #ifndef MINIMALISTIC
4321 mode_sense(struct cam_device *device, int dbd, int pc, int page, int subpage,
4322 int task_attr, int retry_count, int timeout, u_int8_t *data,
4328 ccb = cam_getccb(device);
4331 errx(1, "mode_sense: couldn't allocate CCB");
4333 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4335 scsi_mode_sense_subpage(&ccb->csio,
4336 /* retries */ retry_count,
4338 /* tag_action */ task_attr,
4342 /* subpage */ subpage,
4343 /* param_buf */ data,
4344 /* param_len */ datalen,
4345 /* minimum_cmd_size */ 0,
4346 /* sense_len */ SSD_FULL_SIZE,
4347 /* timeout */ timeout ? timeout : 5000);
4349 if (arglist & CAM_ARG_ERR_RECOVER)
4350 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4352 /* Disable freezing the device queue */
4353 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4355 if (((retval = cam_send_ccb(device, ccb)) < 0)
4356 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4357 if (arglist & CAM_ARG_VERBOSE) {
4358 cam_error_print(device, ccb, CAM_ESF_ALL,
4359 CAM_EPF_ALL, stderr);
4362 cam_close_device(device);
4364 err(1, "error sending mode sense command");
4366 errx(1, "error sending mode sense command");
4373 mode_select(struct cam_device *device, int save_pages, int task_attr,
4374 int retry_count, int timeout, u_int8_t *data, int datalen)
4379 ccb = cam_getccb(device);
4382 errx(1, "mode_select: couldn't allocate CCB");
4384 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4386 scsi_mode_select(&ccb->csio,
4387 /* retries */ retry_count,
4389 /* tag_action */ task_attr,
4390 /* scsi_page_fmt */ 1,
4391 /* save_pages */ save_pages,
4392 /* param_buf */ data,
4393 /* param_len */ datalen,
4394 /* sense_len */ SSD_FULL_SIZE,
4395 /* timeout */ timeout ? timeout : 5000);
4397 if (arglist & CAM_ARG_ERR_RECOVER)
4398 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4400 /* Disable freezing the device queue */
4401 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4403 if (((retval = cam_send_ccb(device, ccb)) < 0)
4404 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4405 if (arglist & CAM_ARG_VERBOSE) {
4406 cam_error_print(device, ccb, CAM_ESF_ALL,
4407 CAM_EPF_ALL, stderr);
4410 cam_close_device(device);
4413 err(1, "error sending mode select command");
4415 errx(1, "error sending mode select command");
4423 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4424 int task_attr, int retry_count, int timeout)
4427 int c, page = -1, subpage = -1, pc = 0;
4428 int binary = 0, dbd = 0, edit = 0, list = 0;
4430 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4445 str_subpage = optarg;
4446 strsep(&str_subpage, ",");
4447 page = strtol(optarg, NULL, 0);
4449 subpage = strtol(str_subpage, NULL, 0);
4453 errx(1, "invalid mode page %d", page);
4455 errx(1, "invalid mode subpage %d", subpage);
4458 pc = strtol(optarg, NULL, 0);
4459 if ((pc < 0) || (pc > 3))
4460 errx(1, "invalid page control field %d", pc);
4467 if (page == -1 && list == 0)
4468 errx(1, "you must specify a mode page!");
4471 mode_list(device, dbd, pc, list > 1, task_attr, retry_count,
4474 mode_edit(device, dbd, pc, page, subpage, edit, binary,
4475 task_attr, retry_count, timeout);
4480 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4481 int task_attr, int retry_count, int timeout)
4484 u_int32_t flags = CAM_DIR_NONE;
4485 u_int8_t *data_ptr = NULL;
4487 u_int8_t atacmd[12];
4488 struct get_hook hook;
4489 int c, data_bytes = 0, valid_bytes;
4495 char *datastr = NULL, *tstr, *resstr = NULL;
4497 int fd_data = 0, fd_res = 0;
4500 ccb = cam_getccb(device);
4503 warnx("scsicmd: error allocating ccb");
4507 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4509 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4513 while (isspace(*tstr) && (*tstr != '\0'))
4515 hook.argc = argc - optind;
4516 hook.argv = argv + optind;
4518 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4521 * Increment optind by the number of arguments the
4522 * encoding routine processed. After each call to
4523 * getopt(3), optind points to the argument that
4524 * getopt should process _next_. In this case,
4525 * that means it points to the first command string
4526 * argument, if there is one. Once we increment
4527 * this, it should point to either the next command
4528 * line argument, or it should be past the end of
4535 while (isspace(*tstr) && (*tstr != '\0'))
4537 hook.argc = argc - optind;
4538 hook.argv = argv + optind;
4540 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4543 * Increment optind by the number of arguments the
4544 * encoding routine processed. After each call to
4545 * getopt(3), optind points to the argument that
4546 * getopt should process _next_. In this case,
4547 * that means it points to the first command string
4548 * argument, if there is one. Once we increment
4549 * this, it should point to either the next command
4550 * line argument, or it should be past the end of
4562 if (arglist & CAM_ARG_CMD_OUT) {
4563 warnx("command must either be "
4564 "read or write, not both");
4566 goto scsicmd_bailout;
4568 arglist |= CAM_ARG_CMD_IN;
4570 data_bytes = strtol(optarg, NULL, 0);
4571 if (data_bytes <= 0) {
4572 warnx("invalid number of input bytes %d",
4575 goto scsicmd_bailout;
4577 hook.argc = argc - optind;
4578 hook.argv = argv + optind;
4581 datastr = cget(&hook, NULL);
4583 * If the user supplied "-" instead of a format, he
4584 * wants the data to be written to stdout.
4586 if ((datastr != NULL)
4587 && (datastr[0] == '-'))
4590 data_ptr = (u_int8_t *)malloc(data_bytes);
4591 if (data_ptr == NULL) {
4592 warnx("can't malloc memory for data_ptr");
4594 goto scsicmd_bailout;
4598 if (arglist & CAM_ARG_CMD_IN) {
4599 warnx("command must either be "
4600 "read or write, not both");
4602 goto scsicmd_bailout;
4604 arglist |= CAM_ARG_CMD_OUT;
4605 flags = CAM_DIR_OUT;
4606 data_bytes = strtol(optarg, NULL, 0);
4607 if (data_bytes <= 0) {
4608 warnx("invalid number of output bytes %d",
4611 goto scsicmd_bailout;
4613 hook.argc = argc - optind;
4614 hook.argv = argv + optind;
4616 datastr = cget(&hook, NULL);
4617 data_ptr = (u_int8_t *)malloc(data_bytes);
4618 if (data_ptr == NULL) {
4619 warnx("can't malloc memory for data_ptr");
4621 goto scsicmd_bailout;
4623 bzero(data_ptr, data_bytes);
4625 * If the user supplied "-" instead of a format, he
4626 * wants the data to be read from stdin.
4628 if ((datastr != NULL)
4629 && (datastr[0] == '-'))
4632 buff_encode_visit(data_ptr, data_bytes, datastr,
4638 hook.argc = argc - optind;
4639 hook.argv = argv + optind;
4641 resstr = cget(&hook, NULL);
4642 if ((resstr != NULL) && (resstr[0] == '-'))
4652 * If fd_data is set, and we're writing to the device, we need to
4653 * read the data the user wants written from stdin.
4655 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4657 int amt_to_read = data_bytes;
4658 u_int8_t *buf_ptr = data_ptr;
4660 for (amt_read = 0; amt_to_read > 0;
4661 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4662 if (amt_read == -1) {
4663 warn("error reading data from stdin");
4665 goto scsicmd_bailout;
4667 amt_to_read -= amt_read;
4668 buf_ptr += amt_read;
4672 if (arglist & CAM_ARG_ERR_RECOVER)
4673 flags |= CAM_PASS_ERR_RECOVER;
4675 /* Disable freezing the device queue */
4676 flags |= CAM_DEV_QFRZDIS;
4680 * This is taken from the SCSI-3 draft spec.
4681 * (T10/1157D revision 0.3)
4682 * The top 3 bits of an opcode are the group code.
4683 * The next 5 bits are the command code.
4684 * Group 0: six byte commands
4685 * Group 1: ten byte commands
4686 * Group 2: ten byte commands
4688 * Group 4: sixteen byte commands
4689 * Group 5: twelve byte commands
4690 * Group 6: vendor specific
4691 * Group 7: vendor specific
4693 switch((cdb[0] >> 5) & 0x7) {
4704 /* computed by buff_encode_visit */
4715 * We should probably use csio_build_visit or something like that
4716 * here, but it's easier to encode arguments as you go. The
4717 * alternative would be skipping the CDB argument and then encoding
4718 * it here, since we've got the data buffer argument by now.
4720 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4722 cam_fill_csio(&ccb->csio,
4723 /*retries*/ retry_count,
4726 /*tag_action*/ task_attr,
4727 /*data_ptr*/ data_ptr,
4728 /*dxfer_len*/ data_bytes,
4729 /*sense_len*/ SSD_FULL_SIZE,
4730 /*cdb_len*/ cdb_len,
4731 /*timeout*/ timeout ? timeout : 5000);
4734 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4736 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4738 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4740 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4742 cam_fill_ataio(&ccb->ataio,
4743 /*retries*/ retry_count,
4747 /*data_ptr*/ data_ptr,
4748 /*dxfer_len*/ data_bytes,
4749 /*timeout*/ timeout ? timeout : 5000);
4752 if (((retval = cam_send_ccb(device, ccb)) < 0)
4753 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4754 const char warnstr[] = "error sending command";
4761 if (arglist & CAM_ARG_VERBOSE) {
4762 cam_error_print(device, ccb, CAM_ESF_ALL,
4763 CAM_EPF_ALL, stderr);
4767 goto scsicmd_bailout;
4770 if (atacmd_len && need_res) {
4772 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4774 fprintf(stdout, "\n");
4777 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4778 ccb->ataio.res.status,
4779 ccb->ataio.res.error,
4780 ccb->ataio.res.lba_low,
4781 ccb->ataio.res.lba_mid,
4782 ccb->ataio.res.lba_high,
4783 ccb->ataio.res.device,
4784 ccb->ataio.res.lba_low_exp,
4785 ccb->ataio.res.lba_mid_exp,
4786 ccb->ataio.res.lba_high_exp,
4787 ccb->ataio.res.sector_count,
4788 ccb->ataio.res.sector_count_exp);
4794 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4796 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4797 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4798 && (arglist & CAM_ARG_CMD_IN)
4799 && (valid_bytes > 0)) {
4801 buff_decode_visit(data_ptr, valid_bytes, datastr,
4803 fprintf(stdout, "\n");
4805 ssize_t amt_written;
4806 int amt_to_write = valid_bytes;
4807 u_int8_t *buf_ptr = data_ptr;
4809 for (amt_written = 0; (amt_to_write > 0) &&
4810 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4811 amt_to_write -= amt_written;
4812 buf_ptr += amt_written;
4814 if (amt_written == -1) {
4815 warn("error writing data to stdout");
4817 goto scsicmd_bailout;
4818 } else if ((amt_written == 0)
4819 && (amt_to_write > 0)) {
4820 warnx("only wrote %u bytes out of %u",
4821 valid_bytes - amt_to_write, valid_bytes);
4828 if ((data_bytes > 0) && (data_ptr != NULL))
4837 camdebug(int argc, char **argv, char *combinedopt)
4840 path_id_t bus = CAM_BUS_WILDCARD;
4841 target_id_t target = CAM_TARGET_WILDCARD;
4842 lun_id_t lun = CAM_LUN_WILDCARD;
4843 char *tstr, *tmpstr = NULL;
4847 bzero(&ccb, sizeof(union ccb));
4849 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4852 arglist |= CAM_ARG_DEBUG_INFO;
4853 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4856 arglist |= CAM_ARG_DEBUG_PERIPH;
4857 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4860 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4861 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4864 arglist |= CAM_ARG_DEBUG_TRACE;
4865 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4868 arglist |= CAM_ARG_DEBUG_XPT;
4869 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4872 arglist |= CAM_ARG_DEBUG_CDB;
4873 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4876 arglist |= CAM_ARG_DEBUG_PROBE;
4877 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4884 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4885 warnx("error opening transport layer device %s", XPT_DEVICE);
4886 warn("%s", XPT_DEVICE);
4893 warnx("you must specify \"off\", \"all\" or a bus,");
4894 warnx("bus:target, or bus:target:lun");
4901 while (isspace(*tstr) && (*tstr != '\0'))
4904 if (strncmp(tstr, "off", 3) == 0) {
4905 ccb.cdbg.flags = CAM_DEBUG_NONE;
4906 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4907 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4908 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4909 } else if (strncmp(tstr, "all", 3) != 0) {
4910 tmpstr = (char *)strtok(tstr, ":");
4911 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4912 bus = strtol(tmpstr, NULL, 0);
4913 arglist |= CAM_ARG_BUS;
4914 tmpstr = (char *)strtok(NULL, ":");
4915 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4916 target = strtol(tmpstr, NULL, 0);
4917 arglist |= CAM_ARG_TARGET;
4918 tmpstr = (char *)strtok(NULL, ":");
4919 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4920 lun = strtol(tmpstr, NULL, 0);
4921 arglist |= CAM_ARG_LUN;
4926 warnx("you must specify \"all\", \"off\", or a bus,");
4927 warnx("bus:target, or bus:target:lun to debug");
4933 ccb.ccb_h.func_code = XPT_DEBUG;
4934 ccb.ccb_h.path_id = bus;
4935 ccb.ccb_h.target_id = target;
4936 ccb.ccb_h.target_lun = lun;
4938 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4939 warn("CAMIOCOMMAND ioctl failed");
4944 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4945 CAM_FUNC_NOTAVAIL) {
4946 warnx("CAM debugging not available");
4947 warnx("you need to put options CAMDEBUG in"
4948 " your kernel config file!");
4950 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4952 warnx("XPT_DEBUG CCB failed with status %#x",
4956 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4958 "Debugging turned off\n");
4961 "Debugging enabled for "
4963 bus, target, (uintmax_t)lun);
4974 tagcontrol(struct cam_device *device, int argc, char **argv,
4984 ccb = cam_getccb(device);
4987 warnx("tagcontrol: error allocating ccb");
4991 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4994 numtags = strtol(optarg, NULL, 0);
4996 warnx("tag count %d is < 0", numtags);
4998 goto tagcontrol_bailout;
5009 cam_path_string(device, pathstr, sizeof(pathstr));
5012 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
5013 ccb->ccb_h.func_code = XPT_REL_SIMQ;
5014 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5015 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5016 ccb->crs.openings = numtags;
5019 if (cam_send_ccb(device, ccb) < 0) {
5020 perror("error sending XPT_REL_SIMQ CCB");
5022 goto tagcontrol_bailout;
5025 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5026 warnx("XPT_REL_SIMQ CCB failed");
5027 cam_error_print(device, ccb, CAM_ESF_ALL,
5028 CAM_EPF_ALL, stderr);
5030 goto tagcontrol_bailout;
5035 fprintf(stdout, "%stagged openings now %d\n",
5036 pathstr, ccb->crs.openings);
5039 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5041 ccb->ccb_h.func_code = XPT_GDEV_STATS;
5043 if (cam_send_ccb(device, ccb) < 0) {
5044 perror("error sending XPT_GDEV_STATS CCB");
5046 goto tagcontrol_bailout;
5049 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5050 warnx("XPT_GDEV_STATS CCB failed");
5051 cam_error_print(device, ccb, CAM_ESF_ALL,
5052 CAM_EPF_ALL, stderr);
5054 goto tagcontrol_bailout;
5057 if (arglist & CAM_ARG_VERBOSE) {
5058 fprintf(stdout, "%s", pathstr);
5059 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
5060 fprintf(stdout, "%s", pathstr);
5061 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
5062 fprintf(stdout, "%s", pathstr);
5063 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
5064 fprintf(stdout, "%s", pathstr);
5065 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
5066 fprintf(stdout, "%s", pathstr);
5067 fprintf(stdout, "held %d\n", ccb->cgds.held);
5068 fprintf(stdout, "%s", pathstr);
5069 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
5070 fprintf(stdout, "%s", pathstr);
5071 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
5074 fprintf(stdout, "%s", pathstr);
5075 fprintf(stdout, "device openings: ");
5077 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5078 ccb->cgds.dev_active);
5088 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5092 cam_path_string(device, pathstr, sizeof(pathstr));
5094 if (cts->transport == XPORT_SPI) {
5095 struct ccb_trans_settings_spi *spi =
5096 &cts->xport_specific.spi;
5098 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5100 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5103 if (spi->sync_offset != 0) {
5106 freq = scsi_calc_syncsrate(spi->sync_period);
5107 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5108 pathstr, freq / 1000, freq % 1000);
5112 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5113 fprintf(stdout, "%soffset: %d\n", pathstr,
5117 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5118 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5119 (0x01 << spi->bus_width) * 8);
5122 if (spi->valid & CTS_SPI_VALID_DISC) {
5123 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5124 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5125 "enabled" : "disabled");
5128 if (cts->transport == XPORT_FC) {
5129 struct ccb_trans_settings_fc *fc =
5130 &cts->xport_specific.fc;
5132 if (fc->valid & CTS_FC_VALID_WWNN)
5133 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5134 (long long) fc->wwnn);
5135 if (fc->valid & CTS_FC_VALID_WWPN)
5136 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5137 (long long) fc->wwpn);
5138 if (fc->valid & CTS_FC_VALID_PORT)
5139 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5140 if (fc->valid & CTS_FC_VALID_SPEED)
5141 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5142 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5144 if (cts->transport == XPORT_SAS) {
5145 struct ccb_trans_settings_sas *sas =
5146 &cts->xport_specific.sas;
5148 if (sas->valid & CTS_SAS_VALID_SPEED)
5149 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5150 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5152 if (cts->transport == XPORT_ATA) {
5153 struct ccb_trans_settings_pata *pata =
5154 &cts->xport_specific.ata;
5156 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5157 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5158 ata_mode2string(pata->mode));
5160 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5161 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5164 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5165 fprintf(stdout, "%sPIO transaction length: %d\n",
5166 pathstr, pata->bytecount);
5169 if (cts->transport == XPORT_SATA) {
5170 struct ccb_trans_settings_sata *sata =
5171 &cts->xport_specific.sata;
5173 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5174 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5177 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5178 fprintf(stdout, "%sATA mode: %s\n", pathstr,
5179 ata_mode2string(sata->mode));
5181 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5182 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5185 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5186 fprintf(stdout, "%sPIO transaction length: %d\n",
5187 pathstr, sata->bytecount);
5189 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5190 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5193 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5194 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5197 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5198 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5202 if (cts->protocol == PROTO_ATA) {
5203 struct ccb_trans_settings_ata *ata=
5204 &cts->proto_specific.ata;
5206 if (ata->valid & CTS_ATA_VALID_TQ) {
5207 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5208 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5209 "enabled" : "disabled");
5212 if (cts->protocol == PROTO_SCSI) {
5213 struct ccb_trans_settings_scsi *scsi=
5214 &cts->proto_specific.scsi;
5216 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5217 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5218 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5219 "enabled" : "disabled");
5223 if (cts->protocol == PROTO_NVME) {
5224 struct ccb_trans_settings_nvme *nvmex =
5225 &cts->xport_specific.nvme;
5227 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5228 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5229 NVME_MAJOR(nvmex->spec),
5230 NVME_MINOR(nvmex->spec));
5232 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5233 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5234 nvmex->lanes, nvmex->max_lanes);
5235 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5236 nvmex->speed, nvmex->max_speed);
5243 * Get a path inquiry CCB for the specified device.
5246 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5251 ccb = cam_getccb(device);
5253 warnx("get_cpi: couldn't allocate CCB");
5256 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5257 ccb->ccb_h.func_code = XPT_PATH_INQ;
5258 if (cam_send_ccb(device, ccb) < 0) {
5259 warn("get_cpi: error sending Path Inquiry CCB");
5260 if (arglist & CAM_ARG_VERBOSE)
5261 cam_error_print(device, ccb, CAM_ESF_ALL,
5262 CAM_EPF_ALL, stderr);
5264 goto get_cpi_bailout;
5266 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5267 if (arglist & CAM_ARG_VERBOSE)
5268 cam_error_print(device, ccb, CAM_ESF_ALL,
5269 CAM_EPF_ALL, stderr);
5271 goto get_cpi_bailout;
5273 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5281 * Get a get device CCB for the specified device.
5284 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5289 ccb = cam_getccb(device);
5291 warnx("get_cgd: couldn't allocate CCB");
5294 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5295 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5296 if (cam_send_ccb(device, ccb) < 0) {
5297 warn("get_cgd: error sending Path Inquiry CCB");
5298 if (arglist & CAM_ARG_VERBOSE)
5299 cam_error_print(device, ccb, CAM_ESF_ALL,
5300 CAM_EPF_ALL, stderr);
5302 goto get_cgd_bailout;
5304 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5305 if (arglist & CAM_ARG_VERBOSE)
5306 cam_error_print(device, ccb, CAM_ESF_ALL,
5307 CAM_EPF_ALL, stderr);
5309 goto get_cgd_bailout;
5311 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5319 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5323 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5324 int timeout, int verbosemode)
5326 union ccb *ccb = NULL;
5327 struct scsi_vpd_supported_page_list sup_pages;
5331 ccb = cam_getccb(dev);
5333 warn("Unable to allocate CCB");
5338 /* cam_getccb cleans up the header, caller has to zero the payload */
5339 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5341 bzero(&sup_pages, sizeof(sup_pages));
5343 scsi_inquiry(&ccb->csio,
5344 /*retries*/ retry_count,
5346 /* tag_action */ MSG_SIMPLE_Q_TAG,
5347 /* inq_buf */ (u_int8_t *)&sup_pages,
5348 /* inq_len */ sizeof(sup_pages),
5350 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5351 /* sense_len */ SSD_FULL_SIZE,
5352 /* timeout */ timeout ? timeout : 5000);
5354 /* Disable freezing the device queue */
5355 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5357 if (retry_count != 0)
5358 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5360 if (cam_send_ccb(dev, ccb) < 0) {
5367 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5368 if (verbosemode != 0)
5369 cam_error_print(dev, ccb, CAM_ESF_ALL,
5370 CAM_EPF_ALL, stderr);
5375 for (i = 0; i < sup_pages.length; i++) {
5376 if (sup_pages.list[i] == page_id) {
5389 * devtype is filled in with the type of device.
5390 * Returns 0 for success, non-zero for failure.
5393 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5394 int verbosemode, camcontrol_devtype *devtype)
5396 struct ccb_getdev cgd;
5399 retval = get_cgd(dev, &cgd);
5403 switch (cgd.protocol) {
5409 *devtype = CC_DT_ATA;
5411 break; /*NOTREACHED*/
5413 *devtype = CC_DT_UNKNOWN;
5415 break; /*NOTREACHED*/
5419 * Check for the ATA Information VPD page (0x89). If this is an
5420 * ATA device behind a SCSI to ATA translation layer, this VPD page
5421 * should be present.
5423 * If that VPD page isn't present, or we get an error back from the
5424 * INQUIRY command, we'll just treat it as a normal SCSI device.
5426 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5427 timeout, verbosemode);
5429 *devtype = CC_DT_ATA_BEHIND_SCSI;
5431 *devtype = CC_DT_SCSI;
5440 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5441 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5442 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5443 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5444 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5445 int is48bit, camcontrol_devtype devtype)
5449 if (devtype == CC_DT_ATA) {
5450 cam_fill_ataio(&ccb->ataio,
5451 /*retries*/ retry_count,
5454 /*tag_action*/ tag_action,
5455 /*data_ptr*/ data_ptr,
5456 /*dxfer_len*/ dxfer_len,
5457 /*timeout*/ timeout);
5458 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5459 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5462 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5465 if (auxiliary != 0) {
5466 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5467 ccb->ataio.aux = auxiliary;
5470 if (ata_flags & AP_FLAG_CHK_COND)
5471 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5473 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5474 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5475 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5476 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5478 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5479 protocol |= AP_EXTEND;
5481 retval = scsi_ata_pass(&ccb->csio,
5482 /*retries*/ retry_count,
5485 /*tag_action*/ tag_action,
5486 /*protocol*/ protocol,
5487 /*ata_flags*/ ata_flags,
5488 /*features*/ features,
5489 /*sector_count*/ sector_count,
5491 /*command*/ command,
5494 /*auxiliary*/ auxiliary,
5496 /*data_ptr*/ data_ptr,
5497 /*dxfer_len*/ dxfer_len,
5498 /*cdb_storage*/ cdb_storage,
5499 /*cdb_storage_len*/ cdb_storage_len,
5500 /*minimum_cmd_size*/ 0,
5501 /*sense_len*/ sense_len,
5502 /*timeout*/ timeout);
5509 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5510 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5514 switch (ccb->ccb_h.func_code) {
5517 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5520 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5521 * or 16 byte, and need to see what
5523 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5524 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5526 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5527 if ((opcode != ATA_PASS_12)
5528 && (opcode != ATA_PASS_16)) {
5530 warnx("%s: unsupported opcode %02x", __func__, opcode);
5534 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5536 /* Note: the _ccb() variant returns 0 for an error */
5543 switch (error_code) {
5544 case SSD_DESC_CURRENT_ERROR:
5545 case SSD_DESC_DEFERRED_ERROR: {
5546 struct scsi_sense_data_desc *sense;
5547 struct scsi_sense_ata_ret_desc *desc;
5550 sense = (struct scsi_sense_data_desc *)
5551 &ccb->csio.sense_data;
5553 desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len -
5554 ccb->csio.sense_resid, SSD_DESC_ATA);
5555 if (desc_ptr == NULL) {
5556 cam_error_print(dev, ccb, CAM_ESF_ALL,
5557 CAM_EPF_ALL, stderr);
5561 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5563 *error = desc->error;
5564 *count = (desc->count_15_8 << 8) |
5566 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5567 ((uint64_t)desc->lba_39_32 << 32) |
5568 ((uint64_t)desc->lba_31_24 << 24) |
5569 (desc->lba_23_16 << 16) |
5570 (desc->lba_15_8 << 8) |
5572 *device = desc->device;
5573 *status = desc->status;
5576 * If the extend bit isn't set, the result is for a
5577 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5578 * command without the extend bit set. This means
5579 * that the device is supposed to return 28-bit
5580 * status. The count field is only 8 bits, and the
5581 * LBA field is only 8 bits.
5583 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5589 case SSD_CURRENT_ERROR:
5590 case SSD_DEFERRED_ERROR: {
5592 struct scsi_sense_data_fixed *sense;
5595 * XXX KDM need to support fixed sense data.
5597 warnx("%s: Fixed sense data not supported yet",
5601 break; /*NOTREACHED*/
5612 struct ata_res *res;
5615 * In this case, we have an ATA command, and we need to
5616 * fill in the requested values from the result register
5619 res = &ccb->ataio.res;
5620 *error = res->error;
5621 *status = res->status;
5622 *device = res->device;
5623 *count = res->sector_count;
5624 *lba = (res->lba_high << 16) |
5625 (res->lba_mid << 8) |
5627 if (res->flags & CAM_ATAIO_48BIT) {
5628 *count |= (res->sector_count_exp << 8);
5629 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5630 ((uint64_t)res->lba_mid_exp << 32) |
5631 ((uint64_t)res->lba_high_exp << 40);
5633 *lba |= (res->device & 0xf) << 24;
5646 cpi_print(struct ccb_pathinq *cpi)
5648 char adapter_str[1024];
5651 snprintf(adapter_str, sizeof(adapter_str),
5652 "%s%d:", cpi->dev_name, cpi->unit_number);
5654 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5657 for (i = 1; i < UINT8_MAX; i = i << 1) {
5660 if ((i & cpi->hba_inquiry) == 0)
5663 fprintf(stdout, "%s supports ", adapter_str);
5667 str = "MDP message";
5670 str = "32 bit wide SCSI";
5673 str = "16 bit wide SCSI";
5676 str = "SDTR message";
5679 str = "linked CDBs";
5682 str = "tag queue messages";
5685 str = "soft reset alternative";
5688 str = "SATA Port Multiplier";
5691 str = "unknown PI bit set";
5694 fprintf(stdout, "%s\n", str);
5697 for (i = 1; i < UINT32_MAX; i = i << 1) {
5700 if ((i & cpi->hba_misc) == 0)
5703 fprintf(stdout, "%s ", adapter_str);
5707 str = "can understand ata_ext requests";
5710 str = "64bit extended LUNs supported";
5713 str = "bus scans from high ID to low ID";
5716 str = "removable devices not included in scan";
5718 case PIM_NOINITIATOR:
5719 str = "initiator role not supported";
5721 case PIM_NOBUSRESET:
5722 str = "user has disabled initial BUS RESET or"
5723 " controller is in target/mixed mode";
5726 str = "do not send 6-byte commands";
5729 str = "scan bus sequentially";
5732 str = "unmapped I/O supported";
5735 str = "does its own scanning";
5738 str = "unknown PIM bit set";
5741 fprintf(stdout, "%s\n", str);
5744 for (i = 1; i < UINT16_MAX; i = i << 1) {
5747 if ((i & cpi->target_sprt) == 0)
5750 fprintf(stdout, "%s supports ", adapter_str);
5753 str = "target mode processor mode";
5756 str = "target mode phase cog. mode";
5758 case PIT_DISCONNECT:
5759 str = "disconnects in target mode";
5762 str = "terminate I/O message in target mode";
5765 str = "group 6 commands in target mode";
5768 str = "group 7 commands in target mode";
5771 str = "unknown PIT bit set";
5775 fprintf(stdout, "%s\n", str);
5777 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5779 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5781 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5783 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5784 adapter_str, cpi->hpath_id);
5785 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5787 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5788 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5789 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5790 adapter_str, cpi->hba_vendor);
5791 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5792 adapter_str, cpi->hba_device);
5793 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5794 adapter_str, cpi->hba_subvendor);
5795 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5796 adapter_str, cpi->hba_subdevice);
5797 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5798 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5799 if (cpi->base_transfer_speed > 1000)
5800 fprintf(stdout, "%d.%03dMB/sec\n",
5801 cpi->base_transfer_speed / 1000,
5802 cpi->base_transfer_speed % 1000);
5804 fprintf(stdout, "%dKB/sec\n",
5805 (cpi->base_transfer_speed % 1000) * 1000);
5806 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5807 adapter_str, cpi->maxio);
5811 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5812 struct ccb_trans_settings *cts)
5818 ccb = cam_getccb(device);
5821 warnx("get_print_cts: error allocating ccb");
5825 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5827 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5829 if (user_settings == 0)
5830 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5832 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5834 if (cam_send_ccb(device, ccb) < 0) {
5835 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5836 if (arglist & CAM_ARG_VERBOSE)
5837 cam_error_print(device, ccb, CAM_ESF_ALL,
5838 CAM_EPF_ALL, stderr);
5840 goto get_print_cts_bailout;
5843 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5844 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5845 if (arglist & CAM_ARG_VERBOSE)
5846 cam_error_print(device, ccb, CAM_ESF_ALL,
5847 CAM_EPF_ALL, stderr);
5849 goto get_print_cts_bailout;
5853 cts_print(device, &ccb->cts);
5856 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5858 get_print_cts_bailout:
5866 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
5867 int timeout, int argc, char **argv, char *combinedopt)
5871 int user_settings = 0;
5873 int disc_enable = -1, tag_enable = -1;
5876 double syncrate = -1;
5879 int change_settings = 0, send_tur = 0;
5880 struct ccb_pathinq cpi;
5882 ccb = cam_getccb(device);
5884 warnx("ratecontrol: error allocating ccb");
5887 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5896 if (strncasecmp(optarg, "enable", 6) == 0)
5898 else if (strncasecmp(optarg, "disable", 7) == 0)
5901 warnx("-D argument \"%s\" is unknown", optarg);
5903 goto ratecontrol_bailout;
5905 change_settings = 1;
5908 mode = ata_string2mode(optarg);
5910 warnx("unknown mode '%s'", optarg);
5912 goto ratecontrol_bailout;
5914 change_settings = 1;
5917 offset = strtol(optarg, NULL, 0);
5919 warnx("offset value %d is < 0", offset);
5921 goto ratecontrol_bailout;
5923 change_settings = 1;
5929 syncrate = atof(optarg);
5931 warnx("sync rate %f is < 0", syncrate);
5933 goto ratecontrol_bailout;
5935 change_settings = 1;
5938 if (strncasecmp(optarg, "enable", 6) == 0)
5940 else if (strncasecmp(optarg, "disable", 7) == 0)
5943 warnx("-T argument \"%s\" is unknown", optarg);
5945 goto ratecontrol_bailout;
5947 change_settings = 1;
5953 bus_width = strtol(optarg, NULL, 0);
5954 if (bus_width < 0) {
5955 warnx("bus width %d is < 0", bus_width);
5957 goto ratecontrol_bailout;
5959 change_settings = 1;
5965 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5967 * Grab path inquiry information, so we can determine whether
5968 * or not the initiator is capable of the things that the user
5971 ccb->ccb_h.func_code = XPT_PATH_INQ;
5972 if (cam_send_ccb(device, ccb) < 0) {
5973 perror("error sending XPT_PATH_INQ CCB");
5974 if (arglist & CAM_ARG_VERBOSE) {
5975 cam_error_print(device, ccb, CAM_ESF_ALL,
5976 CAM_EPF_ALL, stderr);
5979 goto ratecontrol_bailout;
5981 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5982 warnx("XPT_PATH_INQ CCB failed");
5983 if (arglist & CAM_ARG_VERBOSE) {
5984 cam_error_print(device, ccb, CAM_ESF_ALL,
5985 CAM_EPF_ALL, stderr);
5988 goto ratecontrol_bailout;
5990 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5991 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5993 fprintf(stdout, "%s parameters:\n",
5994 user_settings ? "User" : "Current");
5996 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5998 goto ratecontrol_bailout;
6000 if (arglist & CAM_ARG_VERBOSE)
6003 if (change_settings) {
6004 int didsettings = 0;
6005 struct ccb_trans_settings_spi *spi = NULL;
6006 struct ccb_trans_settings_pata *pata = NULL;
6007 struct ccb_trans_settings_sata *sata = NULL;
6008 struct ccb_trans_settings_ata *ata = NULL;
6009 struct ccb_trans_settings_scsi *scsi = NULL;
6011 if (ccb->cts.transport == XPORT_SPI)
6012 spi = &ccb->cts.xport_specific.spi;
6013 if (ccb->cts.transport == XPORT_ATA)
6014 pata = &ccb->cts.xport_specific.ata;
6015 if (ccb->cts.transport == XPORT_SATA)
6016 sata = &ccb->cts.xport_specific.sata;
6017 if (ccb->cts.protocol == PROTO_ATA)
6018 ata = &ccb->cts.proto_specific.ata;
6019 if (ccb->cts.protocol == PROTO_SCSI)
6020 scsi = &ccb->cts.proto_specific.scsi;
6021 ccb->cts.xport_specific.valid = 0;
6022 ccb->cts.proto_specific.valid = 0;
6023 if (spi && disc_enable != -1) {
6024 spi->valid |= CTS_SPI_VALID_DISC;
6025 if (disc_enable == 0)
6026 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6028 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6031 if (tag_enable != -1) {
6032 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6033 warnx("HBA does not support tagged queueing, "
6034 "so you cannot modify tag settings");
6036 goto ratecontrol_bailout;
6039 ata->valid |= CTS_SCSI_VALID_TQ;
6040 if (tag_enable == 0)
6041 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6043 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6046 scsi->valid |= CTS_SCSI_VALID_TQ;
6047 if (tag_enable == 0)
6048 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6050 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6054 if (spi && offset != -1) {
6055 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6056 warnx("HBA is not capable of changing offset");
6058 goto ratecontrol_bailout;
6060 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6061 spi->sync_offset = offset;
6064 if (spi && syncrate != -1) {
6065 int prelim_sync_period;
6067 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6068 warnx("HBA is not capable of changing "
6071 goto ratecontrol_bailout;
6073 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6075 * The sync rate the user gives us is in MHz.
6076 * We need to translate it into KHz for this
6081 * Next, we calculate a "preliminary" sync period
6082 * in tenths of a nanosecond.
6085 prelim_sync_period = 0;
6087 prelim_sync_period = 10000000 / syncrate;
6089 scsi_calc_syncparam(prelim_sync_period);
6092 if (sata && syncrate != -1) {
6093 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6094 warnx("HBA is not capable of changing "
6097 goto ratecontrol_bailout;
6099 if (!user_settings) {
6100 warnx("You can modify only user rate "
6101 "settings for SATA");
6103 goto ratecontrol_bailout;
6105 sata->revision = ata_speed2revision(syncrate * 100);
6106 if (sata->revision < 0) {
6107 warnx("Invalid rate %f", syncrate);
6109 goto ratecontrol_bailout;
6111 sata->valid |= CTS_SATA_VALID_REVISION;
6114 if ((pata || sata) && mode != -1) {
6115 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6116 warnx("HBA is not capable of changing "
6119 goto ratecontrol_bailout;
6121 if (!user_settings) {
6122 warnx("You can modify only user mode "
6123 "settings for ATA/SATA");
6125 goto ratecontrol_bailout;
6129 pata->valid |= CTS_ATA_VALID_MODE;
6132 sata->valid |= CTS_SATA_VALID_MODE;
6137 * The bus_width argument goes like this:
6141 * Therefore, if you shift the number of bits given on the
6142 * command line right by 4, you should get the correct
6145 if (spi && bus_width != -1) {
6147 * We might as well validate things here with a
6148 * decipherable error message, rather than what
6149 * will probably be an indecipherable error message
6150 * by the time it gets back to us.
6152 if ((bus_width == 16)
6153 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6154 warnx("HBA does not support 16 bit bus width");
6156 goto ratecontrol_bailout;
6157 } else if ((bus_width == 32)
6158 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6159 warnx("HBA does not support 32 bit bus width");
6161 goto ratecontrol_bailout;
6162 } else if ((bus_width != 8)
6163 && (bus_width != 16)
6164 && (bus_width != 32)) {
6165 warnx("Invalid bus width %d", bus_width);
6167 goto ratecontrol_bailout;
6169 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6170 spi->bus_width = bus_width >> 4;
6173 if (didsettings == 0) {
6174 goto ratecontrol_bailout;
6176 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6177 if (cam_send_ccb(device, ccb) < 0) {
6178 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
6179 if (arglist & CAM_ARG_VERBOSE) {
6180 cam_error_print(device, ccb, CAM_ESF_ALL,
6181 CAM_EPF_ALL, stderr);
6184 goto ratecontrol_bailout;
6186 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6187 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6188 if (arglist & CAM_ARG_VERBOSE) {
6189 cam_error_print(device, ccb, CAM_ESF_ALL,
6190 CAM_EPF_ALL, stderr);
6193 goto ratecontrol_bailout;
6197 retval = testunitready(device, task_attr, retry_count, timeout,
6198 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6200 * If the TUR didn't succeed, just bail.
6204 fprintf(stderr, "Test Unit Ready failed\n");
6205 goto ratecontrol_bailout;
6208 if ((change_settings || send_tur) && !quiet &&
6209 (ccb->cts.transport == XPORT_ATA ||
6210 ccb->cts.transport == XPORT_SATA || send_tur)) {
6211 fprintf(stdout, "New parameters:\n");
6212 retval = get_print_cts(device, user_settings, 0, NULL);
6215 ratecontrol_bailout:
6221 scsiformat(struct cam_device *device, int argc, char **argv,
6222 char *combinedopt, int task_attr, int retry_count, int timeout)
6226 int ycount = 0, quiet = 0;
6227 int error = 0, retval = 0;
6228 int use_timeout = 10800 * 1000;
6230 struct format_defect_list_header fh;
6231 u_int8_t *data_ptr = NULL;
6232 u_int32_t dxfer_len = 0;
6234 int num_warnings = 0;
6237 ccb = cam_getccb(device);
6240 warnx("scsiformat: error allocating ccb");
6244 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6246 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6267 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6268 "following device:\n");
6270 error = scsidoinquiry(device, argc, argv, combinedopt,
6271 task_attr, retry_count, timeout);
6274 warnx("scsiformat: error sending inquiry");
6275 goto scsiformat_bailout;
6280 if (!get_confirmation()) {
6282 goto scsiformat_bailout;
6287 use_timeout = timeout;
6290 fprintf(stdout, "Current format timeout is %d seconds\n",
6291 use_timeout / 1000);
6295 * If the user hasn't disabled questions and didn't specify a
6296 * timeout on the command line, ask them if they want the current
6300 && (timeout == 0)) {
6302 int new_timeout = 0;
6304 fprintf(stdout, "Enter new timeout in seconds or press\n"
6305 "return to keep the current timeout [%d] ",
6306 use_timeout / 1000);
6308 if (fgets(str, sizeof(str), stdin) != NULL) {
6310 new_timeout = atoi(str);
6313 if (new_timeout != 0) {
6314 use_timeout = new_timeout * 1000;
6315 fprintf(stdout, "Using new timeout value %d\n",
6316 use_timeout / 1000);
6321 * Keep this outside the if block below to silence any unused
6322 * variable warnings.
6324 bzero(&fh, sizeof(fh));
6327 * If we're in immediate mode, we've got to include the format
6330 if (immediate != 0) {
6331 fh.byte2 = FU_DLH_IMMED;
6332 data_ptr = (u_int8_t *)&fh;
6333 dxfer_len = sizeof(fh);
6334 byte2 = FU_FMT_DATA;
6335 } else if (quiet == 0) {
6336 fprintf(stdout, "Formatting...");
6340 scsi_format_unit(&ccb->csio,
6341 /* retries */ retry_count,
6343 /* tag_action */ task_attr,
6346 /* data_ptr */ data_ptr,
6347 /* dxfer_len */ dxfer_len,
6348 /* sense_len */ SSD_FULL_SIZE,
6349 /* timeout */ use_timeout);
6351 /* Disable freezing the device queue */
6352 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6354 if (arglist & CAM_ARG_ERR_RECOVER)
6355 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6357 if (((retval = cam_send_ccb(device, ccb)) < 0)
6358 || ((immediate == 0)
6359 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6360 const char errstr[] = "error sending format command";
6367 if (arglist & CAM_ARG_VERBOSE) {
6368 cam_error_print(device, ccb, CAM_ESF_ALL,
6369 CAM_EPF_ALL, stderr);
6372 goto scsiformat_bailout;
6376 * If we ran in non-immediate mode, we already checked for errors
6377 * above and printed out any necessary information. If we're in
6378 * immediate mode, we need to loop through and get status
6379 * information periodically.
6381 if (immediate == 0) {
6383 fprintf(stdout, "Format Complete\n");
6385 goto scsiformat_bailout;
6392 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6395 * There's really no need to do error recovery or
6396 * retries here, since we're just going to sit in a
6397 * loop and wait for the device to finish formatting.
6399 scsi_test_unit_ready(&ccb->csio,
6402 /* tag_action */ task_attr,
6403 /* sense_len */ SSD_FULL_SIZE,
6404 /* timeout */ 5000);
6406 /* Disable freezing the device queue */
6407 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6409 retval = cam_send_ccb(device, ccb);
6412 * If we get an error from the ioctl, bail out. SCSI
6413 * errors are expected.
6416 warn("error sending CAMIOCOMMAND ioctl");
6417 if (arglist & CAM_ARG_VERBOSE) {
6418 cam_error_print(device, ccb, CAM_ESF_ALL,
6419 CAM_EPF_ALL, stderr);
6422 goto scsiformat_bailout;
6425 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6427 if ((status != CAM_REQ_CMP)
6428 && (status == CAM_SCSI_STATUS_ERROR)
6429 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6430 struct scsi_sense_data *sense;
6431 int error_code, sense_key, asc, ascq;
6433 sense = &ccb->csio.sense_data;
6434 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6435 ccb->csio.sense_resid, &error_code, &sense_key,
6436 &asc, &ascq, /*show_errors*/ 1);
6439 * According to the SCSI-2 and SCSI-3 specs, a
6440 * drive that is in the middle of a format should
6441 * return NOT READY with an ASC of "logical unit
6442 * not ready, format in progress". The sense key
6443 * specific bytes will then be a progress indicator.
6445 if ((sense_key == SSD_KEY_NOT_READY)
6446 && (asc == 0x04) && (ascq == 0x04)) {
6449 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6450 ccb->csio.sense_resid, sks) == 0)
6453 u_int64_t percentage;
6455 val = scsi_2btoul(&sks[1]);
6456 percentage = 10000ull * val;
6459 "\rFormatting: %ju.%02u %% "
6461 (uintmax_t)(percentage /
6463 (unsigned)((percentage /
6467 } else if ((quiet == 0)
6468 && (++num_warnings <= 1)) {
6469 warnx("Unexpected SCSI Sense Key "
6470 "Specific value returned "
6472 scsi_sense_print(device, &ccb->csio,
6474 warnx("Unable to print status "
6475 "information, but format will "
6477 warnx("will exit when format is "
6482 warnx("Unexpected SCSI error during format");
6483 cam_error_print(device, ccb, CAM_ESF_ALL,
6484 CAM_EPF_ALL, stderr);
6486 goto scsiformat_bailout;
6489 } else if (status != CAM_REQ_CMP) {
6490 warnx("Unexpected CAM status %#x", status);
6491 if (arglist & CAM_ARG_VERBOSE)
6492 cam_error_print(device, ccb, CAM_ESF_ALL,
6493 CAM_EPF_ALL, stderr);
6495 goto scsiformat_bailout;
6498 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6501 fprintf(stdout, "\nFormat Complete\n");
6511 scsisanitize(struct cam_device *device, int argc, char **argv,
6512 char *combinedopt, int task_attr, int retry_count, int timeout)
6515 u_int8_t action = 0;
6517 int ycount = 0, quiet = 0;
6518 int error = 0, retval = 0;
6519 int use_timeout = 10800 * 1000;
6525 const char *pattern = NULL;
6526 u_int8_t *data_ptr = NULL;
6527 u_int32_t dxfer_len = 0;
6529 int num_warnings = 0;
6532 ccb = cam_getccb(device);
6535 warnx("scsisanitize: error allocating ccb");
6539 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6541 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6544 if (strcasecmp(optarg, "overwrite") == 0)
6545 action = SSZ_SERVICE_ACTION_OVERWRITE;
6546 else if (strcasecmp(optarg, "block") == 0)
6547 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6548 else if (strcasecmp(optarg, "crypto") == 0)
6549 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6550 else if (strcasecmp(optarg, "exitfailure") == 0)
6551 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6553 warnx("invalid service operation \"%s\"",
6556 goto scsisanitize_bailout;
6560 passes = strtol(optarg, NULL, 0);
6561 if (passes < 1 || passes > 31) {
6562 warnx("invalid passes value %d", passes);
6564 goto scsisanitize_bailout;
6595 warnx("an action is required");
6597 goto scsisanitize_bailout;
6598 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6599 struct scsi_sanitize_parameter_list *pl;
6603 if (pattern == NULL) {
6604 warnx("overwrite action requires -P argument");
6606 goto scsisanitize_bailout;
6608 fd = open(pattern, O_RDONLY);
6610 warn("cannot open pattern file %s", pattern);
6612 goto scsisanitize_bailout;
6614 if (fstat(fd, &sb) < 0) {
6615 warn("cannot stat pattern file %s", pattern);
6617 goto scsisanitize_bailout;
6620 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6621 warnx("pattern file size exceeds maximum value %d",
6622 SSZPL_MAX_PATTERN_LENGTH);
6624 goto scsisanitize_bailout;
6626 dxfer_len = sizeof(*pl) + sz;
6627 data_ptr = calloc(1, dxfer_len);
6628 if (data_ptr == NULL) {
6629 warnx("cannot allocate parameter list buffer");
6631 goto scsisanitize_bailout;
6634 amt = read(fd, data_ptr + sizeof(*pl), sz);
6636 warn("cannot read pattern file");
6638 goto scsisanitize_bailout;
6639 } else if (amt != sz) {
6640 warnx("short pattern file read");
6642 goto scsisanitize_bailout;
6645 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6651 pl->byte1 |= SSZPL_INVERT;
6652 scsi_ulto2b(sz, pl->length);
6658 else if (invert != 0)
6660 else if (pattern != NULL)
6665 warnx("%s argument only valid with overwrite "
6668 goto scsisanitize_bailout;
6673 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6674 "following device:\n");
6676 error = scsidoinquiry(device, argc, argv, combinedopt,
6677 task_attr, retry_count, timeout);
6680 warnx("scsisanitize: error sending inquiry");
6681 goto scsisanitize_bailout;
6686 if (!get_confirmation()) {
6688 goto scsisanitize_bailout;
6693 use_timeout = timeout;
6696 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6697 use_timeout / 1000);
6701 * If the user hasn't disabled questions and didn't specify a
6702 * timeout on the command line, ask them if they want the current
6706 && (timeout == 0)) {
6708 int new_timeout = 0;
6710 fprintf(stdout, "Enter new timeout in seconds or press\n"
6711 "return to keep the current timeout [%d] ",
6712 use_timeout / 1000);
6714 if (fgets(str, sizeof(str), stdin) != NULL) {
6716 new_timeout = atoi(str);
6719 if (new_timeout != 0) {
6720 use_timeout = new_timeout * 1000;
6721 fprintf(stdout, "Using new timeout value %d\n",
6722 use_timeout / 1000);
6728 byte2 |= SSZ_UNRESTRICTED_EXIT;
6732 scsi_sanitize(&ccb->csio,
6733 /* retries */ retry_count,
6735 /* tag_action */ task_attr,
6738 /* data_ptr */ data_ptr,
6739 /* dxfer_len */ dxfer_len,
6740 /* sense_len */ SSD_FULL_SIZE,
6741 /* timeout */ use_timeout);
6743 /* Disable freezing the device queue */
6744 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6746 if (arglist & CAM_ARG_ERR_RECOVER)
6747 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6749 if (cam_send_ccb(device, ccb) < 0) {
6750 warn("error sending sanitize command");
6752 goto scsisanitize_bailout;
6755 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6756 struct scsi_sense_data *sense;
6757 int error_code, sense_key, asc, ascq;
6759 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6760 CAM_SCSI_STATUS_ERROR) {
6761 sense = &ccb->csio.sense_data;
6762 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6763 ccb->csio.sense_resid, &error_code, &sense_key,
6764 &asc, &ascq, /*show_errors*/ 1);
6766 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6767 asc == 0x20 && ascq == 0x00)
6768 warnx("sanitize is not supported by "
6771 warnx("error sanitizing this device");
6773 warnx("error sanitizing this device");
6775 if (arglist & CAM_ARG_VERBOSE) {
6776 cam_error_print(device, ccb, CAM_ESF_ALL,
6777 CAM_EPF_ALL, stderr);
6780 goto scsisanitize_bailout;
6784 * If we ran in non-immediate mode, we already checked for errors
6785 * above and printed out any necessary information. If we're in
6786 * immediate mode, we need to loop through and get status
6787 * information periodically.
6789 if (immediate == 0) {
6791 fprintf(stdout, "Sanitize Complete\n");
6793 goto scsisanitize_bailout;
6800 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6803 * There's really no need to do error recovery or
6804 * retries here, since we're just going to sit in a
6805 * loop and wait for the device to finish sanitizing.
6807 scsi_test_unit_ready(&ccb->csio,
6810 /* tag_action */ task_attr,
6811 /* sense_len */ SSD_FULL_SIZE,
6812 /* timeout */ 5000);
6814 /* Disable freezing the device queue */
6815 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6817 retval = cam_send_ccb(device, ccb);
6820 * If we get an error from the ioctl, bail out. SCSI
6821 * errors are expected.
6824 warn("error sending CAMIOCOMMAND ioctl");
6825 if (arglist & CAM_ARG_VERBOSE) {
6826 cam_error_print(device, ccb, CAM_ESF_ALL,
6827 CAM_EPF_ALL, stderr);
6830 goto scsisanitize_bailout;
6833 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6835 if ((status != CAM_REQ_CMP)
6836 && (status == CAM_SCSI_STATUS_ERROR)
6837 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6838 struct scsi_sense_data *sense;
6839 int error_code, sense_key, asc, ascq;
6841 sense = &ccb->csio.sense_data;
6842 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6843 ccb->csio.sense_resid, &error_code, &sense_key,
6844 &asc, &ascq, /*show_errors*/ 1);
6847 * According to the SCSI-3 spec, a drive that is in the
6848 * middle of a sanitize should return NOT READY with an
6849 * ASC of "logical unit not ready, sanitize in
6850 * progress". The sense key specific bytes will then
6851 * be a progress indicator.
6853 if ((sense_key == SSD_KEY_NOT_READY)
6854 && (asc == 0x04) && (ascq == 0x1b)) {
6857 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6858 ccb->csio.sense_resid, sks) == 0)
6861 u_int64_t percentage;
6863 val = scsi_2btoul(&sks[1]);
6864 percentage = 10000 * val;
6867 "\rSanitizing: %ju.%02u %% "
6869 (uintmax_t)(percentage /
6871 (unsigned)((percentage /
6875 } else if ((quiet == 0)
6876 && (++num_warnings <= 1)) {
6877 warnx("Unexpected SCSI Sense Key "
6878 "Specific value returned "
6879 "during sanitize:");
6880 scsi_sense_print(device, &ccb->csio,
6882 warnx("Unable to print status "
6883 "information, but sanitze will "
6885 warnx("will exit when sanitize is "
6890 warnx("Unexpected SCSI error during sanitize");
6891 cam_error_print(device, ccb, CAM_ESF_ALL,
6892 CAM_EPF_ALL, stderr);
6894 goto scsisanitize_bailout;
6897 } else if (status != CAM_REQ_CMP) {
6898 warnx("Unexpected CAM status %#x", status);
6899 if (arglist & CAM_ARG_VERBOSE)
6900 cam_error_print(device, ccb, CAM_ESF_ALL,
6901 CAM_EPF_ALL, stderr);
6903 goto scsisanitize_bailout;
6905 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6908 fprintf(stdout, "\nSanitize Complete\n");
6910 scsisanitize_bailout:
6913 if (data_ptr != NULL)
6921 scsireportluns(struct cam_device *device, int argc, char **argv,
6922 char *combinedopt, int task_attr, int retry_count, int timeout)
6925 int c, countonly, lunsonly;
6926 struct scsi_report_luns_data *lundata;
6928 uint8_t report_type;
6929 uint32_t list_len, i, j;
6934 report_type = RPL_REPORT_DEFAULT;
6935 ccb = cam_getccb(device);
6938 warnx("%s: error allocating ccb", __func__);
6942 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6947 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6956 if (strcasecmp(optarg, "default") == 0)
6957 report_type = RPL_REPORT_DEFAULT;
6958 else if (strcasecmp(optarg, "wellknown") == 0)
6959 report_type = RPL_REPORT_WELLKNOWN;
6960 else if (strcasecmp(optarg, "all") == 0)
6961 report_type = RPL_REPORT_ALL;
6963 warnx("%s: invalid report type \"%s\"",
6974 if ((countonly != 0)
6975 && (lunsonly != 0)) {
6976 warnx("%s: you can only specify one of -c or -l", __func__);
6981 * According to SPC-4, the allocation length must be at least 16
6982 * bytes -- enough for the header and one LUN.
6984 alloc_len = sizeof(*lundata) + 8;
6988 lundata = malloc(alloc_len);
6990 if (lundata == NULL) {
6991 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6996 scsi_report_luns(&ccb->csio,
6997 /*retries*/ retry_count,
6999 /*tag_action*/ task_attr,
7000 /*select_report*/ report_type,
7001 /*rpl_buf*/ lundata,
7002 /*alloc_len*/ alloc_len,
7003 /*sense_len*/ SSD_FULL_SIZE,
7004 /*timeout*/ timeout ? timeout : 5000);
7006 /* Disable freezing the device queue */
7007 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7009 if (arglist & CAM_ARG_ERR_RECOVER)
7010 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7012 if (cam_send_ccb(device, ccb) < 0) {
7013 warn("error sending REPORT LUNS command");
7015 if (arglist & CAM_ARG_VERBOSE)
7016 cam_error_print(device, ccb, CAM_ESF_ALL,
7017 CAM_EPF_ALL, stderr);
7023 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7024 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7030 list_len = scsi_4btoul(lundata->length);
7033 * If we need to list the LUNs, and our allocation
7034 * length was too short, reallocate and retry.
7036 if ((countonly == 0)
7037 && (list_len > (alloc_len - sizeof(*lundata)))) {
7038 alloc_len = list_len + sizeof(*lundata);
7044 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7045 ((list_len / 8) > 1) ? "s" : "");
7050 for (i = 0; i < (list_len / 8); i++) {
7054 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7056 fprintf(stdout, ",");
7057 switch (lundata->luns[i].lundata[j] &
7058 RPL_LUNDATA_ATYP_MASK) {
7059 case RPL_LUNDATA_ATYP_PERIPH:
7060 if ((lundata->luns[i].lundata[j] &
7061 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7062 fprintf(stdout, "%d:",
7063 lundata->luns[i].lundata[j] &
7064 RPL_LUNDATA_PERIPH_BUS_MASK);
7066 && ((lundata->luns[i].lundata[j+2] &
7067 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7070 fprintf(stdout, "%d",
7071 lundata->luns[i].lundata[j+1]);
7073 case RPL_LUNDATA_ATYP_FLAT: {
7075 tmplun[0] = lundata->luns[i].lundata[j] &
7076 RPL_LUNDATA_FLAT_LUN_MASK;
7077 tmplun[1] = lundata->luns[i].lundata[j+1];
7079 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7083 case RPL_LUNDATA_ATYP_LUN:
7084 fprintf(stdout, "%d:%d:%d",
7085 (lundata->luns[i].lundata[j+1] &
7086 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7087 lundata->luns[i].lundata[j] &
7088 RPL_LUNDATA_LUN_TARG_MASK,
7089 lundata->luns[i].lundata[j+1] &
7090 RPL_LUNDATA_LUN_LUN_MASK);
7092 case RPL_LUNDATA_ATYP_EXTLUN: {
7093 int field_len_code, eam_code;
7095 eam_code = lundata->luns[i].lundata[j] &
7096 RPL_LUNDATA_EXT_EAM_MASK;
7097 field_len_code = (lundata->luns[i].lundata[j] &
7098 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7100 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7101 && (field_len_code == 0x00)) {
7102 fprintf(stdout, "%d",
7103 lundata->luns[i].lundata[j+1]);
7104 } else if ((eam_code ==
7105 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7106 && (field_len_code == 0x03)) {
7110 * This format takes up all 8 bytes.
7111 * If we aren't starting at offset 0,
7115 fprintf(stdout, "Invalid "
7118 "specified format", j);
7122 bzero(tmp_lun, sizeof(tmp_lun));
7123 bcopy(&lundata->luns[i].lundata[j+1],
7124 &tmp_lun[1], sizeof(tmp_lun) - 1);
7125 fprintf(stdout, "%#jx",
7126 (intmax_t)scsi_8btou64(tmp_lun));
7129 fprintf(stderr, "Unknown Extended LUN"
7130 "Address method %#x, length "
7131 "code %#x", eam_code,
7138 fprintf(stderr, "Unknown LUN address method "
7139 "%#x\n", lundata->luns[i].lundata[0] &
7140 RPL_LUNDATA_ATYP_MASK);
7144 * For the flat addressing method, there are no
7145 * other levels after it.
7150 fprintf(stdout, "\n");
7163 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7164 char *combinedopt, int task_attr, int retry_count, int timeout)
7167 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7168 struct scsi_read_capacity_data rcap;
7169 struct scsi_read_capacity_data_long rcaplong;
7184 ccb = cam_getccb(device);
7187 warnx("%s: error allocating ccb", __func__);
7191 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7193 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7223 if ((blocksizeonly != 0)
7224 && (numblocks != 0)) {
7225 warnx("%s: you can only specify one of -b or -N", __func__);
7230 if ((blocksizeonly != 0)
7231 && (sizeonly != 0)) {
7232 warnx("%s: you can only specify one of -b or -s", __func__);
7239 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7245 && (blocksizeonly != 0)) {
7246 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7254 scsi_read_capacity(&ccb->csio,
7255 /*retries*/ retry_count,
7257 /*tag_action*/ task_attr,
7260 /*timeout*/ timeout ? timeout : 5000);
7262 /* Disable freezing the device queue */
7263 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7265 if (arglist & CAM_ARG_ERR_RECOVER)
7266 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7268 if (cam_send_ccb(device, ccb) < 0) {
7269 warn("error sending READ CAPACITY command");
7271 if (arglist & CAM_ARG_VERBOSE)
7272 cam_error_print(device, ccb, CAM_ESF_ALL,
7273 CAM_EPF_ALL, stderr);
7279 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7280 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7285 maxsector = scsi_4btoul(rcap.addr);
7286 block_len = scsi_4btoul(rcap.length);
7289 * A last block of 2^32-1 means that the true capacity is over 2TB,
7290 * and we need to issue the long READ CAPACITY to get the real
7291 * capacity. Otherwise, we're all set.
7293 if (maxsector != 0xffffffff)
7297 scsi_read_capacity_16(&ccb->csio,
7298 /*retries*/ retry_count,
7300 /*tag_action*/ task_attr,
7304 /*rcap_buf*/ (uint8_t *)&rcaplong,
7305 /*rcap_buf_len*/ sizeof(rcaplong),
7306 /*sense_len*/ SSD_FULL_SIZE,
7307 /*timeout*/ timeout ? timeout : 5000);
7309 /* Disable freezing the device queue */
7310 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7312 if (arglist & CAM_ARG_ERR_RECOVER)
7313 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7315 if (cam_send_ccb(device, ccb) < 0) {
7316 warn("error sending READ CAPACITY (16) command");
7318 if (arglist & CAM_ARG_VERBOSE)
7319 cam_error_print(device, ccb, CAM_ESF_ALL,
7320 CAM_EPF_ALL, stderr);
7326 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7327 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7332 maxsector = scsi_8btou64(rcaplong.addr);
7333 block_len = scsi_4btoul(rcaplong.length);
7336 if (blocksizeonly == 0) {
7338 * Humanize implies !quiet, and also implies numblocks.
7340 if (humanize != 0) {
7345 tmpbytes = (maxsector + 1) * block_len;
7346 ret = humanize_number(tmpstr, sizeof(tmpstr),
7347 tmpbytes, "", HN_AUTOSCALE,
7350 HN_DIVISOR_1000 : 0));
7352 warnx("%s: humanize_number failed!", __func__);
7356 fprintf(stdout, "Device Size: %s%s", tmpstr,
7357 (sizeonly == 0) ? ", " : "\n");
7358 } else if (numblocks != 0) {
7359 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7360 "Blocks: " : "", (uintmax_t)maxsector + 1,
7361 (sizeonly == 0) ? ", " : "\n");
7363 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7364 "Last Block: " : "", (uintmax_t)maxsector,
7365 (sizeonly == 0) ? ", " : "\n");
7369 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7370 "Block Length: " : "", block_len, (quiet == 0) ?
7379 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7380 int retry_count, int timeout)
7384 uint8_t *smp_request = NULL, *smp_response = NULL;
7385 int request_size = 0, response_size = 0;
7386 int fd_request = 0, fd_response = 0;
7387 char *datastr = NULL;
7388 struct get_hook hook;
7393 * Note that at the moment we don't support sending SMP CCBs to
7394 * devices that aren't probed by CAM.
7396 ccb = cam_getccb(device);
7398 warnx("%s: error allocating CCB", __func__);
7402 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7404 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7407 arglist |= CAM_ARG_CMD_IN;
7408 response_size = strtol(optarg, NULL, 0);
7409 if (response_size <= 0) {
7410 warnx("invalid number of response bytes %d",
7413 goto smpcmd_bailout;
7415 hook.argc = argc - optind;
7416 hook.argv = argv + optind;
7419 datastr = cget(&hook, NULL);
7421 * If the user supplied "-" instead of a format, he
7422 * wants the data to be written to stdout.
7424 if ((datastr != NULL)
7425 && (datastr[0] == '-'))
7428 smp_response = (u_int8_t *)malloc(response_size);
7429 if (smp_response == NULL) {
7430 warn("can't malloc memory for SMP response");
7432 goto smpcmd_bailout;
7436 arglist |= CAM_ARG_CMD_OUT;
7437 request_size = strtol(optarg, NULL, 0);
7438 if (request_size <= 0) {
7439 warnx("invalid number of request bytes %d",
7442 goto smpcmd_bailout;
7444 hook.argc = argc - optind;
7445 hook.argv = argv + optind;
7447 datastr = cget(&hook, NULL);
7448 smp_request = (u_int8_t *)malloc(request_size);
7449 if (smp_request == NULL) {
7450 warn("can't malloc memory for SMP request");
7452 goto smpcmd_bailout;
7454 bzero(smp_request, request_size);
7456 * If the user supplied "-" instead of a format, he
7457 * wants the data to be read from stdin.
7459 if ((datastr != NULL)
7460 && (datastr[0] == '-'))
7463 buff_encode_visit(smp_request, request_size,
7474 * If fd_data is set, and we're writing to the device, we need to
7475 * read the data the user wants written from stdin.
7477 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7479 int amt_to_read = request_size;
7480 u_int8_t *buf_ptr = smp_request;
7482 for (amt_read = 0; amt_to_read > 0;
7483 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7484 if (amt_read == -1) {
7485 warn("error reading data from stdin");
7487 goto smpcmd_bailout;
7489 amt_to_read -= amt_read;
7490 buf_ptr += amt_read;
7494 if (((arglist & CAM_ARG_CMD_IN) == 0)
7495 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7496 warnx("%s: need both the request (-r) and response (-R) "
7497 "arguments", __func__);
7499 goto smpcmd_bailout;
7502 flags |= CAM_DEV_QFRZDIS;
7504 cam_fill_smpio(&ccb->smpio,
7505 /*retries*/ retry_count,
7508 /*smp_request*/ smp_request,
7509 /*smp_request_len*/ request_size,
7510 /*smp_response*/ smp_response,
7511 /*smp_response_len*/ response_size,
7512 /*timeout*/ timeout ? timeout : 5000);
7514 ccb->smpio.flags = SMP_FLAG_NONE;
7516 if (((retval = cam_send_ccb(device, ccb)) < 0)
7517 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7518 const char warnstr[] = "error sending command";
7525 if (arglist & CAM_ARG_VERBOSE) {
7526 cam_error_print(device, ccb, CAM_ESF_ALL,
7527 CAM_EPF_ALL, stderr);
7531 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7532 && (response_size > 0)) {
7533 if (fd_response == 0) {
7534 buff_decode_visit(smp_response, response_size,
7535 datastr, arg_put, NULL);
7536 fprintf(stdout, "\n");
7538 ssize_t amt_written;
7539 int amt_to_write = response_size;
7540 u_int8_t *buf_ptr = smp_response;
7542 for (amt_written = 0; (amt_to_write > 0) &&
7543 (amt_written = write(STDOUT_FILENO, buf_ptr,
7544 amt_to_write)) > 0;){
7545 amt_to_write -= amt_written;
7546 buf_ptr += amt_written;
7548 if (amt_written == -1) {
7549 warn("error writing data to stdout");
7551 goto smpcmd_bailout;
7552 } else if ((amt_written == 0)
7553 && (amt_to_write > 0)) {
7554 warnx("only wrote %u bytes out of %u",
7555 response_size - amt_to_write,
7564 if (smp_request != NULL)
7567 if (smp_response != NULL)
7574 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7575 int retry_count, int timeout)
7579 int32_t mmc_opcode = 0, mmc_arg = 0;
7580 int32_t mmc_flags = -1;
7583 int is_bw_4 = 0, is_bw_1 = 0;
7584 int is_highspeed = 0, is_stdspeed = 0;
7585 int is_info_request = 0;
7587 uint8_t mmc_data_byte = 0;
7589 /* For IO_RW_EXTENDED command */
7590 uint8_t *mmc_data = NULL;
7591 struct mmc_data mmc_d;
7592 int mmc_data_len = 0;
7595 * Note that at the moment we don't support sending SMP CCBs to
7596 * devices that aren't probed by CAM.
7598 ccb = cam_getccb(device);
7600 warnx("%s: error allocating CCB", __func__);
7604 bzero(&(&ccb->ccb_h)[1],
7605 sizeof(union ccb) - sizeof(struct ccb_hdr));
7607 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7616 if (!strcmp(optarg, "high"))
7622 is_info_request = 1;
7625 mmc_opcode = strtol(optarg, NULL, 0);
7626 if (mmc_opcode < 0) {
7627 warnx("invalid MMC opcode %d",
7630 goto mmccmd_bailout;
7634 mmc_arg = strtol(optarg, NULL, 0);
7636 warnx("invalid MMC arg %d",
7639 goto mmccmd_bailout;
7643 mmc_flags = strtol(optarg, NULL, 0);
7644 if (mmc_flags < 0) {
7645 warnx("invalid MMC flags %d",
7648 goto mmccmd_bailout;
7652 mmc_data_len = strtol(optarg, NULL, 0);
7653 if (mmc_data_len <= 0) {
7654 warnx("invalid MMC data len %d",
7657 goto mmccmd_bailout;
7664 mmc_data_byte = strtol(optarg, NULL, 0);
7670 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7672 /* If flags are left default, supply the right flags */
7674 switch (mmc_opcode) {
7675 case MMC_GO_IDLE_STATE:
7676 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7678 case IO_SEND_OP_COND:
7679 mmc_flags = MMC_RSP_R4;
7681 case SD_SEND_RELATIVE_ADDR:
7682 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7684 case MMC_SELECT_CARD:
7685 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7686 mmc_arg = mmc_arg << 16;
7688 case SD_IO_RW_DIRECT:
7689 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7690 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7692 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7694 case SD_IO_RW_EXTENDED:
7695 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7696 mmc_arg = SD_IO_RW_ADR(mmc_arg);
7697 int len_arg = mmc_data_len;
7698 if (mmc_data_len == 512)
7702 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7704 // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7707 mmc_flags = MMC_RSP_R1;
7711 // Switch bus width instead of sending IO command
7712 if (is_bw_4 || is_bw_1) {
7713 struct ccb_trans_settings_mmc *cts;
7714 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7715 ccb->ccb_h.flags = 0;
7716 cts = &ccb->cts.proto_specific.mmc;
7717 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7718 cts->ios_valid = MMC_BW;
7719 if (((retval = cam_send_ccb(device, ccb)) < 0)
7720 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7721 warn("Error sending command");
7723 printf("Parameters set OK\n");
7729 // Switch bus speed instead of sending IO command
7730 if (is_stdspeed || is_highspeed) {
7731 struct ccb_trans_settings_mmc *cts;
7732 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7733 ccb->ccb_h.flags = 0;
7734 cts = &ccb->cts.proto_specific.mmc;
7735 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
7736 cts->ios_valid = MMC_BT;
7737 if (((retval = cam_send_ccb(device, ccb)) < 0)
7738 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7739 warn("Error sending command");
7741 printf("Speed set OK (HS: %d)\n", is_highspeed);
7747 // Get information about controller and its settings
7748 if (is_info_request) {
7749 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
7750 ccb->ccb_h.flags = 0;
7751 struct ccb_trans_settings_mmc *cts;
7752 cts = &ccb->cts.proto_specific.mmc;
7753 if (((retval = cam_send_ccb(device, ccb)) < 0)
7754 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7755 warn("Error sending command");
7758 printf("Host controller information\n");
7759 printf("Host OCR: 0x%x\n", cts->host_ocr);
7760 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
7761 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
7762 printf("Supported bus width: ");
7763 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
7765 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
7767 printf("\nCurrent settings:\n");
7768 printf("Bus width: ");
7769 switch (cts->ios.bus_width) {
7780 printf("Freq: %d.%03d MHz%s\n",
7781 cts->ios.clock / 1000000,
7782 (cts->ios.clock / 1000) % 1000,
7783 cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : "");
7787 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
7789 if (mmc_data_len > 0) {
7790 flags |= CAM_DIR_IN;
7791 mmc_data = malloc(mmc_data_len);
7792 memset(mmc_data, 0, mmc_data_len);
7793 memset(&mmc_d, 0, sizeof(mmc_d));
7794 mmc_d.len = mmc_data_len;
7795 mmc_d.data = mmc_data;
7796 mmc_d.flags = MMC_DATA_READ;
7797 } else flags |= CAM_DIR_NONE;
7799 cam_fill_mmcio(&ccb->mmcio,
7800 /*retries*/ retry_count,
7803 /*mmc_opcode*/ mmc_opcode,
7804 /*mmc_arg*/ mmc_arg,
7805 /*mmc_flags*/ mmc_flags,
7806 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
7807 /*timeout*/ timeout ? timeout : 5000);
7809 if (((retval = cam_send_ccb(device, ccb)) < 0)
7810 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7811 const char warnstr[] = "error sending command";
7818 if (arglist & CAM_ARG_VERBOSE) {
7819 cam_error_print(device, ccb, CAM_ESF_ALL,
7820 CAM_EPF_ALL, stderr);
7824 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
7825 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
7826 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
7827 ccb->mmcio.cmd.resp[1],
7828 ccb->mmcio.cmd.resp[2],
7829 ccb->mmcio.cmd.resp[3]);
7831 switch (mmc_opcode) {
7832 case SD_IO_RW_DIRECT:
7833 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
7834 SD_R5_DATA(ccb->mmcio.cmd.resp),
7835 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
7837 case SD_IO_RW_EXTENDED:
7838 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
7839 hexdump(mmc_data, mmc_data_len, NULL, 0);
7841 case SD_SEND_RELATIVE_ADDR:
7842 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
7845 printf("No command-specific decoder for CMD %d\n", mmc_opcode);
7852 if (mmc_data_len > 0 && mmc_data != NULL)
7859 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7860 char *combinedopt, int retry_count, int timeout)
7863 struct smp_report_general_request *request = NULL;
7864 struct smp_report_general_response *response = NULL;
7865 struct sbuf *sb = NULL;
7867 int c, long_response = 0;
7871 * Note that at the moment we don't support sending SMP CCBs to
7872 * devices that aren't probed by CAM.
7874 ccb = cam_getccb(device);
7876 warnx("%s: error allocating CCB", __func__);
7880 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7882 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7891 request = malloc(sizeof(*request));
7892 if (request == NULL) {
7893 warn("%s: unable to allocate %zd bytes", __func__,
7899 response = malloc(sizeof(*response));
7900 if (response == NULL) {
7901 warn("%s: unable to allocate %zd bytes", __func__,
7908 smp_report_general(&ccb->smpio,
7912 /*request_len*/ sizeof(*request),
7913 (uint8_t *)response,
7914 /*response_len*/ sizeof(*response),
7915 /*long_response*/ long_response,
7918 if (((retval = cam_send_ccb(device, ccb)) < 0)
7919 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7920 const char warnstr[] = "error sending command";
7927 if (arglist & CAM_ARG_VERBOSE) {
7928 cam_error_print(device, ccb, CAM_ESF_ALL,
7929 CAM_EPF_ALL, stderr);
7936 * If the device supports the long response bit, try again and see
7937 * if we can get all of the data.
7939 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7940 && (long_response == 0)) {
7941 ccb->ccb_h.status = CAM_REQ_INPROG;
7942 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7948 * XXX KDM detect and decode SMP errors here.
7950 sb = sbuf_new_auto();
7952 warnx("%s: error allocating sbuf", __func__);
7956 smp_report_general_sbuf(response, sizeof(*response), sb);
7958 if (sbuf_finish(sb) != 0) {
7959 warnx("%s: sbuf_finish", __func__);
7963 printf("%s", sbuf_data(sb));
7969 if (request != NULL)
7972 if (response != NULL)
7981 static struct camcontrol_opts phy_ops[] = {
7982 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7983 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7984 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7985 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7986 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7987 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7988 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7989 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7990 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7995 smpphycontrol(struct cam_device *device, int argc, char **argv,
7996 char *combinedopt, int retry_count, int timeout)
7999 struct smp_phy_control_request *request = NULL;
8000 struct smp_phy_control_response *response = NULL;
8001 int long_response = 0;
8004 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
8006 uint64_t attached_dev_name = 0;
8007 int dev_name_set = 0;
8008 uint32_t min_plr = 0, max_plr = 0;
8009 uint32_t pp_timeout_val = 0;
8010 int slumber_partial = 0;
8011 int set_pp_timeout_val = 0;
8015 * Note that at the moment we don't support sending SMP CCBs to
8016 * devices that aren't probed by CAM.
8018 ccb = cam_getccb(device);
8020 warnx("%s: error allocating CCB", __func__);
8024 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8026 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8034 if (strcasecmp(optarg, "enable") == 0)
8036 else if (strcasecmp(optarg, "disable") == 0)
8039 warnx("%s: Invalid argument %s", __func__,
8046 slumber_partial |= enable <<
8047 SMP_PC_SAS_SLUMBER_SHIFT;
8050 slumber_partial |= enable <<
8051 SMP_PC_SAS_PARTIAL_SHIFT;
8054 slumber_partial |= enable <<
8055 SMP_PC_SATA_SLUMBER_SHIFT;
8058 slumber_partial |= enable <<
8059 SMP_PC_SATA_PARTIAL_SHIFT;
8062 warnx("%s: programmer error", __func__);
8065 break; /*NOTREACHED*/
8070 attached_dev_name = (uintmax_t)strtoumax(optarg,
8079 * We don't do extensive checking here, so this
8080 * will continue to work when new speeds come out.
8082 min_plr = strtoul(optarg, NULL, 0);
8084 || (min_plr > 0xf)) {
8085 warnx("%s: invalid link rate %x",
8093 * We don't do extensive checking here, so this
8094 * will continue to work when new speeds come out.
8096 max_plr = strtoul(optarg, NULL, 0);
8098 || (max_plr > 0xf)) {
8099 warnx("%s: invalid link rate %x",
8106 camcontrol_optret optreturn;
8107 cam_argmask argnums;
8110 if (phy_op_set != 0) {
8111 warnx("%s: only one phy operation argument "
8112 "(-o) allowed", __func__);
8120 * Allow the user to specify the phy operation
8121 * numerically, as well as with a name. This will
8122 * future-proof it a bit, so options that are added
8123 * in future specs can be used.
8125 if (isdigit(optarg[0])) {
8126 phy_operation = strtoul(optarg, NULL, 0);
8127 if ((phy_operation == 0)
8128 || (phy_operation > 0xff)) {
8129 warnx("%s: invalid phy operation %#x",
8130 __func__, phy_operation);
8136 optreturn = getoption(phy_ops, optarg, &phy_operation,
8139 if (optreturn == CC_OR_AMBIGUOUS) {
8140 warnx("%s: ambiguous option %s", __func__,
8145 } else if (optreturn == CC_OR_NOT_FOUND) {
8146 warnx("%s: option %s not found", __func__,
8158 pp_timeout_val = strtoul(optarg, NULL, 0);
8159 if (pp_timeout_val > 15) {
8160 warnx("%s: invalid partial pathway timeout "
8161 "value %u, need a value less than 16",
8162 __func__, pp_timeout_val);
8166 set_pp_timeout_val = 1;
8174 warnx("%s: a PHY (-p phy) argument is required",__func__);
8179 if (((dev_name_set != 0)
8180 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8181 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8182 && (dev_name_set == 0))) {
8183 warnx("%s: -d name and -o setdevname arguments both "
8184 "required to set device name", __func__);
8189 request = malloc(sizeof(*request));
8190 if (request == NULL) {
8191 warn("%s: unable to allocate %zd bytes", __func__,
8197 response = malloc(sizeof(*response));
8198 if (response == NULL) {
8199 warn("%s: unable to allocate %zd bytes", __func__,
8205 smp_phy_control(&ccb->smpio,
8210 (uint8_t *)response,
8213 /*expected_exp_change_count*/ 0,
8216 (set_pp_timeout_val != 0) ? 1 : 0,
8224 if (((retval = cam_send_ccb(device, ccb)) < 0)
8225 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8226 const char warnstr[] = "error sending command";
8233 if (arglist & CAM_ARG_VERBOSE) {
8235 * Use CAM_EPF_NORMAL so we only get one line of
8236 * SMP command decoding.
8238 cam_error_print(device, ccb, CAM_ESF_ALL,
8239 CAM_EPF_NORMAL, stderr);
8245 /* XXX KDM print out something here for success? */
8250 if (request != NULL)
8253 if (response != NULL)
8260 smpmaninfo(struct cam_device *device, int argc, char **argv,
8261 char *combinedopt, int retry_count, int timeout)
8264 struct smp_report_manuf_info_request request;
8265 struct smp_report_manuf_info_response response;
8266 struct sbuf *sb = NULL;
8267 int long_response = 0;
8272 * Note that at the moment we don't support sending SMP CCBs to
8273 * devices that aren't probed by CAM.
8275 ccb = cam_getccb(device);
8277 warnx("%s: error allocating CCB", __func__);
8281 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8283 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8292 bzero(&request, sizeof(request));
8293 bzero(&response, sizeof(response));
8295 smp_report_manuf_info(&ccb->smpio,
8300 (uint8_t *)&response,
8305 if (((retval = cam_send_ccb(device, ccb)) < 0)
8306 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8307 const char warnstr[] = "error sending command";
8314 if (arglist & CAM_ARG_VERBOSE) {
8315 cam_error_print(device, ccb, CAM_ESF_ALL,
8316 CAM_EPF_ALL, stderr);
8322 sb = sbuf_new_auto();
8324 warnx("%s: error allocating sbuf", __func__);
8328 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8330 if (sbuf_finish(sb) != 0) {
8331 warnx("%s: sbuf_finish", __func__);
8335 printf("%s", sbuf_data(sb));
8349 getdevid(struct cam_devitem *item)
8352 union ccb *ccb = NULL;
8354 struct cam_device *dev;
8356 dev = cam_open_btl(item->dev_match.path_id,
8357 item->dev_match.target_id,
8358 item->dev_match.target_lun, O_RDWR, NULL);
8361 warnx("%s", cam_errbuf);
8366 item->device_id_len = 0;
8368 ccb = cam_getccb(dev);
8370 warnx("%s: error allocating CCB", __func__);
8375 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8378 * On the first try, we just probe for the size of the data, and
8379 * then allocate that much memory and try again.
8382 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8383 ccb->ccb_h.flags = CAM_DIR_IN;
8384 ccb->cdai.flags = CDAI_FLAG_NONE;
8385 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8386 ccb->cdai.bufsiz = item->device_id_len;
8387 if (item->device_id_len != 0)
8388 ccb->cdai.buf = (uint8_t *)item->device_id;
8390 if (cam_send_ccb(dev, ccb) < 0) {
8391 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8396 if (ccb->ccb_h.status != CAM_REQ_CMP) {
8397 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8402 if (item->device_id_len == 0) {
8404 * This is our first time through. Allocate the buffer,
8405 * and then go back to get the data.
8407 if (ccb->cdai.provsiz == 0) {
8408 warnx("%s: invalid .provsiz field returned with "
8409 "XPT_GDEV_ADVINFO CCB", __func__);
8413 item->device_id_len = ccb->cdai.provsiz;
8414 item->device_id = malloc(item->device_id_len);
8415 if (item->device_id == NULL) {
8416 warn("%s: unable to allocate %d bytes", __func__,
8417 item->device_id_len);
8421 ccb->ccb_h.status = CAM_REQ_INPROG;
8427 cam_close_device(dev);
8436 * XXX KDM merge this code with getdevtree()?
8439 buildbusdevlist(struct cam_devlist *devlist)
8442 int bufsize, fd = -1;
8443 struct dev_match_pattern *patterns;
8444 struct cam_devitem *item = NULL;
8445 int skip_device = 0;
8448 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8449 warn("couldn't open %s", XPT_DEVICE);
8453 bzero(&ccb, sizeof(union ccb));
8455 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8456 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8457 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8459 ccb.ccb_h.func_code = XPT_DEV_MATCH;
8460 bufsize = sizeof(struct dev_match_result) * 100;
8461 ccb.cdm.match_buf_len = bufsize;
8462 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8463 if (ccb.cdm.matches == NULL) {
8464 warnx("can't malloc memory for matches");
8468 ccb.cdm.num_matches = 0;
8469 ccb.cdm.num_patterns = 2;
8470 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8471 ccb.cdm.num_patterns;
8473 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8474 if (patterns == NULL) {
8475 warnx("can't malloc memory for patterns");
8480 ccb.cdm.patterns = patterns;
8481 bzero(patterns, ccb.cdm.pattern_buf_len);
8483 patterns[0].type = DEV_MATCH_DEVICE;
8484 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8485 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8486 patterns[1].type = DEV_MATCH_PERIPH;
8487 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8488 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8491 * We do the ioctl multiple times if necessary, in case there are
8492 * more than 100 nodes in the EDT.
8497 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8498 warn("error sending CAMIOCOMMAND ioctl");
8503 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8504 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8505 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8506 warnx("got CAM error %#x, CDM error %d\n",
8507 ccb.ccb_h.status, ccb.cdm.status);
8512 for (i = 0; i < ccb.cdm.num_matches; i++) {
8513 switch (ccb.cdm.matches[i].type) {
8514 case DEV_MATCH_DEVICE: {
8515 struct device_match_result *dev_result;
8518 &ccb.cdm.matches[i].result.device_result;
8520 if (dev_result->flags &
8521 DEV_RESULT_UNCONFIGURED) {
8527 item = malloc(sizeof(*item));
8529 warn("%s: unable to allocate %zd bytes",
8530 __func__, sizeof(*item));
8534 bzero(item, sizeof(*item));
8535 bcopy(dev_result, &item->dev_match,
8536 sizeof(*dev_result));
8537 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8540 if (getdevid(item) != 0) {
8546 case DEV_MATCH_PERIPH: {
8547 struct periph_match_result *periph_result;
8550 &ccb.cdm.matches[i].result.periph_result;
8552 if (skip_device != 0)
8554 item->num_periphs++;
8555 item->periph_matches = realloc(
8556 item->periph_matches,
8558 sizeof(struct periph_match_result));
8559 if (item->periph_matches == NULL) {
8560 warn("%s: error allocating periph "
8565 bcopy(periph_result, &item->periph_matches[
8566 item->num_periphs - 1],
8567 sizeof(*periph_result));
8571 fprintf(stderr, "%s: unexpected match "
8572 "type %d\n", __func__,
8573 ccb.cdm.matches[i].type);
8576 break; /*NOTREACHED*/
8579 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8580 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8588 free(ccb.cdm.matches);
8591 freebusdevlist(devlist);
8597 freebusdevlist(struct cam_devlist *devlist)
8599 struct cam_devitem *item, *item2;
8601 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8602 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8604 free(item->device_id);
8605 free(item->periph_matches);
8610 static struct cam_devitem *
8611 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8613 struct cam_devitem *item;
8615 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8616 struct scsi_vpd_id_descriptor *idd;
8619 * XXX KDM look for LUN IDs as well?
8621 idd = scsi_get_devid(item->device_id,
8622 item->device_id_len,
8623 scsi_devid_is_sas_target);
8627 if (scsi_8btou64(idd->identifier) == sasaddr)
8635 smpphylist(struct cam_device *device, int argc, char **argv,
8636 char *combinedopt, int retry_count, int timeout)
8638 struct smp_report_general_request *rgrequest = NULL;
8639 struct smp_report_general_response *rgresponse = NULL;
8640 struct smp_discover_request *disrequest = NULL;
8641 struct smp_discover_response *disresponse = NULL;
8642 struct cam_devlist devlist;
8644 int long_response = 0;
8651 * Note that at the moment we don't support sending SMP CCBs to
8652 * devices that aren't probed by CAM.
8654 ccb = cam_getccb(device);
8656 warnx("%s: error allocating CCB", __func__);
8660 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8661 STAILQ_INIT(&devlist.dev_queue);
8663 rgrequest = malloc(sizeof(*rgrequest));
8664 if (rgrequest == NULL) {
8665 warn("%s: unable to allocate %zd bytes", __func__,
8666 sizeof(*rgrequest));
8671 rgresponse = malloc(sizeof(*rgresponse));
8672 if (rgresponse == NULL) {
8673 warn("%s: unable to allocate %zd bytes", __func__,
8674 sizeof(*rgresponse));
8679 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8692 smp_report_general(&ccb->smpio,
8696 /*request_len*/ sizeof(*rgrequest),
8697 (uint8_t *)rgresponse,
8698 /*response_len*/ sizeof(*rgresponse),
8699 /*long_response*/ long_response,
8702 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8704 if (((retval = cam_send_ccb(device, ccb)) < 0)
8705 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8706 const char warnstr[] = "error sending command";
8713 if (arglist & CAM_ARG_VERBOSE) {
8714 cam_error_print(device, ccb, CAM_ESF_ALL,
8715 CAM_EPF_ALL, stderr);
8721 num_phys = rgresponse->num_phys;
8723 if (num_phys == 0) {
8725 fprintf(stdout, "%s: No Phys reported\n", __func__);
8730 devlist.path_id = device->path_id;
8732 retval = buildbusdevlist(&devlist);
8737 fprintf(stdout, "%d PHYs:\n", num_phys);
8738 fprintf(stdout, "PHY Attached SAS Address\n");
8741 disrequest = malloc(sizeof(*disrequest));
8742 if (disrequest == NULL) {
8743 warn("%s: unable to allocate %zd bytes", __func__,
8744 sizeof(*disrequest));
8749 disresponse = malloc(sizeof(*disresponse));
8750 if (disresponse == NULL) {
8751 warn("%s: unable to allocate %zd bytes", __func__,
8752 sizeof(*disresponse));
8757 for (i = 0; i < num_phys; i++) {
8758 struct cam_devitem *item;
8759 struct device_match_result *dev_match;
8760 char vendor[16], product[48], revision[16];
8764 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8766 ccb->ccb_h.status = CAM_REQ_INPROG;
8767 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8769 smp_discover(&ccb->smpio,
8773 sizeof(*disrequest),
8774 (uint8_t *)disresponse,
8775 sizeof(*disresponse),
8777 /*ignore_zone_group*/ 0,
8781 if (((retval = cam_send_ccb(device, ccb)) < 0)
8782 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
8783 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
8784 const char warnstr[] = "error sending command";
8791 if (arglist & CAM_ARG_VERBOSE) {
8792 cam_error_print(device, ccb, CAM_ESF_ALL,
8793 CAM_EPF_ALL, stderr);
8799 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
8801 fprintf(stdout, "%3d <vacant>\n", i);
8805 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
8808 item = findsasdevice(&devlist,
8809 scsi_8btou64(disresponse->attached_sas_address));
8813 || (item != NULL)) {
8814 fprintf(stdout, "%3d 0x%016jx", i,
8815 (uintmax_t)scsi_8btou64(
8816 disresponse->attached_sas_address));
8818 fprintf(stdout, "\n");
8821 } else if (quiet != 0)
8824 dev_match = &item->dev_match;
8826 if (dev_match->protocol == PROTO_SCSI) {
8827 cam_strvis(vendor, dev_match->inq_data.vendor,
8828 sizeof(dev_match->inq_data.vendor),
8830 cam_strvis(product, dev_match->inq_data.product,
8831 sizeof(dev_match->inq_data.product),
8833 cam_strvis(revision, dev_match->inq_data.revision,
8834 sizeof(dev_match->inq_data.revision),
8836 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8838 } else if ((dev_match->protocol == PROTO_ATA)
8839 || (dev_match->protocol == PROTO_SATAPM)) {
8840 cam_strvis(product, dev_match->ident_data.model,
8841 sizeof(dev_match->ident_data.model),
8843 cam_strvis(revision, dev_match->ident_data.revision,
8844 sizeof(dev_match->ident_data.revision),
8846 sprintf(tmpstr, "<%s %s>", product, revision);
8848 sprintf(tmpstr, "<>");
8850 fprintf(stdout, " %-33s ", tmpstr);
8853 * If we have 0 periphs, that's a bug...
8855 if (item->num_periphs == 0) {
8856 fprintf(stdout, "\n");
8860 fprintf(stdout, "(");
8861 for (j = 0; j < item->num_periphs; j++) {
8863 fprintf(stdout, ",");
8865 fprintf(stdout, "%s%d",
8866 item->periph_matches[j].periph_name,
8867 item->periph_matches[j].unit_number);
8870 fprintf(stdout, ")\n");
8884 freebusdevlist(&devlist);
8890 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
8892 struct ata_res *res;
8894 res = &ccb->ataio.res;
8895 if (res->status & ATA_STATUS_ERROR) {
8896 if (arglist & CAM_ARG_VERBOSE) {
8897 cam_error_print(device, ccb, CAM_ESF_ALL,
8898 CAM_EPF_ALL, stderr);
8899 printf("error = 0x%02x, sector_count = 0x%04x, "
8900 "device = 0x%02x, status = 0x%02x\n",
8901 res->error, res->sector_count,
8902 res->device, res->status);
8908 if (arglist & CAM_ARG_VERBOSE) {
8909 fprintf(stdout, "%s%d: Raw native check power data:\n",
8910 device->device_name, device->dev_unit_num);
8911 /* res is 4 byte aligned */
8912 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
8914 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
8915 "status = 0x%02x\n", res->error, res->sector_count,
8916 res->device, res->status);
8919 printf("%s%d: ", device->device_name, device->dev_unit_num);
8920 switch (res->sector_count) {
8922 printf("Standby mode\n");
8925 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
8928 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
8931 printf("Idle mode\n");
8934 printf("Active or Idle mode\n");
8937 printf("Unknown mode 0x%02x\n", res->sector_count);
8945 atapm(struct cam_device *device, int argc, char **argv,
8946 char *combinedopt, int retry_count, int timeout)
8952 u_int8_t ata_flags = 0;
8955 ccb = cam_getccb(device);
8958 warnx("%s: error allocating ccb", __func__);
8962 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8971 if (strcmp(argv[1], "idle") == 0) {
8973 cmd = ATA_IDLE_IMMEDIATE;
8976 } else if (strcmp(argv[1], "standby") == 0) {
8978 cmd = ATA_STANDBY_IMMEDIATE;
8980 cmd = ATA_STANDBY_CMD;
8981 } else if (strcmp(argv[1], "powermode") == 0) {
8982 cmd = ATA_CHECK_POWER_MODE;
8983 ata_flags = AP_FLAG_CHK_COND;
8992 else if (t <= (240 * 5))
8994 else if (t <= (252 * 5))
8995 /* special encoding for 21 minutes */
8997 else if (t <= (11 * 30 * 60))
8998 sc = (t - 1) / (30 * 60) + 241;
9002 retval = ata_do_cmd(device,
9004 /*retries*/retry_count,
9005 /*flags*/CAM_DIR_NONE,
9006 /*protocol*/AP_PROTO_NON_DATA,
9007 /*ata_flags*/ata_flags,
9008 /*tag_action*/MSG_SIMPLE_Q_TAG,
9015 /*timeout*/timeout ? timeout : 30 * 1000,
9020 if (retval || cmd != ATA_CHECK_POWER_MODE)
9023 return (atapm_proc_resp(device, ccb));
9027 ataaxm(struct cam_device *device, int argc, char **argv,
9028 char *combinedopt, int retry_count, int timeout)
9036 ccb = cam_getccb(device);
9039 warnx("%s: error allocating ccb", __func__);
9043 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9053 if (strcmp(argv[1], "apm") == 0) {
9069 retval = ata_do_28bit_cmd(device,
9071 /*retries*/retry_count,
9072 /*flags*/CAM_DIR_NONE,
9073 /*protocol*/AP_PROTO_NON_DATA,
9074 /*tag_action*/MSG_SIMPLE_Q_TAG,
9075 /*command*/ATA_SETFEATURES,
9081 /*timeout*/timeout ? timeout : 30 * 1000,
9089 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9090 int show_sa_errors, int sa_set, int service_action,
9091 int timeout_desc, int task_attr, int retry_count, int timeout,
9092 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9094 union ccb *ccb = NULL;
9095 uint8_t *buf = NULL;
9096 uint32_t alloc_len = 0, num_opcodes;
9097 uint32_t valid_len = 0;
9098 uint32_t avail_len = 0;
9099 struct scsi_report_supported_opcodes_all *all_hdr;
9100 struct scsi_report_supported_opcodes_one *one;
9105 * Make it clear that we haven't yet allocated or filled anything.
9110 ccb = cam_getccb(device);
9112 warnx("couldn't allocate CCB");
9117 /* cam_getccb cleans up the header, caller has to zero the payload */
9118 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9120 if (opcode_set != 0) {
9121 options |= RSO_OPTIONS_OC;
9123 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9126 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9127 sizeof(struct scsi_report_supported_opcodes_descr));
9130 if (timeout_desc != 0) {
9131 options |= RSO_RCTD;
9132 alloc_len += num_opcodes *
9133 sizeof(struct scsi_report_supported_opcodes_timeout);
9137 options |= RSO_OPTIONS_OC_SA;
9138 if (show_sa_errors != 0)
9139 options &= ~RSO_OPTIONS_OC;
9148 buf = malloc(alloc_len);
9150 warn("Unable to allocate %u bytes", alloc_len);
9154 bzero(buf, alloc_len);
9156 scsi_report_supported_opcodes(&ccb->csio,
9157 /*retries*/ retry_count,
9159 /*tag_action*/ task_attr,
9160 /*options*/ options,
9161 /*req_opcode*/ opcode,
9162 /*req_service_action*/ service_action,
9164 /*dxfer_len*/ alloc_len,
9165 /*sense_len*/ SSD_FULL_SIZE,
9166 /*timeout*/ timeout ? timeout : 10000);
9168 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9170 if (retry_count != 0)
9171 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9173 if (cam_send_ccb(device, ccb) < 0) {
9174 perror("error sending REPORT SUPPORTED OPERATION CODES");
9179 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9180 if (verbosemode != 0)
9181 cam_error_print(device, ccb, CAM_ESF_ALL,
9182 CAM_EPF_ALL, stderr);
9187 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9189 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9190 && (valid_len >= sizeof(*all_hdr))) {
9191 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9192 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9193 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9194 && (valid_len >= sizeof(*one))) {
9195 uint32_t cdb_length;
9197 one = (struct scsi_report_supported_opcodes_one *)buf;
9198 cdb_length = scsi_2btoul(one->cdb_length);
9199 avail_len = sizeof(*one) + cdb_length;
9200 if (one->support & RSO_ONE_CTDP) {
9201 struct scsi_report_supported_opcodes_timeout *td;
9203 td = (struct scsi_report_supported_opcodes_timeout *)
9205 if (valid_len >= (avail_len + sizeof(td->length))) {
9206 avail_len += scsi_2btoul(td->length) +
9209 avail_len += sizeof(*td);
9215 * avail_len could be zero if we didn't get enough data back from
9216 * thet target to determine
9218 if ((avail_len != 0)
9219 && (avail_len > valid_len)) {
9220 alloc_len = avail_len;
9224 *fill_len = valid_len;
9236 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9237 int req_sa, uint8_t *buf, uint32_t valid_len)
9239 struct scsi_report_supported_opcodes_one *one;
9240 struct scsi_report_supported_opcodes_timeout *td;
9241 uint32_t cdb_len = 0, td_len = 0;
9242 const char *op_desc = NULL;
9246 one = (struct scsi_report_supported_opcodes_one *)buf;
9249 * If we don't have the full single opcode descriptor, no point in
9252 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9254 warnx("Only %u bytes returned, not enough to verify support",
9260 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9262 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9265 printf(", SA 0x%x", req_sa);
9268 switch (one->support & RSO_ONE_SUP_MASK) {
9269 case RSO_ONE_SUP_UNAVAIL:
9270 printf("No command support information currently available\n");
9272 case RSO_ONE_SUP_NOT_SUP:
9273 printf("Command not supported\n");
9276 break; /*NOTREACHED*/
9277 case RSO_ONE_SUP_AVAIL:
9278 printf("Command is supported, complies with a SCSI standard\n");
9280 case RSO_ONE_SUP_VENDOR:
9281 printf("Command is supported, vendor-specific "
9282 "implementation\n");
9285 printf("Unknown command support flags 0x%#x\n",
9286 one->support & RSO_ONE_SUP_MASK);
9291 * If we don't have the CDB length, it isn't exactly an error, the
9292 * command probably isn't supported.
9294 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9298 cdb_len = scsi_2btoul(one->cdb_length);
9301 * If our valid data doesn't include the full reported length,
9302 * return. The caller should have detected this and adjusted his
9303 * allocation length to get all of the available data.
9305 if (valid_len < sizeof(*one) + cdb_len) {
9311 * If all we have is the opcode, there is no point in printing out
9319 printf("CDB usage bitmap:");
9320 for (i = 0; i < cdb_len; i++) {
9321 printf(" %02x", one->cdb_usage[i]);
9326 * If we don't have a timeout descriptor, we're done.
9328 if ((one->support & RSO_ONE_CTDP) == 0)
9332 * If we don't have enough valid length to include the timeout
9333 * descriptor length, we're done.
9335 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9338 td = (struct scsi_report_supported_opcodes_timeout *)
9339 &buf[sizeof(*one) + cdb_len];
9340 td_len = scsi_2btoul(td->length);
9341 td_len += sizeof(td->length);
9344 * If we don't have the full timeout descriptor, we're done.
9346 if (td_len < sizeof(*td))
9350 * If we don't have enough valid length to contain the full timeout
9351 * descriptor, we're done.
9353 if (valid_len < (sizeof(*one) + cdb_len + td_len))
9356 printf("Timeout information:\n");
9357 printf("Command-specific: 0x%02x\n", td->cmd_specific);
9358 printf("Nominal timeout: %u seconds\n",
9359 scsi_4btoul(td->nominal_time));
9360 printf("Recommended timeout: %u seconds\n",
9361 scsi_4btoul(td->recommended_time));
9368 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9371 struct scsi_report_supported_opcodes_all *hdr;
9372 struct scsi_report_supported_opcodes_descr *desc;
9373 uint32_t avail_len = 0, used_len = 0;
9377 if (valid_len < sizeof(*hdr)) {
9378 warnx("%s: not enough returned data (%u bytes) opcode list",
9379 __func__, valid_len);
9383 hdr = (struct scsi_report_supported_opcodes_all *)buf;
9384 avail_len = scsi_4btoul(hdr->length);
9385 avail_len += sizeof(hdr->length);
9387 * Take the lesser of the amount of data the drive claims is
9388 * available, and the amount of data the HBA says was returned.
9390 avail_len = MIN(avail_len, valid_len);
9392 used_len = sizeof(hdr->length);
9394 printf("%-6s %4s %8s ",
9395 "Opcode", "SA", "CDB len" );
9398 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9399 printf(" Description\n");
9401 while ((avail_len - used_len) > sizeof(*desc)) {
9402 struct scsi_report_supported_opcodes_timeout *td;
9404 const char *op_desc = NULL;
9406 cur_ptr = &buf[used_len];
9407 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9409 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9410 if (op_desc == NULL)
9411 op_desc = "UNKNOWN";
9413 printf("0x%02x %#4x %8u ", desc->opcode,
9414 scsi_2btoul(desc->service_action),
9415 scsi_2btoul(desc->cdb_length));
9417 used_len += sizeof(*desc);
9419 if ((desc->flags & RSO_CTDP) == 0) {
9420 printf(" %s\n", op_desc);
9425 * If we don't have enough space to fit a timeout
9426 * descriptor, then we're done.
9428 if (avail_len - used_len < sizeof(*td)) {
9429 used_len = avail_len;
9430 printf(" %s\n", op_desc);
9433 cur_ptr = &buf[used_len];
9434 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9435 td_len = scsi_2btoul(td->length);
9436 td_len += sizeof(td->length);
9440 * If the given timeout descriptor length is less than what
9441 * we understand, skip it.
9443 if (td_len < sizeof(*td)) {
9444 printf(" %s\n", op_desc);
9448 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
9449 scsi_4btoul(td->nominal_time),
9450 scsi_4btoul(td->recommended_time), op_desc);
9457 scsiopcodes(struct cam_device *device, int argc, char **argv,
9458 char *combinedopt, int task_attr, int retry_count, int timeout,
9462 uint32_t opcode = 0, service_action = 0;
9463 int td_set = 0, opcode_set = 0, sa_set = 0;
9464 int show_sa_errors = 1;
9465 uint32_t valid_len = 0;
9466 uint8_t *buf = NULL;
9470 while ((c = getopt(argc, argv, combinedopt)) != -1) {
9476 opcode = strtoul(optarg, &endptr, 0);
9477 if (*endptr != '\0') {
9478 warnx("Invalid opcode \"%s\", must be a number",
9483 if (opcode > 0xff) {
9484 warnx("Invalid opcode 0x%#x, must be between"
9485 "0 and 0xff inclusive", opcode);
9492 service_action = strtoul(optarg, &endptr, 0);
9493 if (*endptr != '\0') {
9494 warnx("Invalid service action \"%s\", must "
9495 "be a number", optarg);
9499 if (service_action > 0xffff) {
9500 warnx("Invalid service action 0x%#x, must "
9501 "be between 0 and 0xffff inclusive",
9516 && (opcode_set == 0)) {
9517 warnx("You must specify an opcode with -o if a service "
9522 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9523 sa_set, service_action, td_set, task_attr,
9524 retry_count, timeout, verbosemode, &valid_len,
9529 if ((opcode_set != 0)
9531 retval = scsiprintoneopcode(device, opcode, sa_set,
9532 service_action, buf, valid_len);
9534 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9543 #endif /* MINIMALISTIC */
9546 scsireprobe(struct cam_device *device)
9551 ccb = cam_getccb(device);
9554 warnx("%s: error allocating ccb", __func__);
9558 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9560 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9562 if (cam_send_ccb(device, ccb) < 0) {
9563 warn("error sending XPT_REPROBE_LUN CCB");
9568 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9569 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9581 usage(int printlong)
9584 fprintf(printlong ? stdout : stderr,
9585 "usage: camcontrol <command> [device id][generic args][command args]\n"
9586 " camcontrol devlist [-b] [-v]\n"
9587 #ifndef MINIMALISTIC
9588 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9589 " camcontrol tur [dev_id][generic args]\n"
9590 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9591 " camcontrol identify [dev_id][generic args] [-v]\n"
9592 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9593 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9595 " camcontrol start [dev_id][generic args]\n"
9596 " camcontrol stop [dev_id][generic args]\n"
9597 " camcontrol load [dev_id][generic args]\n"
9598 " camcontrol eject [dev_id][generic args]\n"
9599 " camcontrol reprobe [dev_id][generic args]\n"
9600 #endif /* MINIMALISTIC */
9601 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9602 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9603 #ifndef MINIMALISTIC
9604 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9605 " [-q][-s][-S offset][-X]\n"
9606 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9607 " [-P pagectl][-e | -b][-d]\n"
9608 " camcontrol cmd [dev_id][generic args]\n"
9609 " <-a cmd [args] | -c cmd [args]>\n"
9610 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9611 " camcontrol smpcmd [dev_id][generic args]\n"
9612 " <-r len fmt [args]> <-R len fmt [args]>\n"
9613 " camcontrol smprg [dev_id][generic args][-l]\n"
9614 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9615 " [-o operation][-d name][-m rate][-M rate]\n"
9616 " [-T pp_timeout][-a enable|disable]\n"
9617 " [-A enable|disable][-s enable|disable]\n"
9618 " [-S enable|disable]\n"
9619 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9620 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9621 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9622 " <all|bus[:target[:lun]]|off>\n"
9623 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9624 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9625 " [-D <enable|disable>][-M mode][-O offset]\n"
9626 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9627 " [-U][-W bus_width]\n"
9628 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9629 " camcontrol sanitize [dev_id][generic args]\n"
9630 " [-a overwrite|block|crypto|exitfailure]\n"
9631 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9633 " camcontrol idle [dev_id][generic args][-t time]\n"
9634 " camcontrol standby [dev_id][generic args][-t time]\n"
9635 " camcontrol sleep [dev_id][generic args]\n"
9636 " camcontrol powermode [dev_id][generic args]\n"
9637 " camcontrol apm [dev_id][generic args][-l level]\n"
9638 " camcontrol aam [dev_id][generic args][-l level]\n"
9639 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9641 " camcontrol security [dev_id][generic args]\n"
9642 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9643 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9644 " [-U <user|master>] [-y]\n"
9645 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9646 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9647 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9648 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9649 " [-s scope][-S][-T type][-U]\n"
9650 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9651 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9652 " [-p part][-s start][-T type][-V vol]\n"
9653 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9655 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9656 " [-o rep_opts] [-P print_opts]\n"
9657 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9658 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9659 " [-S power_src] [-T timer]\n"
9660 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9661 " <-s <-f format -T time | -U >>\n"
9663 #endif /* MINIMALISTIC */
9664 " camcontrol help\n");
9667 #ifndef MINIMALISTIC
9669 "Specify one of the following options:\n"
9670 "devlist list all CAM devices\n"
9671 "periphlist list all CAM peripheral drivers attached to a device\n"
9672 "tur send a test unit ready to the named device\n"
9673 "inquiry send a SCSI inquiry command to the named device\n"
9674 "identify send a ATA identify command to the named device\n"
9675 "reportluns send a SCSI report luns command to the device\n"
9676 "readcap send a SCSI read capacity command to the device\n"
9677 "start send a Start Unit command to the device\n"
9678 "stop send a Stop Unit command to the device\n"
9679 "load send a Start Unit command to the device with the load bit set\n"
9680 "eject send a Stop Unit command to the device with the eject bit set\n"
9681 "reprobe update capacity information of the given device\n"
9682 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9683 "reset reset all buses, the given bus, bus:target:lun or device\n"
9684 "defects read the defect list of the specified device\n"
9685 "modepage display or edit (-e) the given mode page\n"
9686 "cmd send the given SCSI command, may need -i or -o as well\n"
9687 "smpcmd send the given SMP command, requires -o and -i\n"
9688 "smprg send the SMP Report General command\n"
9689 "smppc send the SMP PHY Control command, requires -p\n"
9690 "smpphylist display phys attached to a SAS expander\n"
9691 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9692 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9693 "tags report or set the number of transaction slots for a device\n"
9694 "negotiate report or set device negotiation parameters\n"
9695 "format send the SCSI FORMAT UNIT command to the named device\n"
9696 "sanitize send the SCSI SANITIZE command to the named device\n"
9697 "idle send the ATA IDLE command to the named device\n"
9698 "standby send the ATA STANDBY command to the named device\n"
9699 "sleep send the ATA SLEEP command to the named device\n"
9700 "powermode send the ATA CHECK POWER MODE command to the named device\n"
9701 "fwdownload program firmware of the named device with the given image\n"
9702 "security report or send ATA security commands to the named device\n"
9703 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9704 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9705 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9706 "zone manage Zoned Block (Shingled) devices\n"
9707 "epc send ATA Extended Power Conditions commands\n"
9708 "timestamp report or set the device's timestamp\n"
9709 "help this message\n"
9710 "Device Identifiers:\n"
9711 "bus:target specify the bus and target, lun defaults to 0\n"
9712 "bus:target:lun specify the bus, target and lun\n"
9713 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
9714 "Generic arguments:\n"
9715 "-v be verbose, print out sense information\n"
9716 "-t timeout command timeout in seconds, overrides default timeout\n"
9717 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
9718 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
9719 "-E have the kernel attempt to perform SCSI error recovery\n"
9720 "-C count specify the SCSI command retry count (needs -E to work)\n"
9721 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
9722 "modepage arguments:\n"
9723 "-l list all available mode pages\n"
9724 "-m page specify the mode page to view or edit\n"
9725 "-e edit the specified mode page\n"
9726 "-b force view to binary mode\n"
9727 "-d disable block descriptors for mode sense\n"
9728 "-P pgctl page control field 0-3\n"
9729 "defects arguments:\n"
9730 "-f format specify defect list format (block, bfi or phys)\n"
9731 "-G get the grown defect list\n"
9732 "-P get the permanent defect list\n"
9733 "inquiry arguments:\n"
9734 "-D get the standard inquiry data\n"
9735 "-S get the serial number\n"
9736 "-R get the transfer rate, etc.\n"
9737 "reportluns arguments:\n"
9738 "-c only report a count of available LUNs\n"
9739 "-l only print out luns, and not a count\n"
9740 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
9741 "readcap arguments\n"
9742 "-b only report the blocksize\n"
9743 "-h human readable device size, base 2\n"
9744 "-H human readable device size, base 10\n"
9745 "-N print the number of blocks instead of last block\n"
9746 "-q quiet, print numbers only\n"
9747 "-s only report the last block/device size\n"
9749 "-c cdb [args] specify the SCSI CDB\n"
9750 "-i len fmt specify input data and input data format\n"
9751 "-o len fmt [args] specify output data and output data fmt\n"
9752 "smpcmd arguments:\n"
9753 "-r len fmt [args] specify the SMP command to be sent\n"
9754 "-R len fmt [args] specify SMP response format\n"
9755 "smprg arguments:\n"
9756 "-l specify the long response format\n"
9757 "smppc arguments:\n"
9758 "-p phy specify the PHY to operate on\n"
9759 "-l specify the long request/response format\n"
9760 "-o operation specify the phy control operation\n"
9761 "-d name set the attached device name\n"
9762 "-m rate set the minimum physical link rate\n"
9763 "-M rate set the maximum physical link rate\n"
9764 "-T pp_timeout set the partial pathway timeout value\n"
9765 "-a enable|disable enable or disable SATA slumber\n"
9766 "-A enable|disable enable or disable SATA partial phy power\n"
9767 "-s enable|disable enable or disable SAS slumber\n"
9768 "-S enable|disable enable or disable SAS partial phy power\n"
9769 "smpphylist arguments:\n"
9770 "-l specify the long response format\n"
9771 "-q only print phys with attached devices\n"
9772 "smpmaninfo arguments:\n"
9773 "-l specify the long response format\n"
9774 "debug arguments:\n"
9775 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
9776 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
9777 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
9778 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
9780 "-N tags specify the number of tags to use for this device\n"
9781 "-q be quiet, don't report the number of tags\n"
9782 "-v report a number of tag-related parameters\n"
9783 "negotiate arguments:\n"
9784 "-a send a test unit ready after negotiation\n"
9785 "-c report/set current negotiation settings\n"
9786 "-D <arg> \"enable\" or \"disable\" disconnection\n"
9787 "-M mode set ATA mode\n"
9788 "-O offset set command delay offset\n"
9789 "-q be quiet, don't report anything\n"
9790 "-R syncrate synchronization rate in MHz\n"
9791 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
9792 "-U report/set user negotiation settings\n"
9793 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
9794 "-v also print a Path Inquiry CCB for the controller\n"
9795 "format arguments:\n"
9796 "-q be quiet, don't print status messages\n"
9797 "-r run in report only mode\n"
9798 "-w don't send immediate format command\n"
9799 "-y don't ask any questions\n"
9800 "sanitize arguments:\n"
9801 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
9802 "-c passes overwrite passes to perform (1 to 31)\n"
9803 "-I invert overwrite pattern after each pass\n"
9804 "-P pattern path to overwrite pattern file\n"
9805 "-q be quiet, don't print status messages\n"
9806 "-r run in report only mode\n"
9807 "-U run operation in unrestricted completion exit mode\n"
9808 "-w don't send immediate sanitize command\n"
9809 "-y don't ask any questions\n"
9810 "idle/standby arguments:\n"
9811 "-t <arg> number of seconds before respective state.\n"
9812 "fwdownload arguments:\n"
9813 "-f fw_image path to firmware image file\n"
9814 "-q don't print informational messages, only errors\n"
9815 "-s run in simulation mode\n"
9816 "-v print info for every firmware segment sent to device\n"
9817 "-y don't ask any questions\n"
9818 "security arguments:\n"
9819 "-d pwd disable security using the given password for the selected\n"
9821 "-e pwd erase the device using the given pwd for the selected user\n"
9822 "-f freeze the security configuration of the specified device\n"
9823 "-h pwd enhanced erase the device using the given pwd for the\n"
9825 "-k pwd unlock the device using the given pwd for the selected\n"
9827 "-l <high|maximum> specifies which security level to set: high or maximum\n"
9828 "-q be quiet, do not print any status messages\n"
9829 "-s pwd password the device (enable security) using the given\n"
9830 " pwd for the selected user\n"
9831 "-T timeout overrides the timeout (seconds) used for erase operation\n"
9832 "-U <user|master> specifies which user to set: user or master\n"
9833 "-y don't ask any questions\n"
9835 "-f freeze the HPA configuration of the device\n"
9836 "-l lock the HPA configuration of the device\n"
9837 "-P make the HPA max sectors persist\n"
9838 "-p pwd Set the HPA configuration password required for unlock\n"
9840 "-q be quiet, do not print any status messages\n"
9841 "-s sectors configures the maximum user accessible sectors of the\n"
9843 "-U pwd unlock the HPA configuration of the device\n"
9844 "-y don't ask any questions\n"
9845 "persist arguments:\n"
9846 "-i action specify read_keys, read_reservation, report_cap, or\n"
9847 " read_full_status\n"
9848 "-o action specify register, register_ignore, reserve, release,\n"
9849 " clear, preempt, preempt_abort, register_move, replace_lost\n"
9850 "-a set the All Target Ports (ALL_TG_PT) bit\n"
9851 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
9852 "-k key specify the Reservation Key\n"
9853 "-K sa_key specify the Service Action Reservation Key\n"
9854 "-p set the Activate Persist Through Power Loss bit\n"
9855 "-R rtp specify the Relative Target Port\n"
9856 "-s scope specify the scope: lun, extent, element or a number\n"
9857 "-S specify Transport ID for register, requires -I\n"
9858 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
9859 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
9860 "-U unregister the current initiator for register_move\n"
9861 "attrib arguments:\n"
9862 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
9864 "-w attr specify an attribute to write, one -w argument per attr\n"
9865 "-a attr_num only display this attribute number\n"
9866 "-c get cached attributes\n"
9867 "-e elem_addr request attributes for the given element in a changer\n"
9868 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
9869 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
9870 " field_none, field_desc, field_num, field_size, field_rw\n"
9871 "-p partition request attributes for the given partition\n"
9872 "-s start_attr request attributes starting at the given number\n"
9873 "-T elem_type specify the element type (used with -e)\n"
9874 "-V logical_vol specify the logical volume ID\n"
9875 "opcodes arguments:\n"
9876 "-o opcode specify the individual opcode to list\n"
9877 "-s service_action specify the service action for the opcode\n"
9878 "-N do not return SCSI error for unsupported SA\n"
9879 "-T request nominal and recommended timeout values\n"
9881 "-c cmd required: rz, open, close, finish, or rwp\n"
9882 "-a apply the action to all zones\n"
9883 "-l LBA specify the zone starting LBA\n"
9884 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
9885 " closed, full, ro, offline, reset, nonseq, nonwp\n"
9886 "-P print_opt report zones printing: normal, summary, script\n"
9888 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
9889 " source, status, list\n"
9890 "-d disable power mode (timer, state)\n"
9891 "-D delayed entry (goto)\n"
9892 "-e enable power mode (timer, state)\n"
9893 "-H hold power mode (goto)\n"
9894 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
9896 "-P only display power mode (status)\n"
9897 "-r rst_src restore settings from: default, saved (restore)\n"
9898 "-s save mode (timer, state, restore)\n"
9899 "-S power_src set power source: battery, nonbattery (source)\n"
9900 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
9901 "timestamp arguments:\n"
9902 "-r report the timestamp of the device\n"
9903 "-f format report the timestamp of the device with the given\n"
9904 " strftime(3) format string\n"
9905 "-m report the timestamp of the device as milliseconds since\n"
9906 " January 1st, 1970\n"
9907 "-U report the time with UTC instead of the local time zone\n"
9908 "-s set the timestamp of the device\n"
9909 "-f format the format of the time string passed into strptime(3)\n"
9910 "-T time the time value passed into strptime(3)\n"
9911 "-U set the timestamp of the device to UTC time\n"
9913 #endif /* MINIMALISTIC */
9917 main(int argc, char **argv)
9920 char *device = NULL;
9922 struct cam_device *cam_dev = NULL;
9923 int timeout = 0, retry_count = 1;
9924 camcontrol_optret optreturn;
9926 const char *mainopt = "C:En:Q:t:u:v";
9927 const char *subopt = NULL;
9928 char combinedopt[256];
9929 int error = 0, optstart = 2;
9930 int task_attr = MSG_SIMPLE_Q_TAG;
9932 #ifndef MINIMALISTIC
9936 #endif /* MINIMALISTIC */
9938 cmdlist = CAM_CMD_NONE;
9939 arglist = CAM_ARG_NONE;
9947 * Get the base option.
9949 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
9951 if (optreturn == CC_OR_AMBIGUOUS) {
9952 warnx("ambiguous option %s", argv[1]);
9955 } else if (optreturn == CC_OR_NOT_FOUND) {
9956 warnx("option %s not found", argv[1]);
9962 * Ahh, getopt(3) is a pain.
9964 * This is a gross hack. There really aren't many other good
9965 * options (excuse the pun) for parsing options in a situation like
9966 * this. getopt is kinda braindead, so you end up having to run
9967 * through the options twice, and give each invocation of getopt
9968 * the option string for the other invocation.
9970 * You would think that you could just have two groups of options.
9971 * The first group would get parsed by the first invocation of
9972 * getopt, and the second group would get parsed by the second
9973 * invocation of getopt. It doesn't quite work out that way. When
9974 * the first invocation of getopt finishes, it leaves optind pointing
9975 * to the argument _after_ the first argument in the second group.
9976 * So when the second invocation of getopt comes around, it doesn't
9977 * recognize the first argument it gets and then bails out.
9979 * A nice alternative would be to have a flag for getopt that says
9980 * "just keep parsing arguments even when you encounter an unknown
9981 * argument", but there isn't one. So there's no real clean way to
9982 * easily parse two sets of arguments without having one invocation
9983 * of getopt know about the other.
9985 * Without this hack, the first invocation of getopt would work as
9986 * long as the generic arguments are first, but the second invocation
9987 * (in the subfunction) would fail in one of two ways. In the case
9988 * where you don't set optreset, it would fail because optind may be
9989 * pointing to the argument after the one it should be pointing at.
9990 * In the case where you do set optreset, and reset optind, it would
9991 * fail because getopt would run into the first set of options, which
9992 * it doesn't understand.
9994 * All of this would "sort of" work if you could somehow figure out
9995 * whether optind had been incremented one option too far. The
9996 * mechanics of that, however, are more daunting than just giving
9997 * both invocations all of the expect options for either invocation.
9999 * Needless to say, I wouldn't mind if someone invented a better
10000 * (non-GPL!) command line parsing interface than getopt. I
10001 * wouldn't mind if someone added more knobs to getopt to make it
10002 * work better. Who knows, I may talk myself into doing it someday,
10003 * if the standards weenies let me. As it is, it just leads to
10004 * hackery like this and causes people to avoid it in some cases.
10006 * KDM, September 8th, 1998
10008 if (subopt != NULL)
10009 sprintf(combinedopt, "%s%s", mainopt, subopt);
10011 sprintf(combinedopt, "%s", mainopt);
10014 * For these options we do not parse optional device arguments and
10015 * we do not open a passthrough device.
10017 if ((cmdlist == CAM_CMD_RESCAN)
10018 || (cmdlist == CAM_CMD_RESET)
10019 || (cmdlist == CAM_CMD_DEVTREE)
10020 || (cmdlist == CAM_CMD_USAGE)
10021 || (cmdlist == CAM_CMD_DEBUG))
10024 #ifndef MINIMALISTIC
10026 && (argc > 2 && argv[2][0] != '-')) {
10030 if (isdigit(argv[2][0])) {
10031 /* device specified as bus:target[:lun] */
10032 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10034 errx(1, "numeric device specification must "
10035 "be either bus:target, or "
10037 /* default to 0 if lun was not specified */
10038 if ((arglist & CAM_ARG_LUN) == 0) {
10040 arglist |= CAM_ARG_LUN;
10044 if (cam_get_device(argv[2], name, sizeof name, &unit)
10046 errx(1, "%s", cam_errbuf);
10047 device = strdup(name);
10048 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10052 #endif /* MINIMALISTIC */
10054 * Start getopt processing at argv[2/3], since we've already
10055 * accepted argv[1..2] as the command name, and as a possible
10061 * Now we run through the argument list looking for generic
10062 * options, and ignoring options that possibly belong to
10065 while ((c = getopt(argc, argv, combinedopt))!= -1){
10068 retry_count = strtol(optarg, NULL, 0);
10069 if (retry_count < 0)
10070 errx(1, "retry count %d is < 0",
10072 arglist |= CAM_ARG_RETRIES;
10075 arglist |= CAM_ARG_ERR_RECOVER;
10078 arglist |= CAM_ARG_DEVICE;
10080 while (isspace(*tstr) && (*tstr != '\0'))
10082 device = (char *)strdup(tstr);
10086 int table_entry = 0;
10089 while (isspace(*tstr) && (*tstr != '\0'))
10091 if (isdigit(*tstr)) {
10092 task_attr = strtol(tstr, &endptr, 0);
10093 if (*endptr != '\0') {
10094 errx(1, "Invalid queue option "
10099 scsi_nv_status status;
10101 table_size = sizeof(task_attrs) /
10102 sizeof(task_attrs[0]);
10103 status = scsi_get_nv(task_attrs,
10104 table_size, tstr, &table_entry,
10105 SCSI_NV_FLAG_IG_CASE);
10106 if (status == SCSI_NV_FOUND)
10107 task_attr = task_attrs[
10108 table_entry].value;
10110 errx(1, "%s option %s",
10111 (status == SCSI_NV_AMBIGUOUS)?
10112 "ambiguous" : "invalid",
10119 timeout = strtol(optarg, NULL, 0);
10121 errx(1, "invalid timeout %d", timeout);
10122 /* Convert the timeout from seconds to ms */
10124 arglist |= CAM_ARG_TIMEOUT;
10127 arglist |= CAM_ARG_UNIT;
10128 unit = strtol(optarg, NULL, 0);
10131 arglist |= CAM_ARG_VERBOSE;
10138 #ifndef MINIMALISTIC
10140 * For most commands we'll want to open the passthrough device
10141 * associated with the specified device. In the case of the rescan
10142 * commands, we don't use a passthrough device at all, just the
10143 * transport layer device.
10145 if (devopen == 1) {
10146 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10147 && (((arglist & CAM_ARG_DEVICE) == 0)
10148 || ((arglist & CAM_ARG_UNIT) == 0))) {
10149 errx(1, "subcommand \"%s\" requires a valid device "
10150 "identifier", argv[1]);
10153 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10154 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10155 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10157 errx(1,"%s", cam_errbuf);
10159 #endif /* MINIMALISTIC */
10162 * Reset optind to 2, and reset getopt, so these routines can parse
10163 * the arguments again.
10169 #ifndef MINIMALISTIC
10170 case CAM_CMD_DEVLIST:
10171 error = getdevlist(cam_dev);
10174 error = atahpa(cam_dev, retry_count, timeout,
10175 argc, argv, combinedopt);
10177 #endif /* MINIMALISTIC */
10178 case CAM_CMD_DEVTREE:
10179 error = getdevtree(argc, argv, combinedopt);
10181 #ifndef MINIMALISTIC
10183 error = testunitready(cam_dev, task_attr, retry_count,
10186 case CAM_CMD_INQUIRY:
10187 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10188 task_attr, retry_count, timeout);
10190 case CAM_CMD_IDENTIFY:
10191 error = identify(cam_dev, retry_count, timeout);
10193 case CAM_CMD_STARTSTOP:
10194 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10195 arglist & CAM_ARG_EJECT, task_attr,
10196 retry_count, timeout);
10198 #endif /* MINIMALISTIC */
10199 case CAM_CMD_RESCAN:
10200 error = dorescan_or_reset(argc, argv, 1);
10202 case CAM_CMD_RESET:
10203 error = dorescan_or_reset(argc, argv, 0);
10205 #ifndef MINIMALISTIC
10206 case CAM_CMD_READ_DEFECTS:
10207 error = readdefects(cam_dev, argc, argv, combinedopt,
10208 task_attr, retry_count, timeout);
10210 case CAM_CMD_MODE_PAGE:
10211 modepage(cam_dev, argc, argv, combinedopt,
10212 task_attr, retry_count, timeout);
10214 case CAM_CMD_SCSI_CMD:
10215 error = scsicmd(cam_dev, argc, argv, combinedopt,
10216 task_attr, retry_count, timeout);
10218 case CAM_CMD_MMCSD_CMD:
10219 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10220 retry_count, timeout);
10222 case CAM_CMD_SMP_CMD:
10223 error = smpcmd(cam_dev, argc, argv, combinedopt,
10224 retry_count, timeout);
10226 case CAM_CMD_SMP_RG:
10227 error = smpreportgeneral(cam_dev, argc, argv,
10228 combinedopt, retry_count,
10231 case CAM_CMD_SMP_PC:
10232 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10233 retry_count, timeout);
10235 case CAM_CMD_SMP_PHYLIST:
10236 error = smpphylist(cam_dev, argc, argv, combinedopt,
10237 retry_count, timeout);
10239 case CAM_CMD_SMP_MANINFO:
10240 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10241 retry_count, timeout);
10243 case CAM_CMD_DEBUG:
10244 error = camdebug(argc, argv, combinedopt);
10247 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10250 error = ratecontrol(cam_dev, task_attr, retry_count,
10251 timeout, argc, argv, combinedopt);
10253 case CAM_CMD_FORMAT:
10254 error = scsiformat(cam_dev, argc, argv,
10255 combinedopt, task_attr, retry_count,
10258 case CAM_CMD_REPORTLUNS:
10259 error = scsireportluns(cam_dev, argc, argv,
10260 combinedopt, task_attr,
10261 retry_count, timeout);
10263 case CAM_CMD_READCAP:
10264 error = scsireadcapacity(cam_dev, argc, argv,
10265 combinedopt, task_attr,
10266 retry_count, timeout);
10269 case CAM_CMD_STANDBY:
10270 case CAM_CMD_SLEEP:
10271 case CAM_CMD_POWER_MODE:
10272 error = atapm(cam_dev, argc, argv,
10273 combinedopt, retry_count, timeout);
10277 error = ataaxm(cam_dev, argc, argv,
10278 combinedopt, retry_count, timeout);
10280 case CAM_CMD_SECURITY:
10281 error = atasecurity(cam_dev, retry_count, timeout,
10282 argc, argv, combinedopt);
10284 case CAM_CMD_DOWNLOAD_FW:
10285 error = fwdownload(cam_dev, argc, argv, combinedopt,
10286 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10289 case CAM_CMD_SANITIZE:
10290 error = scsisanitize(cam_dev, argc, argv,
10291 combinedopt, task_attr,
10292 retry_count, timeout);
10294 case CAM_CMD_PERSIST:
10295 error = scsipersist(cam_dev, argc, argv, combinedopt,
10296 task_attr, retry_count, timeout,
10297 arglist & CAM_ARG_VERBOSE,
10298 arglist & CAM_ARG_ERR_RECOVER);
10300 case CAM_CMD_ATTRIB:
10301 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10302 task_attr, retry_count, timeout,
10303 arglist & CAM_ARG_VERBOSE,
10304 arglist & CAM_ARG_ERR_RECOVER);
10306 case CAM_CMD_OPCODES:
10307 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10308 task_attr, retry_count, timeout,
10309 arglist & CAM_ARG_VERBOSE);
10311 case CAM_CMD_REPROBE:
10312 error = scsireprobe(cam_dev);
10315 error = zone(cam_dev, argc, argv, combinedopt,
10316 task_attr, retry_count, timeout,
10317 arglist & CAM_ARG_VERBOSE);
10320 error = epc(cam_dev, argc, argv, combinedopt,
10321 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10323 case CAM_CMD_TIMESTAMP:
10324 error = timestamp(cam_dev, argc, argv, combinedopt,
10325 task_attr, retry_count, timeout,
10326 arglist & CAM_ARG_VERBOSE);
10328 #endif /* MINIMALISTIC */
10329 case CAM_CMD_USAGE:
10338 if (cam_dev != NULL)
10339 cam_close_device(cam_dev);