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>
64 #include "camcontrol.h"
67 CAM_CMD_NONE = 0x00000000,
68 CAM_CMD_DEVLIST = 0x00000001,
69 CAM_CMD_TUR = 0x00000002,
70 CAM_CMD_INQUIRY = 0x00000003,
71 CAM_CMD_STARTSTOP = 0x00000004,
72 CAM_CMD_RESCAN = 0x00000005,
73 CAM_CMD_READ_DEFECTS = 0x00000006,
74 CAM_CMD_MODE_PAGE = 0x00000007,
75 CAM_CMD_SCSI_CMD = 0x00000008,
76 CAM_CMD_DEVTREE = 0x00000009,
77 CAM_CMD_USAGE = 0x0000000a,
78 CAM_CMD_DEBUG = 0x0000000b,
79 CAM_CMD_RESET = 0x0000000c,
80 CAM_CMD_FORMAT = 0x0000000d,
81 CAM_CMD_TAG = 0x0000000e,
82 CAM_CMD_RATE = 0x0000000f,
83 CAM_CMD_DETACH = 0x00000010,
84 CAM_CMD_REPORTLUNS = 0x00000011,
85 CAM_CMD_READCAP = 0x00000012,
86 CAM_CMD_IDENTIFY = 0x00000013,
87 CAM_CMD_IDLE = 0x00000014,
88 CAM_CMD_STANDBY = 0x00000015,
89 CAM_CMD_SLEEP = 0x00000016,
90 CAM_CMD_SMP_CMD = 0x00000017,
91 CAM_CMD_SMP_RG = 0x00000018,
92 CAM_CMD_SMP_PC = 0x00000019,
93 CAM_CMD_SMP_PHYLIST = 0x0000001a,
94 CAM_CMD_SMP_MANINFO = 0x0000001b,
95 CAM_CMD_DOWNLOAD_FW = 0x0000001c,
96 CAM_CMD_SECURITY = 0x0000001d,
97 CAM_CMD_HPA = 0x0000001e,
98 CAM_CMD_SANITIZE = 0x0000001f,
99 CAM_CMD_PERSIST = 0x00000020,
100 CAM_CMD_APM = 0x00000021,
101 CAM_CMD_AAM = 0x00000022,
102 CAM_CMD_ATTRIB = 0x00000023,
103 CAM_CMD_OPCODES = 0x00000024,
104 CAM_CMD_REPROBE = 0x00000025,
105 CAM_CMD_ZONE = 0x00000026,
106 CAM_CMD_EPC = 0x00000027,
107 CAM_CMD_TIMESTAMP = 0x00000028
111 CAM_ARG_NONE = 0x00000000,
112 CAM_ARG_VERBOSE = 0x00000001,
113 CAM_ARG_DEVICE = 0x00000002,
114 CAM_ARG_BUS = 0x00000004,
115 CAM_ARG_TARGET = 0x00000008,
116 CAM_ARG_LUN = 0x00000010,
117 CAM_ARG_EJECT = 0x00000020,
118 CAM_ARG_UNIT = 0x00000040,
119 CAM_ARG_FORMAT_BLOCK = 0x00000080,
120 CAM_ARG_FORMAT_BFI = 0x00000100,
121 CAM_ARG_FORMAT_PHYS = 0x00000200,
122 CAM_ARG_PLIST = 0x00000400,
123 CAM_ARG_GLIST = 0x00000800,
124 CAM_ARG_GET_SERIAL = 0x00001000,
125 CAM_ARG_GET_STDINQ = 0x00002000,
126 CAM_ARG_GET_XFERRATE = 0x00004000,
127 CAM_ARG_INQ_MASK = 0x00007000,
128 CAM_ARG_TIMEOUT = 0x00020000,
129 CAM_ARG_CMD_IN = 0x00040000,
130 CAM_ARG_CMD_OUT = 0x00080000,
131 CAM_ARG_ERR_RECOVER = 0x00200000,
132 CAM_ARG_RETRIES = 0x00400000,
133 CAM_ARG_START_UNIT = 0x00800000,
134 CAM_ARG_DEBUG_INFO = 0x01000000,
135 CAM_ARG_DEBUG_TRACE = 0x02000000,
136 CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
137 CAM_ARG_DEBUG_CDB = 0x08000000,
138 CAM_ARG_DEBUG_XPT = 0x10000000,
139 CAM_ARG_DEBUG_PERIPH = 0x20000000,
140 CAM_ARG_DEBUG_PROBE = 0x40000000,
143 struct camcontrol_opts {
151 struct ata_res_pass16 {
152 u_int16_t reserved[5];
155 u_int8_t sector_count_exp;
156 u_int8_t sector_count;
157 u_int8_t lba_low_exp;
159 u_int8_t lba_mid_exp;
161 u_int8_t lba_high_exp;
167 struct ata_set_max_pwd
170 u_int8_t password[32];
171 u_int16_t reserved2[239];
174 static struct scsi_nv task_attrs[] = {
175 { "simple", MSG_SIMPLE_Q_TAG },
176 { "head", MSG_HEAD_OF_Q_TAG },
177 { "ordered", MSG_ORDERED_Q_TAG },
178 { "iwr", MSG_IGN_WIDE_RESIDUE },
179 { "aca", MSG_ACA_TASK }
182 static const char scsicmd_opts[] = "a:c:dfi:o:r";
183 static const char readdefect_opts[] = "f:GPqsS:X";
184 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
185 static const char smprg_opts[] = "l";
186 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
187 static const char smpphylist_opts[] = "lq";
191 static struct camcontrol_opts option_table[] = {
193 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
194 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
195 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
196 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
197 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
198 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
199 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
200 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
201 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
202 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
203 #endif /* MINIMALISTIC */
204 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
205 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
207 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
208 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts},
209 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"},
210 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
211 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts},
212 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
213 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts},
214 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
215 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts},
216 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"},
217 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
218 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
219 #endif /* MINIMALISTIC */
220 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
222 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
223 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
224 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
225 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
226 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
227 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
228 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
229 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
230 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
231 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
232 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
233 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"},
234 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"},
235 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"},
236 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
237 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"},
238 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"},
239 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"},
240 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
241 {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
242 {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
243 {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
244 #endif /* MINIMALISTIC */
245 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
246 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
247 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
252 struct device_match_result dev_match;
254 struct periph_match_result *periph_matches;
255 struct scsi_vpd_device_id *device_id;
257 STAILQ_ENTRY(cam_devitem) links;
261 STAILQ_HEAD(, cam_devitem) dev_queue;
265 static cam_cmdmask cmdlist;
266 static cam_argmask arglist;
268 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
269 uint32_t *cmdnum, cam_argmask *argnum,
270 const char **subopt);
272 static int getdevlist(struct cam_device *device);
273 #endif /* MINIMALISTIC */
274 static int getdevtree(int argc, char **argv, char *combinedopt);
276 static int testunitready(struct cam_device *device, int task_attr,
277 int retry_count, int timeout, int quiet);
278 static int scsistart(struct cam_device *device, int startstop, int loadeject,
279 int task_attr, int retry_count, int timeout);
280 static int scsiinquiry(struct cam_device *device, int task_attr,
281 int retry_count, int timeout);
282 static int scsiserial(struct cam_device *device, int task_attr,
283 int retry_count, int timeout);
284 #endif /* MINIMALISTIC */
285 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target,
286 lun_id_t *lun, cam_argmask *arglst);
287 static int dorescan_or_reset(int argc, char **argv, int rescan);
288 static int rescan_or_reset_bus(path_id_t bus, int rescan);
289 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target,
290 lun_id_t lun, int scan);
292 static int readdefects(struct cam_device *device, int argc, char **argv,
293 char *combinedopt, int task_attr, int retry_count,
295 static void modepage(struct cam_device *device, int argc, char **argv,
296 char *combinedopt, int task_attr, int retry_count,
298 static int scsicmd(struct cam_device *device, int argc, char **argv,
299 char *combinedopt, int task_attr, int retry_count,
301 static int smpcmd(struct cam_device *device, int argc, char **argv,
302 char *combinedopt, int retry_count, int timeout);
303 static int smpreportgeneral(struct cam_device *device, int argc, char **argv,
304 char *combinedopt, int retry_count, int timeout);
305 static int smpphycontrol(struct cam_device *device, int argc, char **argv,
306 char *combinedopt, int retry_count, int timeout);
307 static int smpmaninfo(struct cam_device *device, int argc, char **argv,
308 char *combinedopt, int retry_count, int timeout);
309 static int getdevid(struct cam_devitem *item);
310 static int buildbusdevlist(struct cam_devlist *devlist);
311 static void freebusdevlist(struct cam_devlist *devlist);
312 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist,
314 static int smpphylist(struct cam_device *device, int argc, char **argv,
315 char *combinedopt, int retry_count, int timeout);
316 static int tagcontrol(struct cam_device *device, int argc, char **argv,
318 static void cts_print(struct cam_device *device,
319 struct ccb_trans_settings *cts);
320 static void cpi_print(struct ccb_pathinq *cpi);
321 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
322 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd);
323 static int get_print_cts(struct cam_device *device, int user_settings,
324 int quiet, struct ccb_trans_settings *cts);
325 static int ratecontrol(struct cam_device *device, int task_attr,
326 int retry_count, int timeout, int argc, char **argv,
328 static int scsiformat(struct cam_device *device, int argc, char **argv,
329 char *combinedopt, int task_attr, int retry_count,
331 static int scsisanitize(struct cam_device *device, int argc, char **argv,
332 char *combinedopt, int task_attr, int retry_count,
334 static int scsireportluns(struct cam_device *device, int argc, char **argv,
335 char *combinedopt, int task_attr, int retry_count,
337 static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
338 char *combinedopt, int task_attr, int retry_count,
340 static int atapm(struct cam_device *device, int argc, char **argv,
341 char *combinedopt, int retry_count, int timeout);
342 static int atasecurity(struct cam_device *device, int retry_count, int timeout,
343 int argc, char **argv, char *combinedopt);
344 static int atahpa(struct cam_device *device, int retry_count, int timeout,
345 int argc, char **argv, char *combinedopt);
346 static int scsiprintoneopcode(struct cam_device *device, int req_opcode,
347 int sa_set, int req_sa, uint8_t *buf,
349 static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
351 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
352 char *combinedopt, int task_attr, int retry_count,
353 int timeout, int verbose);
354 static int scsireprobe(struct cam_device *device);
356 #endif /* MINIMALISTIC */
358 #define min(a,b) (((a)<(b))?(a):(b))
361 #define max(a,b) (((a)>(b))?(a):(b))
365 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum,
366 cam_argmask *argnum, const char **subopt)
368 struct camcontrol_opts *opts;
371 for (opts = table; (opts != NULL) && (opts->optname != NULL);
373 if (strncmp(opts->optname, arg, strlen(arg)) == 0) {
374 *cmdnum = opts->cmdnum;
375 *argnum = opts->argnum;
376 *subopt = opts->subopt;
377 if (++num_matches > 1)
378 return(CC_OR_AMBIGUOUS);
385 return(CC_OR_NOT_FOUND);
390 getdevlist(struct cam_device *device)
396 ccb = cam_getccb(device);
398 ccb->ccb_h.func_code = XPT_GDEVLIST;
399 ccb->ccb_h.flags = CAM_DIR_NONE;
400 ccb->ccb_h.retry_count = 1;
402 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
403 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
404 if (cam_send_ccb(device, ccb) < 0) {
405 perror("error getting device list");
412 switch (ccb->cgdl.status) {
413 case CAM_GDEVLIST_MORE_DEVS:
414 strcpy(status, "MORE");
416 case CAM_GDEVLIST_LAST_DEVICE:
417 strcpy(status, "LAST");
419 case CAM_GDEVLIST_LIST_CHANGED:
420 strcpy(status, "CHANGED");
422 case CAM_GDEVLIST_ERROR:
423 strcpy(status, "ERROR");
428 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
429 ccb->cgdl.periph_name,
430 ccb->cgdl.unit_number,
431 ccb->cgdl.generation,
436 * If the list has changed, we need to start over from the
439 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
447 #endif /* MINIMALISTIC */
450 getdevtree(int argc, char **argv, char *combinedopt)
461 while ((c = getopt(argc, argv, combinedopt)) != -1) {
464 if ((arglist & CAM_ARG_VERBOSE) == 0)
472 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
473 warn("couldn't open %s", XPT_DEVICE);
477 bzero(&ccb, sizeof(union ccb));
479 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
480 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
481 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
483 ccb.ccb_h.func_code = XPT_DEV_MATCH;
484 bufsize = sizeof(struct dev_match_result) * 100;
485 ccb.cdm.match_buf_len = bufsize;
486 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
487 if (ccb.cdm.matches == NULL) {
488 warnx("can't malloc memory for matches");
492 ccb.cdm.num_matches = 0;
495 * We fetch all nodes, since we display most of them in the default
496 * case, and all in the verbose case.
498 ccb.cdm.num_patterns = 0;
499 ccb.cdm.pattern_buf_len = 0;
502 * We do the ioctl multiple times if necessary, in case there are
503 * more than 100 nodes in the EDT.
506 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
507 warn("error sending CAMIOCOMMAND ioctl");
512 if ((ccb.ccb_h.status != CAM_REQ_CMP)
513 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
514 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
515 warnx("got CAM error %#x, CDM error %d\n",
516 ccb.ccb_h.status, ccb.cdm.status);
521 for (i = 0; i < ccb.cdm.num_matches; i++) {
522 switch (ccb.cdm.matches[i].type) {
523 case DEV_MATCH_BUS: {
524 struct bus_match_result *bus_result;
527 * Only print the bus information if the
528 * user turns on the verbose flag.
530 if ((busonly == 0) &&
531 (arglist & CAM_ARG_VERBOSE) == 0)
535 &ccb.cdm.matches[i].result.bus_result;
538 fprintf(stdout, ")\n");
542 fprintf(stdout, "scbus%d on %s%d bus %d%s\n",
544 bus_result->dev_name,
545 bus_result->unit_number,
547 (busonly ? "" : ":"));
550 case DEV_MATCH_DEVICE: {
551 struct device_match_result *dev_result;
552 char vendor[16], product[48], revision[16];
553 char fw[5], tmpstr[256];
559 &ccb.cdm.matches[i].result.device_result;
561 if ((dev_result->flags
562 & DEV_RESULT_UNCONFIGURED)
563 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
569 if (dev_result->protocol == PROTO_SCSI) {
570 cam_strvis(vendor, dev_result->inq_data.vendor,
571 sizeof(dev_result->inq_data.vendor),
574 dev_result->inq_data.product,
575 sizeof(dev_result->inq_data.product),
578 dev_result->inq_data.revision,
579 sizeof(dev_result->inq_data.revision),
581 sprintf(tmpstr, "<%s %s %s>", vendor, product,
583 } else if (dev_result->protocol == PROTO_ATA ||
584 dev_result->protocol == PROTO_SATAPM) {
586 dev_result->ident_data.model,
587 sizeof(dev_result->ident_data.model),
590 dev_result->ident_data.revision,
591 sizeof(dev_result->ident_data.revision),
593 sprintf(tmpstr, "<%s %s>", product,
595 } else if (dev_result->protocol == PROTO_SEMB) {
596 struct sep_identify_data *sid;
598 sid = (struct sep_identify_data *)
599 &dev_result->ident_data;
600 cam_strvis(vendor, sid->vendor_id,
601 sizeof(sid->vendor_id),
603 cam_strvis(product, sid->product_id,
604 sizeof(sid->product_id),
606 cam_strvis(revision, sid->product_rev,
607 sizeof(sid->product_rev),
609 cam_strvis(fw, sid->firmware_rev,
610 sizeof(sid->firmware_rev),
612 sprintf(tmpstr, "<%s %s %s %s>",
613 vendor, product, revision, fw);
615 sprintf(tmpstr, "<>");
618 fprintf(stdout, ")\n");
622 fprintf(stdout, "%-33s at scbus%d "
623 "target %d lun %jx (",
626 dev_result->target_id,
627 (uintmax_t)dev_result->target_lun);
633 case DEV_MATCH_PERIPH: {
634 struct periph_match_result *periph_result;
637 &ccb.cdm.matches[i].result.periph_result;
639 if (busonly || skip_device != 0)
643 fprintf(stdout, ",");
645 fprintf(stdout, "%s%d",
646 periph_result->periph_name,
647 periph_result->unit_number);
653 fprintf(stdout, "unknown match type\n");
658 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
659 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
662 fprintf(stdout, ")\n");
671 testunitready(struct cam_device *device, int task_attr, int retry_count,
672 int timeout, int quiet)
677 ccb = cam_getccb(device);
679 scsi_test_unit_ready(&ccb->csio,
680 /* retries */ retry_count,
682 /* tag_action */ task_attr,
683 /* sense_len */ SSD_FULL_SIZE,
684 /* timeout */ timeout ? timeout : 5000);
686 /* Disable freezing the device queue */
687 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
689 if (arglist & CAM_ARG_ERR_RECOVER)
690 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
692 if (cam_send_ccb(device, ccb) < 0) {
694 perror("error sending test unit ready");
696 if (arglist & CAM_ARG_VERBOSE) {
697 cam_error_print(device, ccb, CAM_ESF_ALL,
698 CAM_EPF_ALL, stderr);
705 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
707 fprintf(stdout, "Unit is ready\n");
710 fprintf(stdout, "Unit is not ready\n");
713 if (arglist & CAM_ARG_VERBOSE) {
714 cam_error_print(device, ccb, CAM_ESF_ALL,
715 CAM_EPF_ALL, stderr);
725 scsistart(struct cam_device *device, int startstop, int loadeject,
726 int task_attr, int retry_count, int timeout)
731 ccb = cam_getccb(device);
734 * If we're stopping, send an ordered tag so the drive in question
735 * will finish any previously queued writes before stopping. If
736 * the device isn't capable of tagged queueing, or if tagged
737 * queueing is turned off, the tag action is a no-op. We override
738 * the default simple tag, although this also has the effect of
739 * overriding the user's wishes if he wanted to specify a simple
743 && (task_attr == MSG_SIMPLE_Q_TAG))
744 task_attr = MSG_ORDERED_Q_TAG;
746 scsi_start_stop(&ccb->csio,
747 /* retries */ retry_count,
749 /* tag_action */ task_attr,
750 /* start/stop */ startstop,
751 /* load_eject */ loadeject,
753 /* sense_len */ SSD_FULL_SIZE,
754 /* timeout */ timeout ? timeout : 120000);
756 /* Disable freezing the device queue */
757 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
759 if (arglist & CAM_ARG_ERR_RECOVER)
760 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
762 if (cam_send_ccb(device, ccb) < 0) {
763 perror("error sending start unit");
765 if (arglist & CAM_ARG_VERBOSE) {
766 cam_error_print(device, ccb, CAM_ESF_ALL,
767 CAM_EPF_ALL, stderr);
774 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
776 fprintf(stdout, "Unit started successfully");
778 fprintf(stdout,", Media loaded\n");
780 fprintf(stdout,"\n");
782 fprintf(stdout, "Unit stopped successfully");
784 fprintf(stdout, ", Media ejected\n");
786 fprintf(stdout, "\n");
792 "Error received from start unit command\n");
795 "Error received from stop unit command\n");
797 if (arglist & CAM_ARG_VERBOSE) {
798 cam_error_print(device, ccb, CAM_ESF_ALL,
799 CAM_EPF_ALL, stderr);
809 scsidoinquiry(struct cam_device *device, int argc, char **argv,
810 char *combinedopt, int task_attr, int retry_count, int timeout)
815 while ((c = getopt(argc, argv, combinedopt)) != -1) {
818 arglist |= CAM_ARG_GET_STDINQ;
821 arglist |= CAM_ARG_GET_XFERRATE;
824 arglist |= CAM_ARG_GET_SERIAL;
832 * If the user didn't specify any inquiry options, he wants all of
835 if ((arglist & CAM_ARG_INQ_MASK) == 0)
836 arglist |= CAM_ARG_INQ_MASK;
838 if (arglist & CAM_ARG_GET_STDINQ)
839 error = scsiinquiry(device, task_attr, retry_count, timeout);
844 if (arglist & CAM_ARG_GET_SERIAL)
845 scsiserial(device, task_attr, retry_count, timeout);
847 if (arglist & CAM_ARG_GET_XFERRATE)
848 error = camxferrate(device);
854 scsiinquiry(struct cam_device *device, int task_attr, int retry_count,
858 struct scsi_inquiry_data *inq_buf;
861 ccb = cam_getccb(device);
864 warnx("couldn't allocate CCB");
868 /* cam_getccb cleans up the header, caller has to zero the payload */
869 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
871 inq_buf = (struct scsi_inquiry_data *)malloc(
872 sizeof(struct scsi_inquiry_data));
874 if (inq_buf == NULL) {
876 warnx("can't malloc memory for inquiry\n");
879 bzero(inq_buf, sizeof(*inq_buf));
882 * Note that although the size of the inquiry buffer is the full
883 * 256 bytes specified in the SCSI spec, we only tell the device
884 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are
885 * two reasons for this:
887 * - The SCSI spec says that when a length field is only 1 byte,
888 * a value of 0 will be interpreted as 256. Therefore
889 * scsi_inquiry() will convert an inq_len (which is passed in as
890 * a u_int32_t, but the field in the CDB is only 1 byte) of 256
891 * to 0. Evidently, very few devices meet the spec in that
892 * regard. Some devices, like many Seagate disks, take the 0 as
893 * 0, and don't return any data. One Pioneer DVD-R drive
894 * returns more data than the command asked for.
896 * So, since there are numerous devices that just don't work
897 * right with the full inquiry size, we don't send the full size.
899 * - The second reason not to use the full inquiry data length is
900 * that we don't need it here. The only reason we issue a
901 * standard inquiry is to get the vendor name, device name,
902 * and revision so scsi_print_inquiry() can print them.
904 * If, at some point in the future, more inquiry data is needed for
905 * some reason, this code should use a procedure similar to the
906 * probe code. i.e., issue a short inquiry, and determine from
907 * the additional length passed back from the device how much
908 * inquiry data the device supports. Once the amount the device
909 * supports is determined, issue an inquiry for that amount and no
914 scsi_inquiry(&ccb->csio,
915 /* retries */ retry_count,
917 /* tag_action */ task_attr,
918 /* inq_buf */ (u_int8_t *)inq_buf,
919 /* inq_len */ SHORT_INQUIRY_LENGTH,
922 /* sense_len */ SSD_FULL_SIZE,
923 /* timeout */ timeout ? timeout : 5000);
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 SCSI inquiry");
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) {
946 if (arglist & CAM_ARG_VERBOSE) {
947 cam_error_print(device, ccb, CAM_ESF_ALL,
948 CAM_EPF_ALL, stderr);
959 fprintf(stdout, "%s%d: ", device->device_name,
960 device->dev_unit_num);
961 scsi_print_inquiry(inq_buf);
969 scsiserial(struct cam_device *device, int task_attr, int retry_count,
973 struct scsi_vpd_unit_serial_number *serial_buf;
974 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
977 ccb = cam_getccb(device);
980 warnx("couldn't allocate CCB");
984 /* cam_getccb cleans up the header, caller has to zero the payload */
985 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
987 serial_buf = (struct scsi_vpd_unit_serial_number *)
988 malloc(sizeof(*serial_buf));
990 if (serial_buf == NULL) {
992 warnx("can't malloc memory for serial number");
996 scsi_inquiry(&ccb->csio,
997 /*retries*/ retry_count,
999 /* tag_action */ task_attr,
1000 /* inq_buf */ (u_int8_t *)serial_buf,
1001 /* inq_len */ sizeof(*serial_buf),
1003 /* page_code */ SVPD_UNIT_SERIAL_NUMBER,
1004 /* sense_len */ SSD_FULL_SIZE,
1005 /* timeout */ timeout ? timeout : 5000);
1007 /* Disable freezing the device queue */
1008 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1010 if (arglist & CAM_ARG_ERR_RECOVER)
1011 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1013 if (cam_send_ccb(device, ccb) < 0) {
1014 warn("error getting serial number");
1016 if (arglist & CAM_ARG_VERBOSE) {
1017 cam_error_print(device, ccb, CAM_ESF_ALL,
1018 CAM_EPF_ALL, stderr);
1026 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1029 if (arglist & CAM_ARG_VERBOSE) {
1030 cam_error_print(device, ccb, CAM_ESF_ALL,
1031 CAM_EPF_ALL, stderr);
1042 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
1043 serial_num[serial_buf->length] = '\0';
1045 if ((arglist & CAM_ARG_GET_STDINQ)
1046 || (arglist & CAM_ARG_GET_XFERRATE))
1047 fprintf(stdout, "%s%d: Serial Number ",
1048 device->device_name, device->dev_unit_num);
1050 fprintf(stdout, "%.60s\n", serial_num);
1058 camxferrate(struct cam_device *device)
1060 struct ccb_pathinq cpi;
1062 u_int32_t speed = 0;
1067 if ((retval = get_cpi(device, &cpi)) != 0)
1070 ccb = cam_getccb(device);
1073 warnx("couldn't allocate CCB");
1077 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
1079 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1080 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
1082 if (((retval = cam_send_ccb(device, ccb)) < 0)
1083 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
1084 const char error_string[] = "error getting transfer settings";
1089 warnx(error_string);
1091 if (arglist & CAM_ARG_VERBOSE)
1092 cam_error_print(device, ccb, CAM_ESF_ALL,
1093 CAM_EPF_ALL, stderr);
1097 goto xferrate_bailout;
1101 speed = cpi.base_transfer_speed;
1103 if (ccb->cts.transport == XPORT_SPI) {
1104 struct ccb_trans_settings_spi *spi =
1105 &ccb->cts.xport_specific.spi;
1107 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
1108 freq = scsi_calc_syncsrate(spi->sync_period);
1111 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
1112 speed *= (0x01 << spi->bus_width);
1114 } else if (ccb->cts.transport == XPORT_FC) {
1115 struct ccb_trans_settings_fc *fc =
1116 &ccb->cts.xport_specific.fc;
1118 if (fc->valid & CTS_FC_VALID_SPEED)
1119 speed = fc->bitrate;
1120 } else if (ccb->cts.transport == XPORT_SAS) {
1121 struct ccb_trans_settings_sas *sas =
1122 &ccb->cts.xport_specific.sas;
1124 if (sas->valid & CTS_SAS_VALID_SPEED)
1125 speed = sas->bitrate;
1126 } else if (ccb->cts.transport == XPORT_ATA) {
1127 struct ccb_trans_settings_pata *pata =
1128 &ccb->cts.xport_specific.ata;
1130 if (pata->valid & CTS_ATA_VALID_MODE)
1131 speed = ata_mode2speed(pata->mode);
1132 } else if (ccb->cts.transport == XPORT_SATA) {
1133 struct ccb_trans_settings_sata *sata =
1134 &ccb->cts.xport_specific.sata;
1136 if (sata->valid & CTS_SATA_VALID_REVISION)
1137 speed = ata_revision2speed(sata->revision);
1142 fprintf(stdout, "%s%d: %d.%03dMB/s transfers",
1143 device->device_name, device->dev_unit_num,
1146 fprintf(stdout, "%s%d: %dKB/s transfers",
1147 device->device_name, device->dev_unit_num,
1151 if (ccb->cts.transport == XPORT_SPI) {
1152 struct ccb_trans_settings_spi *spi =
1153 &ccb->cts.xport_specific.spi;
1155 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1156 && (spi->sync_offset != 0))
1157 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000,
1158 freq % 1000, spi->sync_offset);
1160 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1161 && (spi->bus_width > 0)) {
1162 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1163 && (spi->sync_offset != 0)) {
1164 fprintf(stdout, ", ");
1166 fprintf(stdout, " (");
1168 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width));
1169 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
1170 && (spi->sync_offset != 0)) {
1171 fprintf(stdout, ")");
1173 } else if (ccb->cts.transport == XPORT_ATA) {
1174 struct ccb_trans_settings_pata *pata =
1175 &ccb->cts.xport_specific.ata;
1178 if (pata->valid & CTS_ATA_VALID_MODE)
1179 printf("%s, ", ata_mode2string(pata->mode));
1180 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
1181 printf("ATAPI %dbytes, ", pata->atapi);
1182 if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
1183 printf("PIO %dbytes", pata->bytecount);
1185 } else if (ccb->cts.transport == XPORT_SATA) {
1186 struct ccb_trans_settings_sata *sata =
1187 &ccb->cts.xport_specific.sata;
1190 if (sata->valid & CTS_SATA_VALID_REVISION)
1191 printf("SATA %d.x, ", sata->revision);
1194 if (sata->valid & CTS_SATA_VALID_MODE)
1195 printf("%s, ", ata_mode2string(sata->mode));
1196 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0)
1197 printf("ATAPI %dbytes, ", sata->atapi);
1198 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1199 printf("PIO %dbytes", sata->bytecount);
1203 if (ccb->cts.protocol == PROTO_SCSI) {
1204 struct ccb_trans_settings_scsi *scsi =
1205 &ccb->cts.proto_specific.scsi;
1206 if (scsi->valid & CTS_SCSI_VALID_TQ) {
1207 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1208 fprintf(stdout, ", Command Queueing Enabled");
1213 fprintf(stdout, "\n");
1223 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header)
1225 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1226 ((u_int32_t)parm->lba_size_2 << 16);
1228 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1229 ((u_int64_t)parm->lba_size48_2 << 16) |
1230 ((u_int64_t)parm->lba_size48_3 << 32) |
1231 ((u_int64_t)parm->lba_size48_4 << 48);
1235 "Support Enabled Value\n");
1238 printf("Host Protected Area (HPA) ");
1239 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) {
1240 u_int64_t lba = lbasize48 ? lbasize48 : lbasize;
1241 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ",
1244 printf("HPA - Security ");
1245 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY)
1255 atasata(struct ata_params *parm)
1259 if (parm->satacapabilities != 0xffff &&
1260 parm->satacapabilities != 0x0000)
1267 atacapprint(struct ata_params *parm)
1269 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
1270 ((u_int32_t)parm->lba_size_2 << 16);
1272 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
1273 ((u_int64_t)parm->lba_size48_2 << 16) |
1274 ((u_int64_t)parm->lba_size48_3 << 32) |
1275 ((u_int64_t)parm->lba_size48_4 << 48);
1278 printf("protocol ");
1279 printf("ATA/ATAPI-%d", ata_version(parm->version_major));
1280 if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
1281 if (parm->satacapabilities & ATA_SATA_GEN3)
1282 printf(" SATA 3.x\n");
1283 else if (parm->satacapabilities & ATA_SATA_GEN2)
1284 printf(" SATA 2.x\n");
1285 else if (parm->satacapabilities & ATA_SATA_GEN1)
1286 printf(" SATA 1.x\n");
1292 printf("device model %.40s\n", parm->model);
1293 printf("firmware revision %.8s\n", parm->revision);
1294 printf("serial number %.20s\n", parm->serial);
1295 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
1296 printf("WWN %04x%04x%04x%04x\n",
1297 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
1299 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
1300 printf("media serial number %.30s\n",
1301 parm->media_serial);
1304 printf("cylinders %d\n", parm->cylinders);
1305 printf("heads %d\n", parm->heads);
1306 printf("sectors/track %d\n", parm->sectors);
1307 printf("sector size logical %u, physical %lu, offset %lu\n",
1308 ata_logical_sector_size(parm),
1309 (unsigned long)ata_physical_sector_size(parm),
1310 (unsigned long)ata_logical_sector_offset(parm));
1312 if (parm->config == ATA_PROTO_CFA ||
1313 (parm->support.command2 & ATA_SUPPORT_CFA))
1314 printf("CFA supported\n");
1316 printf("LBA%ssupported ",
1317 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
1319 printf("%d sectors\n", lbasize);
1323 printf("LBA48%ssupported ",
1324 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
1326 printf("%ju sectors\n", (uintmax_t)lbasize48);
1330 printf("PIO supported PIO");
1331 switch (ata_max_pmode(parm)) {
1347 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
1348 printf(" w/o IORDY");
1351 printf("DMA%ssupported ",
1352 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
1353 if (parm->capabilities1 & ATA_SUPPORT_DMA) {
1354 if (parm->mwdmamodes & 0xff) {
1356 if (parm->mwdmamodes & 0x04)
1358 else if (parm->mwdmamodes & 0x02)
1360 else if (parm->mwdmamodes & 0x01)
1364 if ((parm->atavalid & ATA_FLAG_88) &&
1365 (parm->udmamodes & 0xff)) {
1367 if (parm->udmamodes & 0x40)
1369 else if (parm->udmamodes & 0x20)
1371 else if (parm->udmamodes & 0x10)
1373 else if (parm->udmamodes & 0x08)
1375 else if (parm->udmamodes & 0x04)
1377 else if (parm->udmamodes & 0x02)
1379 else if (parm->udmamodes & 0x01)
1386 if (parm->media_rotation_rate == 1) {
1387 printf("media RPM non-rotating\n");
1388 } else if (parm->media_rotation_rate >= 0x0401 &&
1389 parm->media_rotation_rate <= 0xFFFE) {
1390 printf("media RPM %d\n",
1391 parm->media_rotation_rate);
1395 "Support Enabled Value Vendor\n");
1396 printf("read ahead %s %s\n",
1397 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1398 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1399 printf("write cache %s %s\n",
1400 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1401 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1402 printf("flush cache %s %s\n",
1403 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1404 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1405 printf("overlap %s\n",
1406 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1407 printf("Tagged Command Queuing (TCQ) %s %s",
1408 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1409 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1410 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1411 printf(" %d tags\n",
1412 ATA_QUEUE_LEN(parm->queue) + 1);
1415 printf("Native Command Queuing (NCQ) ");
1416 if (parm->satacapabilities != 0xffff &&
1417 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1418 printf("yes %d tags\n",
1419 ATA_QUEUE_LEN(parm->queue) + 1);
1423 printf("NCQ Queue Management %s\n", atasata(parm) &&
1424 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1426 printf("NCQ Streaming %s\n", atasata(parm) &&
1427 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1429 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1430 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1433 printf("SMART %s %s\n",
1434 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1435 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1436 printf("microcode download %s %s\n",
1437 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1438 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1439 printf("security %s %s\n",
1440 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1441 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1442 printf("power management %s %s\n",
1443 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1444 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1445 printf("advanced power management %s %s",
1446 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1447 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1448 if (parm->support.command2 & ATA_SUPPORT_APM) {
1449 printf(" %d/0x%02X\n",
1450 parm->apm_value & 0xff, parm->apm_value & 0xff);
1453 printf("automatic acoustic management %s %s",
1454 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1455 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1456 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1457 printf(" %d/0x%02X %d/0x%02X\n",
1458 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1459 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1460 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1461 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1464 printf("media status notification %s %s\n",
1465 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1466 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1467 printf("power-up in Standby %s %s\n",
1468 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1469 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1470 printf("write-read-verify %s %s",
1471 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1472 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1473 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1474 printf(" %d/0x%x\n",
1475 parm->wrv_mode, parm->wrv_mode);
1478 printf("unload %s %s\n",
1479 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1480 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1481 printf("general purpose logging %s %s\n",
1482 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1483 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1484 printf("free-fall %s %s\n",
1485 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1486 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1487 printf("Data Set Management (DSM/TRIM) ");
1488 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1490 printf("DSM - max 512byte blocks ");
1491 if (parm->max_dsm_blocks == 0x00)
1492 printf("yes not specified\n");
1495 parm->max_dsm_blocks);
1497 printf("DSM - deterministic read ");
1498 if (parm->support3 & ATA_SUPPORT_DRAT) {
1499 if (parm->support3 & ATA_SUPPORT_RZAT)
1500 printf("yes zeroed\n");
1502 printf("yes any value\n");
1512 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1514 struct ata_pass_16 *ata_pass_16;
1515 struct ata_cmd ata_cmd;
1517 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1518 ata_cmd.command = ata_pass_16->command;
1519 ata_cmd.control = ata_pass_16->control;
1520 ata_cmd.features = ata_pass_16->features;
1522 if (arglist & CAM_ARG_VERBOSE) {
1523 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1524 ata_op_string(&ata_cmd),
1525 ccb->csio.ccb_h.timeout);
1528 /* Disable freezing the device queue */
1529 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1531 if (arglist & CAM_ARG_ERR_RECOVER)
1532 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1534 if (cam_send_ccb(device, ccb) < 0) {
1535 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1536 warn("error sending ATA %s via pass_16",
1537 ata_op_string(&ata_cmd));
1540 if (arglist & CAM_ARG_VERBOSE) {
1541 cam_error_print(device, ccb, CAM_ESF_ALL,
1542 CAM_EPF_ALL, stderr);
1548 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1549 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1550 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1551 warnx("ATA %s via pass_16 failed",
1552 ata_op_string(&ata_cmd));
1554 if (arglist & CAM_ARG_VERBOSE) {
1555 cam_error_print(device, ccb, CAM_ESF_ALL,
1556 CAM_EPF_ALL, stderr);
1567 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1569 if (arglist & CAM_ARG_VERBOSE) {
1570 warnx("sending ATA %s with timeout of %u msecs",
1571 ata_op_string(&(ccb->ataio.cmd)),
1572 ccb->ataio.ccb_h.timeout);
1575 /* Disable freezing the device queue */
1576 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1578 if (arglist & CAM_ARG_ERR_RECOVER)
1579 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1581 if (cam_send_ccb(device, ccb) < 0) {
1582 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1583 warn("error sending ATA %s",
1584 ata_op_string(&(ccb->ataio.cmd)));
1587 if (arglist & CAM_ARG_VERBOSE) {
1588 cam_error_print(device, ccb, CAM_ESF_ALL,
1589 CAM_EPF_ALL, stderr);
1595 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1596 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1597 warnx("ATA %s failed: %d",
1598 ata_op_string(&(ccb->ataio.cmd)), quiet);
1601 if (arglist & CAM_ARG_VERBOSE) {
1602 cam_error_print(device, ccb, CAM_ESF_ALL,
1603 CAM_EPF_ALL, stderr);
1613 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1614 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1615 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1616 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1617 u_int16_t dxfer_len, int timeout, int quiet)
1619 if (data_ptr != NULL) {
1620 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1621 AP_FLAG_TLEN_SECT_CNT;
1622 if (flags & CAM_DIR_OUT)
1623 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1625 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1627 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1630 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1632 scsi_ata_pass_16(&ccb->csio,
1646 /*sense_len*/SSD_FULL_SIZE,
1649 return scsi_cam_pass_16_send(device, ccb, quiet);
1653 ata_try_pass_16(struct cam_device *device)
1655 struct ccb_pathinq cpi;
1657 if (get_cpi(device, &cpi) != 0) {
1658 warnx("couldn't get CPI");
1662 if (cpi.protocol == PROTO_SCSI) {
1663 /* possibly compatible with pass_16 */
1667 /* likely not compatible with pass_16 */
1672 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1673 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1674 u_int8_t command, u_int8_t features, u_int32_t lba,
1675 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1676 int timeout, int quiet)
1680 switch (ata_try_pass_16(device)) {
1684 /* Try using SCSI Passthrough */
1685 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1686 0, tag_action, command, features, lba,
1687 sector_count, data_ptr, dxfer_len,
1691 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1692 cam_fill_ataio(&ccb->ataio,
1701 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1702 return ata_cam_send(device, ccb, quiet);
1706 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1707 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1708 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1709 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1710 u_int16_t dxfer_len, int timeout, int force48bit)
1714 retval = ata_try_pass_16(device);
1721 /* Try using SCSI Passthrough */
1722 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1723 ata_flags, tag_action, command, features,
1724 lba, sector_count, data_ptr, dxfer_len,
1727 if (ata_flags & AP_FLAG_CHK_COND) {
1728 /* Decode ata_res from sense data */
1729 struct ata_res_pass16 *res_pass16;
1730 struct ata_res *res;
1734 /* sense_data is 4 byte aligned */
1735 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1736 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1737 ptr[i] = le16toh(ptr[i]);
1739 /* sense_data is 4 byte aligned */
1740 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1741 &ccb->csio.sense_data;
1742 res = &ccb->ataio.res;
1743 res->flags = res_pass16->flags;
1744 res->status = res_pass16->status;
1745 res->error = res_pass16->error;
1746 res->lba_low = res_pass16->lba_low;
1747 res->lba_mid = res_pass16->lba_mid;
1748 res->lba_high = res_pass16->lba_high;
1749 res->device = res_pass16->device;
1750 res->lba_low_exp = res_pass16->lba_low_exp;
1751 res->lba_mid_exp = res_pass16->lba_mid_exp;
1752 res->lba_high_exp = res_pass16->lba_high_exp;
1753 res->sector_count = res_pass16->sector_count;
1754 res->sector_count_exp = res_pass16->sector_count_exp;
1760 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1761 cam_fill_ataio(&ccb->ataio,
1770 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1771 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1773 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1775 if (ata_flags & AP_FLAG_CHK_COND)
1776 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1778 return ata_cam_send(device, ccb, 0);
1782 dump_data(uint16_t *ptr, uint32_t len)
1786 for (i = 0; i < len / 2; i++) {
1788 printf(" %3d: ", i);
1789 printf("%04hx ", ptr[i]);
1798 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1799 int is48bit, u_int64_t *hpasize)
1801 struct ata_res *res;
1803 res = &ccb->ataio.res;
1804 if (res->status & ATA_STATUS_ERROR) {
1805 if (arglist & CAM_ARG_VERBOSE) {
1806 cam_error_print(device, ccb, CAM_ESF_ALL,
1807 CAM_EPF_ALL, stderr);
1808 printf("error = 0x%02x, sector_count = 0x%04x, "
1809 "device = 0x%02x, status = 0x%02x\n",
1810 res->error, res->sector_count,
1811 res->device, res->status);
1814 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1815 warnx("Max address has already been set since "
1816 "last power-on or hardware reset");
1822 if (arglist & CAM_ARG_VERBOSE) {
1823 fprintf(stdout, "%s%d: Raw native max data:\n",
1824 device->device_name, device->dev_unit_num);
1825 /* res is 4 byte aligned */
1826 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1828 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1829 "status = 0x%02x\n", res->error, res->sector_count,
1830 res->device, res->status);
1833 if (hpasize != NULL) {
1835 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1836 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1837 ((res->lba_high << 16) | (res->lba_mid << 8) |
1840 *hpasize = (((res->device & 0x0f) << 24) |
1841 (res->lba_high << 16) | (res->lba_mid << 8) |
1850 ata_read_native_max(struct cam_device *device, int retry_count,
1851 u_int32_t timeout, union ccb *ccb,
1852 struct ata_params *parm, u_int64_t *hpasize)
1858 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1859 protocol = AP_PROTO_NON_DATA;
1862 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1863 protocol |= AP_EXTEND;
1865 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1868 error = ata_do_cmd(device,
1871 /*flags*/CAM_DIR_NONE,
1872 /*protocol*/protocol,
1873 /*ata_flags*/AP_FLAG_CHK_COND,
1874 /*tag_action*/MSG_SIMPLE_Q_TAG,
1881 timeout ? timeout : 1000,
1887 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
1891 atahpa_set_max(struct cam_device *device, int retry_count,
1892 u_int32_t timeout, union ccb *ccb,
1893 int is48bit, u_int64_t maxsize, int persist)
1899 protocol = AP_PROTO_NON_DATA;
1902 cmd = ATA_SET_MAX_ADDRESS48;
1903 protocol |= AP_EXTEND;
1905 cmd = ATA_SET_MAX_ADDRESS;
1908 /* lba's are zero indexed so the max lba is requested max - 1 */
1912 error = ata_do_cmd(device,
1915 /*flags*/CAM_DIR_NONE,
1916 /*protocol*/protocol,
1917 /*ata_flags*/AP_FLAG_CHK_COND,
1918 /*tag_action*/MSG_SIMPLE_Q_TAG,
1920 /*features*/ATA_HPA_FEAT_MAX_ADDR,
1922 /*sector_count*/persist,
1925 timeout ? timeout : 1000,
1931 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1935 atahpa_password(struct cam_device *device, int retry_count,
1936 u_int32_t timeout, union ccb *ccb,
1937 int is48bit, struct ata_set_max_pwd *pwd)
1943 protocol = AP_PROTO_PIO_OUT;
1944 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1946 error = ata_do_cmd(device,
1949 /*flags*/CAM_DIR_OUT,
1950 /*protocol*/protocol,
1951 /*ata_flags*/AP_FLAG_CHK_COND,
1952 /*tag_action*/MSG_SIMPLE_Q_TAG,
1954 /*features*/ATA_HPA_FEAT_SET_PWD,
1957 /*data_ptr*/(u_int8_t*)pwd,
1958 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1959 timeout ? timeout : 1000,
1965 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1969 atahpa_lock(struct cam_device *device, int retry_count,
1970 u_int32_t timeout, union ccb *ccb, int is48bit)
1976 protocol = AP_PROTO_NON_DATA;
1977 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1979 error = ata_do_cmd(device,
1982 /*flags*/CAM_DIR_NONE,
1983 /*protocol*/protocol,
1984 /*ata_flags*/AP_FLAG_CHK_COND,
1985 /*tag_action*/MSG_SIMPLE_Q_TAG,
1987 /*features*/ATA_HPA_FEAT_LOCK,
1992 timeout ? timeout : 1000,
1998 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2002 atahpa_unlock(struct cam_device *device, int retry_count,
2003 u_int32_t timeout, union ccb *ccb,
2004 int is48bit, struct ata_set_max_pwd *pwd)
2010 protocol = AP_PROTO_PIO_OUT;
2011 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2013 error = ata_do_cmd(device,
2016 /*flags*/CAM_DIR_OUT,
2017 /*protocol*/protocol,
2018 /*ata_flags*/AP_FLAG_CHK_COND,
2019 /*tag_action*/MSG_SIMPLE_Q_TAG,
2021 /*features*/ATA_HPA_FEAT_UNLOCK,
2024 /*data_ptr*/(u_int8_t*)pwd,
2025 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2026 timeout ? timeout : 1000,
2032 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2036 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2037 u_int32_t timeout, union ccb *ccb, int is48bit)
2043 protocol = AP_PROTO_NON_DATA;
2044 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2046 error = ata_do_cmd(device,
2049 /*flags*/CAM_DIR_NONE,
2050 /*protocol*/protocol,
2051 /*ata_flags*/AP_FLAG_CHK_COND,
2052 /*tag_action*/MSG_SIMPLE_Q_TAG,
2054 /*features*/ATA_HPA_FEAT_FREEZE,
2059 timeout ? timeout : 1000,
2065 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2070 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2071 union ccb *ccb, struct ata_params** ident_bufp)
2073 struct ata_params *ident_buf;
2074 struct ccb_pathinq cpi;
2075 struct ccb_getdev cgd;
2078 u_int8_t command, retry_command;
2080 if (get_cpi(device, &cpi) != 0) {
2081 warnx("couldn't get CPI");
2085 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2086 if (cpi.protocol == PROTO_ATA) {
2087 if (get_cgd(device, &cgd) != 0) {
2088 warnx("couldn't get CGD");
2092 command = (cgd.protocol == PROTO_ATA) ?
2093 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2096 /* We don't know which for sure so try both */
2097 command = ATA_ATA_IDENTIFY;
2098 retry_command = ATA_ATAPI_IDENTIFY;
2101 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2103 warnx("can't calloc memory for identify\n");
2107 error = ata_do_28bit_cmd(device,
2109 /*retries*/retry_count,
2110 /*flags*/CAM_DIR_IN,
2111 /*protocol*/AP_PROTO_PIO_IN,
2112 /*tag_action*/MSG_SIMPLE_Q_TAG,
2116 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2117 /*data_ptr*/(u_int8_t *)ptr,
2118 /*dxfer_len*/sizeof(struct ata_params),
2119 /*timeout*/timeout ? timeout : 30 * 1000,
2123 if (retry_command == 0) {
2127 error = ata_do_28bit_cmd(device,
2129 /*retries*/retry_count,
2130 /*flags*/CAM_DIR_IN,
2131 /*protocol*/AP_PROTO_PIO_IN,
2132 /*tag_action*/MSG_SIMPLE_Q_TAG,
2133 /*command*/retry_command,
2136 /*sector_count*/(u_int8_t)
2137 sizeof(struct ata_params),
2138 /*data_ptr*/(u_int8_t *)ptr,
2139 /*dxfer_len*/sizeof(struct ata_params),
2140 /*timeout*/timeout ? timeout : 30 * 1000,
2150 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2151 ptr[i] = le16toh(ptr[i]);
2156 if (arglist & CAM_ARG_VERBOSE) {
2157 fprintf(stdout, "%s%d: Raw identify data:\n",
2158 device->device_name, device->dev_unit_num);
2159 dump_data(ptr, sizeof(struct ata_params));
2162 /* check for invalid (all zero) response */
2164 warnx("Invalid identify response detected");
2169 ident_buf = (struct ata_params *)ptr;
2170 if (strncmp(ident_buf->model, "FX", 2) &&
2171 strncmp(ident_buf->model, "NEC", 3) &&
2172 strncmp(ident_buf->model, "Pioneer", 7) &&
2173 strncmp(ident_buf->model, "SHARP", 5)) {
2174 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2175 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2176 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2177 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2179 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2180 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2181 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2182 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2183 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2184 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2185 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2186 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2187 sizeof(ident_buf->media_serial));
2189 *ident_bufp = ident_buf;
2196 ataidentify(struct cam_device *device, int retry_count, int timeout)
2199 struct ata_params *ident_buf;
2202 if ((ccb = cam_getccb(device)) == NULL) {
2203 warnx("couldn't allocate CCB");
2207 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2212 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2213 if (ata_read_native_max(device, retry_count, timeout, ccb,
2214 ident_buf, &hpasize) != 0) {
2222 printf("%s%d: ", device->device_name, device->dev_unit_num);
2223 ata_print_ident(ident_buf);
2224 camxferrate(device);
2225 atacapprint(ident_buf);
2226 atahpa_print(ident_buf, hpasize, 0);
2233 #endif /* MINIMALISTIC */
2236 #ifndef MINIMALISTIC
2238 ATA_SECURITY_ACTION_PRINT,
2239 ATA_SECURITY_ACTION_FREEZE,
2240 ATA_SECURITY_ACTION_UNLOCK,
2241 ATA_SECURITY_ACTION_DISABLE,
2242 ATA_SECURITY_ACTION_ERASE,
2243 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2244 ATA_SECURITY_ACTION_SET_PASSWORD
2248 atasecurity_print_time(u_int16_t tw)
2252 printf("unspecified");
2254 printf("> 508 min");
2256 printf("%i min", 2 * tw);
2260 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2264 return 2 * 3600 * 1000; /* default: two hours */
2265 else if (timeout > 255)
2266 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2268 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2273 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2277 bzero(&cmd, sizeof(cmd));
2278 cmd.command = command;
2279 printf("Issuing %s", ata_op_string(&cmd));
2282 char pass[sizeof(pwd->password)+1];
2284 /* pwd->password may not be null terminated */
2285 pass[sizeof(pwd->password)] = '\0';
2286 strncpy(pass, pwd->password, sizeof(pwd->password));
2287 printf(" password='%s', user='%s'",
2289 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2292 if (command == ATA_SECURITY_SET_PASSWORD) {
2293 printf(", mode='%s'",
2294 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2295 "maximum" : "high");
2303 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2304 int retry_count, u_int32_t timeout, int quiet)
2308 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2310 return ata_do_28bit_cmd(device,
2313 /*flags*/CAM_DIR_NONE,
2314 /*protocol*/AP_PROTO_NON_DATA,
2315 /*tag_action*/MSG_SIMPLE_Q_TAG,
2316 /*command*/ATA_SECURITY_FREEZE_LOCK,
2327 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2328 int retry_count, u_int32_t timeout,
2329 struct ata_security_password *pwd, int quiet)
2333 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2335 return ata_do_28bit_cmd(device,
2338 /*flags*/CAM_DIR_OUT,
2339 /*protocol*/AP_PROTO_PIO_OUT,
2340 /*tag_action*/MSG_SIMPLE_Q_TAG,
2341 /*command*/ATA_SECURITY_UNLOCK,
2345 /*data_ptr*/(u_int8_t *)pwd,
2346 /*dxfer_len*/sizeof(*pwd),
2352 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2353 int retry_count, u_int32_t timeout,
2354 struct ata_security_password *pwd, int quiet)
2358 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2359 return ata_do_28bit_cmd(device,
2362 /*flags*/CAM_DIR_OUT,
2363 /*protocol*/AP_PROTO_PIO_OUT,
2364 /*tag_action*/MSG_SIMPLE_Q_TAG,
2365 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2369 /*data_ptr*/(u_int8_t *)pwd,
2370 /*dxfer_len*/sizeof(*pwd),
2377 atasecurity_erase_confirm(struct cam_device *device,
2378 struct ata_params* ident_buf)
2381 printf("\nYou are about to ERASE ALL DATA from the following"
2382 " device:\n%s%d,%s%d: ", device->device_name,
2383 device->dev_unit_num, device->given_dev_name,
2384 device->given_unit_number);
2385 ata_print_ident(ident_buf);
2389 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2391 if (fgets(str, sizeof(str), stdin) != NULL) {
2392 if (strncasecmp(str, "yes", 3) == 0) {
2394 } else if (strncasecmp(str, "no", 2) == 0) {
2397 printf("Please answer \"yes\" or "
2408 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2409 int retry_count, u_int32_t timeout,
2410 u_int32_t erase_timeout,
2411 struct ata_security_password *pwd, int quiet)
2416 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2418 error = ata_do_28bit_cmd(device,
2421 /*flags*/CAM_DIR_NONE,
2422 /*protocol*/AP_PROTO_NON_DATA,
2423 /*tag_action*/MSG_SIMPLE_Q_TAG,
2424 /*command*/ATA_SECURITY_ERASE_PREPARE,
2437 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2439 error = ata_do_28bit_cmd(device,
2442 /*flags*/CAM_DIR_OUT,
2443 /*protocol*/AP_PROTO_PIO_OUT,
2444 /*tag_action*/MSG_SIMPLE_Q_TAG,
2445 /*command*/ATA_SECURITY_ERASE_UNIT,
2449 /*data_ptr*/(u_int8_t *)pwd,
2450 /*dxfer_len*/sizeof(*pwd),
2451 /*timeout*/erase_timeout,
2454 if (error == 0 && quiet == 0)
2455 printf("\nErase Complete\n");
2461 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2462 int retry_count, u_int32_t timeout,
2463 struct ata_security_password *pwd, int quiet)
2467 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2469 return ata_do_28bit_cmd(device,
2472 /*flags*/CAM_DIR_OUT,
2473 /*protocol*/AP_PROTO_PIO_OUT,
2474 /*tag_action*/MSG_SIMPLE_Q_TAG,
2475 /*command*/ATA_SECURITY_SET_PASSWORD,
2479 /*data_ptr*/(u_int8_t *)pwd,
2480 /*dxfer_len*/sizeof(*pwd),
2486 atasecurity_print(struct ata_params *parm)
2489 printf("\nSecurity Option Value\n");
2490 if (arglist & CAM_ARG_VERBOSE) {
2491 printf("status %04x\n",
2492 parm->security_status);
2494 printf("supported %s\n",
2495 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2496 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2498 printf("enabled %s\n",
2499 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2500 printf("drive locked %s\n",
2501 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2502 printf("security config frozen %s\n",
2503 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2504 printf("count expired %s\n",
2505 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2506 printf("security level %s\n",
2507 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2508 printf("enhanced erase supported %s\n",
2509 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2510 printf("erase time ");
2511 atasecurity_print_time(parm->erase_time);
2513 printf("enhanced erase time ");
2514 atasecurity_print_time(parm->enhanced_erase_time);
2516 printf("master password rev %04x%s\n",
2517 parm->master_passwd_revision,
2518 parm->master_passwd_revision == 0x0000 ||
2519 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2523 * Validates and copies the password in optarg to the passed buffer.
2524 * If the password in optarg is the same length as the buffer then
2525 * the data will still be copied but no null termination will occur.
2528 ata_getpwd(u_int8_t *passwd, int max, char opt)
2532 len = strlen(optarg);
2534 warnx("-%c password is too long", opt);
2536 } else if (len == 0) {
2537 warnx("-%c password is missing", opt);
2539 } else if (optarg[0] == '-'){
2540 warnx("-%c password starts with '-' (generic arg?)", opt);
2542 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2543 warnx("-%c password conflicts with existing password from -%c",
2548 /* Callers pass in a buffer which does NOT need to be terminated */
2549 strncpy(passwd, optarg, max);
2556 ATA_HPA_ACTION_PRINT,
2557 ATA_HPA_ACTION_SET_MAX,
2558 ATA_HPA_ACTION_SET_PWD,
2559 ATA_HPA_ACTION_LOCK,
2560 ATA_HPA_ACTION_UNLOCK,
2561 ATA_HPA_ACTION_FREEZE_LOCK
2565 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2566 u_int64_t maxsize, int persist)
2568 printf("\nYou are about to configure HPA to limit the user accessible\n"
2569 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2570 persist ? "persistently" : "temporarily",
2571 device->device_name, device->dev_unit_num,
2572 device->given_dev_name, device->given_unit_number);
2573 ata_print_ident(ident_buf);
2577 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2579 if (NULL != fgets(str, sizeof(str), stdin)) {
2580 if (0 == strncasecmp(str, "yes", 3)) {
2582 } else if (0 == strncasecmp(str, "no", 2)) {
2585 printf("Please answer \"yes\" or "
2596 atahpa(struct cam_device *device, int retry_count, int timeout,
2597 int argc, char **argv, char *combinedopt)
2600 struct ata_params *ident_buf;
2601 struct ccb_getdev cgd;
2602 struct ata_set_max_pwd pwd;
2603 int error, confirm, quiet, c, action, actions, persist;
2604 int security, is48bit, pwdsize;
2605 u_int64_t hpasize, maxsize;
2614 memset(&pwd, 0, sizeof(pwd));
2616 /* default action is to print hpa information */
2617 action = ATA_HPA_ACTION_PRINT;
2618 pwdsize = sizeof(pwd.password);
2620 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2623 action = ATA_HPA_ACTION_SET_MAX;
2624 maxsize = strtoumax(optarg, NULL, 0);
2629 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2631 action = ATA_HPA_ACTION_SET_PWD;
2637 action = ATA_HPA_ACTION_LOCK;
2643 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2645 action = ATA_HPA_ACTION_UNLOCK;
2651 action = ATA_HPA_ACTION_FREEZE_LOCK;
2671 warnx("too many hpa actions specified");
2675 if (get_cgd(device, &cgd) != 0) {
2676 warnx("couldn't get CGD");
2680 ccb = cam_getccb(device);
2682 warnx("couldn't allocate CCB");
2686 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2693 printf("%s%d: ", device->device_name, device->dev_unit_num);
2694 ata_print_ident(ident_buf);
2695 camxferrate(device);
2698 if (action == ATA_HPA_ACTION_PRINT) {
2699 error = ata_read_native_max(device, retry_count, timeout, ccb,
2700 ident_buf, &hpasize);
2702 atahpa_print(ident_buf, hpasize, 1);
2709 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2710 warnx("HPA is not supported by this device");
2716 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2717 warnx("HPA Security is not supported by this device");
2723 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2726 * The ATA spec requires:
2727 * 1. Read native max addr is called directly before set max addr
2728 * 2. Read native max addr is NOT called before any other set max call
2731 case ATA_HPA_ACTION_SET_MAX:
2733 atahpa_set_confirm(device, ident_buf, maxsize,
2740 error = ata_read_native_max(device, retry_count, timeout,
2741 ccb, ident_buf, &hpasize);
2743 error = atahpa_set_max(device, retry_count, timeout,
2744 ccb, is48bit, maxsize, persist);
2746 /* redo identify to get new lba values */
2747 error = ata_do_identify(device, retry_count,
2750 atahpa_print(ident_buf, hpasize, 1);
2755 case ATA_HPA_ACTION_SET_PWD:
2756 error = atahpa_password(device, retry_count, timeout,
2757 ccb, is48bit, &pwd);
2759 printf("HPA password has been set\n");
2762 case ATA_HPA_ACTION_LOCK:
2763 error = atahpa_lock(device, retry_count, timeout,
2766 printf("HPA has been locked\n");
2769 case ATA_HPA_ACTION_UNLOCK:
2770 error = atahpa_unlock(device, retry_count, timeout,
2771 ccb, is48bit, &pwd);
2773 printf("HPA has been unlocked\n");
2776 case ATA_HPA_ACTION_FREEZE_LOCK:
2777 error = atahpa_freeze_lock(device, retry_count, timeout,
2780 printf("HPA has been frozen\n");
2784 errx(1, "Option currently not supported");
2794 atasecurity(struct cam_device *device, int retry_count, int timeout,
2795 int argc, char **argv, char *combinedopt)
2798 struct ata_params *ident_buf;
2799 int error, confirm, quiet, c, action, actions, setpwd;
2800 int security_enabled, erase_timeout, pwdsize;
2801 struct ata_security_password pwd;
2809 memset(&pwd, 0, sizeof(pwd));
2811 /* default action is to print security information */
2812 action = ATA_SECURITY_ACTION_PRINT;
2814 /* user is master by default as its safer that way */
2815 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2816 pwdsize = sizeof(pwd.password);
2818 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2821 action = ATA_SECURITY_ACTION_FREEZE;
2826 if (strcasecmp(optarg, "user") == 0) {
2827 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2828 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2829 } else if (strcasecmp(optarg, "master") == 0) {
2830 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2831 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2833 warnx("-U argument '%s' is invalid (must be "
2834 "'user' or 'master')", optarg);
2840 if (strcasecmp(optarg, "high") == 0) {
2841 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2842 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2843 } else if (strcasecmp(optarg, "maximum") == 0) {
2844 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2845 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2847 warnx("-l argument '%s' is unknown (must be "
2848 "'high' or 'maximum')", optarg);
2854 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2856 action = ATA_SECURITY_ACTION_UNLOCK;
2861 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2863 action = ATA_SECURITY_ACTION_DISABLE;
2868 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2870 action = ATA_SECURITY_ACTION_ERASE;
2875 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2877 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2878 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2883 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2886 if (action == ATA_SECURITY_ACTION_PRINT)
2887 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2889 * Don't increment action as this can be combined
2890 * with other actions.
2903 erase_timeout = atoi(optarg) * 1000;
2909 warnx("too many security actions specified");
2913 if ((ccb = cam_getccb(device)) == NULL) {
2914 warnx("couldn't allocate CCB");
2918 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2925 printf("%s%d: ", device->device_name, device->dev_unit_num);
2926 ata_print_ident(ident_buf);
2927 camxferrate(device);
2930 if (action == ATA_SECURITY_ACTION_PRINT) {
2931 atasecurity_print(ident_buf);
2937 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2938 warnx("Security not supported");
2944 /* default timeout 15 seconds the same as linux hdparm */
2945 timeout = timeout ? timeout : 15 * 1000;
2947 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2949 /* first set the password if requested */
2951 /* confirm we can erase before setting the password if erasing */
2953 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2954 action == ATA_SECURITY_ACTION_ERASE) &&
2955 atasecurity_erase_confirm(device, ident_buf) == 0) {
2961 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2962 pwd.revision = ident_buf->master_passwd_revision;
2963 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2964 --pwd.revision == 0) {
2965 pwd.revision = 0xfffe;
2968 error = atasecurity_set_password(device, ccb, retry_count,
2969 timeout, &pwd, quiet);
2975 security_enabled = 1;
2979 case ATA_SECURITY_ACTION_FREEZE:
2980 error = atasecurity_freeze(device, ccb, retry_count,
2984 case ATA_SECURITY_ACTION_UNLOCK:
2985 if (security_enabled) {
2986 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2987 error = atasecurity_unlock(device, ccb,
2988 retry_count, timeout, &pwd, quiet);
2990 warnx("Can't unlock, drive is not locked");
2994 warnx("Can't unlock, security is disabled");
2999 case ATA_SECURITY_ACTION_DISABLE:
3000 if (security_enabled) {
3001 /* First unlock the drive if its locked */
3002 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3003 error = atasecurity_unlock(device, ccb,
3011 error = atasecurity_disable(device,
3019 warnx("Can't disable security (already disabled)");
3024 case ATA_SECURITY_ACTION_ERASE:
3025 if (security_enabled) {
3026 if (erase_timeout == 0) {
3027 erase_timeout = atasecurity_erase_timeout_msecs(
3028 ident_buf->erase_time);
3031 error = atasecurity_erase(device, ccb, retry_count,
3032 timeout, erase_timeout, &pwd,
3035 warnx("Can't secure erase (security is disabled)");
3040 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3041 if (security_enabled) {
3042 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3043 if (erase_timeout == 0) {
3045 atasecurity_erase_timeout_msecs(
3046 ident_buf->enhanced_erase_time);
3049 error = atasecurity_erase(device, ccb,
3050 retry_count, timeout,
3051 erase_timeout, &pwd,
3054 warnx("Enhanced erase is not supported");
3058 warnx("Can't secure erase (enhanced), "
3059 "(security is disabled)");
3070 #endif /* MINIMALISTIC */
3073 * Parse out a bus, or a bus, target and lun in the following
3079 * Returns the number of parsed components, or 0.
3082 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3083 cam_argmask *arglst)
3088 while (isspace(*tstr) && (*tstr != '\0'))
3091 tmpstr = (char *)strtok(tstr, ":");
3092 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3093 *bus = strtol(tmpstr, NULL, 0);
3094 *arglst |= CAM_ARG_BUS;
3096 tmpstr = (char *)strtok(NULL, ":");
3097 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3098 *target = strtol(tmpstr, NULL, 0);
3099 *arglst |= CAM_ARG_TARGET;
3101 tmpstr = (char *)strtok(NULL, ":");
3102 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3103 *lun = strtol(tmpstr, NULL, 0);
3104 *arglst |= CAM_ARG_LUN;
3114 dorescan_or_reset(int argc, char **argv, int rescan)
3116 static const char must[] =
3117 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3119 path_id_t bus = CAM_BUS_WILDCARD;
3120 target_id_t target = CAM_TARGET_WILDCARD;
3121 lun_id_t lun = CAM_LUN_WILDCARD;
3125 warnx(must, rescan? "rescan" : "reset");
3129 tstr = argv[optind];
3130 while (isspace(*tstr) && (*tstr != '\0'))
3132 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3133 arglist |= CAM_ARG_BUS;
3135 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3136 if (rv != 1 && rv != 3) {
3137 warnx(must, rescan? "rescan" : "reset");
3142 if ((arglist & CAM_ARG_BUS)
3143 && (arglist & CAM_ARG_TARGET)
3144 && (arglist & CAM_ARG_LUN))
3145 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3147 error = rescan_or_reset_bus(bus, rescan);
3153 rescan_or_reset_bus(path_id_t bus, int rescan)
3155 union ccb *ccb = NULL, *matchccb = NULL;
3156 int fd = -1, retval;
3161 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3162 warnx("error opening transport layer device %s", XPT_DEVICE);
3163 warn("%s", XPT_DEVICE);
3167 ccb = malloc(sizeof(*ccb));
3169 warn("failed to allocate CCB");
3173 bzero(ccb, sizeof(*ccb));
3175 if (bus != CAM_BUS_WILDCARD) {
3176 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3177 ccb->ccb_h.path_id = bus;
3178 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3179 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3180 ccb->crcn.flags = CAM_FLAG_NONE;
3182 /* run this at a low priority */
3183 ccb->ccb_h.pinfo.priority = 5;
3185 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3186 warn("CAMIOCOMMAND ioctl failed");
3191 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3192 fprintf(stdout, "%s of bus %d was successful\n",
3193 rescan ? "Re-scan" : "Reset", bus);
3195 fprintf(stdout, "%s of bus %d returned error %#x\n",
3196 rescan ? "Re-scan" : "Reset", bus,
3197 ccb->ccb_h.status & CAM_STATUS_MASK);
3206 * The right way to handle this is to modify the xpt so that it can
3207 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3208 * that isn't implemented, so instead we enumerate the buses and
3209 * send the rescan or reset to those buses in the case where the
3210 * given bus is -1 (wildcard). We don't send a rescan or reset
3211 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3212 * no-op, sending a rescan to the xpt bus would result in a status of
3215 matchccb = malloc(sizeof(*matchccb));
3216 if (matchccb == NULL) {
3217 warn("failed to allocate CCB");
3221 bzero(matchccb, sizeof(*matchccb));
3222 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3223 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3224 bufsize = sizeof(struct dev_match_result) * 20;
3225 matchccb->cdm.match_buf_len = bufsize;
3226 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3227 if (matchccb->cdm.matches == NULL) {
3228 warnx("can't malloc memory for matches");
3232 matchccb->cdm.num_matches = 0;
3234 matchccb->cdm.num_patterns = 1;
3235 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3237 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3238 matchccb->cdm.pattern_buf_len);
3239 if (matchccb->cdm.patterns == NULL) {
3240 warnx("can't malloc memory for patterns");
3244 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3245 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3250 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3251 warn("CAMIOCOMMAND ioctl failed");
3256 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3257 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3258 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3259 warnx("got CAM error %#x, CDM error %d\n",
3260 matchccb->ccb_h.status, matchccb->cdm.status);
3265 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3266 struct bus_match_result *bus_result;
3268 /* This shouldn't happen. */
3269 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3272 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3275 * We don't want to rescan or reset the xpt bus.
3278 if (bus_result->path_id == CAM_XPT_PATH_ID)
3281 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3283 ccb->ccb_h.path_id = bus_result->path_id;
3284 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3285 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3286 ccb->crcn.flags = CAM_FLAG_NONE;
3288 /* run this at a low priority */
3289 ccb->ccb_h.pinfo.priority = 5;
3291 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3292 warn("CAMIOCOMMAND ioctl failed");
3297 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3298 fprintf(stdout, "%s of bus %d was successful\n",
3299 rescan? "Re-scan" : "Reset",
3300 bus_result->path_id);
3303 * Don't bail out just yet, maybe the other
3304 * rescan or reset commands will complete
3307 fprintf(stderr, "%s of bus %d returned error "
3308 "%#x\n", rescan? "Re-scan" : "Reset",
3309 bus_result->path_id,
3310 ccb->ccb_h.status & CAM_STATUS_MASK);
3314 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3315 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3322 if (matchccb != NULL) {
3323 free(matchccb->cdm.patterns);
3324 free(matchccb->cdm.matches);
3333 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3336 struct cam_device *device;
3341 if (bus == CAM_BUS_WILDCARD) {
3342 warnx("invalid bus number %d", bus);
3346 if (target == CAM_TARGET_WILDCARD) {
3347 warnx("invalid target number %d", target);
3351 if (lun == CAM_LUN_WILDCARD) {
3352 warnx("invalid lun number %jx", (uintmax_t)lun);
3358 bzero(&ccb, sizeof(union ccb));
3361 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3362 warnx("error opening transport layer device %s\n",
3364 warn("%s", XPT_DEVICE);
3368 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3369 if (device == NULL) {
3370 warnx("%s", cam_errbuf);
3375 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3376 ccb.ccb_h.path_id = bus;
3377 ccb.ccb_h.target_id = target;
3378 ccb.ccb_h.target_lun = lun;
3379 ccb.ccb_h.timeout = 5000;
3380 ccb.crcn.flags = CAM_FLAG_NONE;
3382 /* run this at a low priority */
3383 ccb.ccb_h.pinfo.priority = 5;
3386 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3387 warn("CAMIOCOMMAND ioctl failed");
3392 if (cam_send_ccb(device, &ccb) < 0) {
3393 warn("error sending XPT_RESET_DEV CCB");
3394 cam_close_device(device);
3402 cam_close_device(device);
3405 * An error code of CAM_BDR_SENT is normal for a BDR request.
3407 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3409 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3410 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3411 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3414 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3415 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3416 ccb.ccb_h.status & CAM_STATUS_MASK);
3421 #ifndef MINIMALISTIC
3423 static struct scsi_nv defect_list_type_map[] = {
3424 { "block", SRDD10_BLOCK_FORMAT },
3425 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3426 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3427 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3428 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3429 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3433 readdefects(struct cam_device *device, int argc, char **argv,
3434 char *combinedopt, int task_attr, int retry_count, int timeout)
3436 union ccb *ccb = NULL;
3437 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3438 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3439 size_t hdr_size = 0, entry_size = 0;
3442 u_int8_t *defect_list = NULL;
3443 u_int8_t list_format = 0;
3444 int list_type_set = 0;
3445 u_int32_t dlist_length = 0;
3446 u_int32_t returned_length = 0, valid_len = 0;
3447 u_int32_t num_returned = 0, num_valid = 0;
3448 u_int32_t max_possible_size = 0, hdr_max = 0;
3449 u_int32_t starting_offset = 0;
3450 u_int8_t returned_format, returned_type;
3452 int summary = 0, quiet = 0;
3454 int lists_specified = 0;
3455 int get_length = 1, first_pass = 1;
3458 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3462 scsi_nv_status status;
3465 status = scsi_get_nv(defect_list_type_map,
3466 sizeof(defect_list_type_map) /
3467 sizeof(defect_list_type_map[0]), optarg,
3468 &entry_num, SCSI_NV_FLAG_IG_CASE);
3470 if (status == SCSI_NV_FOUND) {
3471 list_format = defect_list_type_map[
3475 warnx("%s: %s %s option %s", __func__,
3476 (status == SCSI_NV_AMBIGUOUS) ?
3477 "ambiguous" : "invalid", "defect list type",
3480 goto defect_bailout;
3485 arglist |= CAM_ARG_GLIST;
3488 arglist |= CAM_ARG_PLIST;
3499 starting_offset = strtoul(optarg, &endptr, 0);
3500 if (*endptr != '\0') {
3502 warnx("invalid starting offset %s", optarg);
3503 goto defect_bailout;
3515 if (list_type_set == 0) {
3517 warnx("no defect list format specified");
3518 goto defect_bailout;
3521 if (arglist & CAM_ARG_PLIST) {
3522 list_format |= SRDD10_PLIST;
3526 if (arglist & CAM_ARG_GLIST) {
3527 list_format |= SRDD10_GLIST;
3532 * This implies a summary, and was the previous behavior.
3534 if (lists_specified == 0)
3537 ccb = cam_getccb(device);
3542 * We start off asking for just the header to determine how much
3543 * defect data is available. Some Hitachi drives return an error
3544 * if you ask for more data than the drive has. Once we know the
3545 * length, we retry the command with the returned length.
3547 if (use_12byte == 0)
3548 dlist_length = sizeof(*hdr10);
3550 dlist_length = sizeof(*hdr12);
3553 if (defect_list != NULL) {
3557 defect_list = malloc(dlist_length);
3558 if (defect_list == NULL) {
3559 warnx("can't malloc memory for defect list");
3561 goto defect_bailout;
3565 bzero(defect_list, dlist_length);
3568 * cam_getccb() zeros the CCB header only. So we need to zero the
3569 * payload portion of the ccb.
3571 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3573 scsi_read_defects(&ccb->csio,
3574 /*retries*/ retry_count,
3576 /*tag_action*/ task_attr,
3577 /*list_format*/ list_format,
3578 /*addr_desc_index*/ starting_offset,
3579 /*data_ptr*/ defect_list,
3580 /*dxfer_len*/ dlist_length,
3581 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3582 /*sense_len*/ SSD_FULL_SIZE,
3583 /*timeout*/ timeout ? timeout : 5000);
3585 /* Disable freezing the device queue */
3586 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3588 if (cam_send_ccb(device, ccb) < 0) {
3589 perror("error reading defect list");
3591 if (arglist & CAM_ARG_VERBOSE) {
3592 cam_error_print(device, ccb, CAM_ESF_ALL,
3593 CAM_EPF_ALL, stderr);
3597 goto defect_bailout;
3600 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3602 if (use_12byte == 0) {
3603 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3604 hdr_size = sizeof(*hdr10);
3605 hdr_max = SRDDH10_MAX_LENGTH;
3607 if (valid_len >= hdr_size) {
3608 returned_length = scsi_2btoul(hdr10->length);
3609 returned_format = hdr10->format;
3611 returned_length = 0;
3612 returned_format = 0;
3615 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3616 hdr_size = sizeof(*hdr12);
3617 hdr_max = SRDDH12_MAX_LENGTH;
3619 if (valid_len >= hdr_size) {
3620 returned_length = scsi_4btoul(hdr12->length);
3621 returned_format = hdr12->format;
3623 returned_length = 0;
3624 returned_format = 0;
3628 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3629 switch (returned_type) {
3630 case SRDD10_BLOCK_FORMAT:
3631 entry_size = sizeof(struct scsi_defect_desc_block);
3633 case SRDD10_LONG_BLOCK_FORMAT:
3634 entry_size = sizeof(struct scsi_defect_desc_long_block);
3636 case SRDD10_EXT_PHYS_FORMAT:
3637 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3638 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3640 case SRDD10_EXT_BFI_FORMAT:
3641 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3642 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3645 warnx("Unknown defect format 0x%x\n", returned_type);
3647 goto defect_bailout;
3651 max_possible_size = (hdr_max / entry_size) * entry_size;
3652 num_returned = returned_length / entry_size;
3653 num_valid = min(returned_length, valid_len - hdr_size);
3654 num_valid /= entry_size;
3656 if (get_length != 0) {
3659 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3660 CAM_SCSI_STATUS_ERROR) {
3661 struct scsi_sense_data *sense;
3662 int error_code, sense_key, asc, ascq;
3664 sense = &ccb->csio.sense_data;
3665 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3666 ccb->csio.sense_resid, &error_code, &sense_key,
3667 &asc, &ascq, /*show_errors*/ 1);
3670 * If the drive is reporting that it just doesn't
3671 * support the defect list format, go ahead and use
3672 * the length it reported. Otherwise, the length
3673 * may not be valid, so use the maximum.
3675 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3676 && (asc == 0x1c) && (ascq == 0x00)
3677 && (returned_length > 0)) {
3678 if ((use_12byte == 0)
3679 && (returned_length >= max_possible_size)) {
3684 dlist_length = returned_length + hdr_size;
3685 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3686 && (asc == 0x1f) && (ascq == 0x00)
3687 && (returned_length > 0)) {
3688 /* Partial defect list transfer */
3690 * Hitachi drives return this error
3691 * along with a partial defect list if they
3692 * have more defects than the 10 byte
3693 * command can support. Retry with the 12
3696 if (use_12byte == 0) {
3701 dlist_length = returned_length + hdr_size;
3702 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
3703 && (asc == 0x24) && (ascq == 0x00)) {
3704 /* Invalid field in CDB */
3706 * SBC-3 says that if the drive has more
3707 * defects than can be reported with the
3708 * 10 byte command, it should return this
3709 * error and no data. Retry with the 12
3712 if (use_12byte == 0) {
3717 dlist_length = returned_length + hdr_size;
3720 * If we got a SCSI error and no valid length,
3721 * just use the 10 byte maximum. The 12
3722 * byte maximum is too large.
3724 if (returned_length == 0)
3725 dlist_length = SRDD10_MAX_LENGTH;
3727 if ((use_12byte == 0)
3728 && (returned_length >=
3729 max_possible_size)) {
3734 dlist_length = returned_length +
3738 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3741 warnx("Error reading defect header");
3742 if (arglist & CAM_ARG_VERBOSE)
3743 cam_error_print(device, ccb, CAM_ESF_ALL,
3744 CAM_EPF_ALL, stderr);
3745 goto defect_bailout;
3747 if ((use_12byte == 0)
3748 && (returned_length >= max_possible_size)) {
3753 dlist_length = returned_length + hdr_size;
3756 fprintf(stdout, "%u", num_returned);
3758 fprintf(stdout, " defect%s",
3759 (num_returned != 1) ? "s" : "");
3761 fprintf(stdout, "\n");
3763 goto defect_bailout;
3767 * We always limit the list length to the 10-byte maximum
3768 * length (0xffff). The reason is that some controllers
3769 * can't handle larger I/Os, and we can transfer the entire
3770 * 10 byte list in one shot. For drives that support the 12
3771 * byte read defects command, we'll step through the list
3772 * by specifying a starting offset. For drives that don't
3773 * support the 12 byte command's starting offset, we'll
3774 * just display the first 64K.
3776 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3782 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3783 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3784 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3785 struct scsi_sense_data *sense;
3786 int error_code, sense_key, asc, ascq;
3788 sense = &ccb->csio.sense_data;
3789 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3790 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3791 &ascq, /*show_errors*/ 1);
3794 * According to the SCSI spec, if the disk doesn't support
3795 * the requested format, it will generally return a sense
3796 * key of RECOVERED ERROR, and an additional sense code
3797 * of "DEFECT LIST NOT FOUND". HGST drives also return
3798 * Primary/Grown defect list not found errors. So just
3799 * check for an ASC of 0x1c.
3801 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3803 const char *format_str;
3805 format_str = scsi_nv_to_str(defect_list_type_map,
3806 sizeof(defect_list_type_map) /
3807 sizeof(defect_list_type_map[0]),
3808 list_format & SRDD10_DLIST_FORMAT_MASK);
3809 warnx("requested defect format %s not available",
3810 format_str ? format_str : "unknown");
3812 format_str = scsi_nv_to_str(defect_list_type_map,
3813 sizeof(defect_list_type_map) /
3814 sizeof(defect_list_type_map[0]), returned_type);
3815 if (format_str != NULL) {
3816 warnx("Device returned %s format",
3820 warnx("Device returned unknown defect"
3821 " data format %#x", returned_type);
3822 goto defect_bailout;
3826 warnx("Error returned from read defect data command");
3827 if (arglist & CAM_ARG_VERBOSE)
3828 cam_error_print(device, ccb, CAM_ESF_ALL,
3829 CAM_EPF_ALL, stderr);
3830 goto defect_bailout;
3832 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3834 warnx("Error returned from read defect data command");
3835 if (arglist & CAM_ARG_VERBOSE)
3836 cam_error_print(device, ccb, CAM_ESF_ALL,
3837 CAM_EPF_ALL, stderr);
3838 goto defect_bailout;
3841 if (first_pass != 0) {
3842 fprintf(stderr, "Got %d defect", num_returned);
3844 if ((lists_specified == 0) || (num_returned == 0)) {
3845 fprintf(stderr, "s.\n");
3846 goto defect_bailout;
3847 } else if (num_returned == 1)
3848 fprintf(stderr, ":\n");
3850 fprintf(stderr, "s:\n");
3856 * XXX KDM I should probably clean up the printout format for the
3859 switch (returned_type) {
3860 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3861 case SRDD10_EXT_PHYS_FORMAT:
3863 struct scsi_defect_desc_phys_sector *dlist;
3865 dlist = (struct scsi_defect_desc_phys_sector *)
3866 (defect_list + hdr_size);
3868 for (i = 0; i < num_valid; i++) {
3871 sector = scsi_4btoul(dlist[i].sector);
3872 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
3873 mads = (sector & SDD_EXT_PHYS_MADS) ?
3875 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
3877 if (hex_format == 0)
3878 fprintf(stdout, "%d:%d:%d%s",
3879 scsi_3btoul(dlist[i].cylinder),
3881 scsi_4btoul(dlist[i].sector),
3882 mads ? " - " : "\n");
3884 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3885 scsi_3btoul(dlist[i].cylinder),
3887 scsi_4btoul(dlist[i].sector),
3888 mads ? " - " : "\n");
3891 if (num_valid < num_returned) {
3892 starting_offset += num_valid;
3897 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3898 case SRDD10_EXT_BFI_FORMAT:
3900 struct scsi_defect_desc_bytes_from_index *dlist;
3902 dlist = (struct scsi_defect_desc_bytes_from_index *)
3903 (defect_list + hdr_size);
3905 for (i = 0; i < num_valid; i++) {
3908 bfi = scsi_4btoul(dlist[i].bytes_from_index);
3909 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
3910 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
3911 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
3913 if (hex_format == 0)
3914 fprintf(stdout, "%d:%d:%d%s",
3915 scsi_3btoul(dlist[i].cylinder),
3917 scsi_4btoul(dlist[i].bytes_from_index),
3918 mads ? " - " : "\n");
3920 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3921 scsi_3btoul(dlist[i].cylinder),
3923 scsi_4btoul(dlist[i].bytes_from_index),
3924 mads ? " - " : "\n");
3928 if (num_valid < num_returned) {
3929 starting_offset += num_valid;
3934 case SRDDH10_BLOCK_FORMAT:
3936 struct scsi_defect_desc_block *dlist;
3938 dlist = (struct scsi_defect_desc_block *)
3939 (defect_list + hdr_size);
3941 for (i = 0; i < num_valid; i++) {
3942 if (hex_format == 0)
3943 fprintf(stdout, "%u\n",
3944 scsi_4btoul(dlist[i].address));
3946 fprintf(stdout, "0x%x\n",
3947 scsi_4btoul(dlist[i].address));
3950 if (num_valid < num_returned) {
3951 starting_offset += num_valid;
3957 case SRDD10_LONG_BLOCK_FORMAT:
3959 struct scsi_defect_desc_long_block *dlist;
3961 dlist = (struct scsi_defect_desc_long_block *)
3962 (defect_list + hdr_size);
3964 for (i = 0; i < num_valid; i++) {
3965 if (hex_format == 0)
3966 fprintf(stdout, "%ju\n",
3967 (uintmax_t)scsi_8btou64(
3970 fprintf(stdout, "0x%jx\n",
3971 (uintmax_t)scsi_8btou64(
3975 if (num_valid < num_returned) {
3976 starting_offset += num_valid;
3982 fprintf(stderr, "Unknown defect format 0x%x\n",
3989 if (defect_list != NULL)
3997 #endif /* MINIMALISTIC */
4001 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4005 ccb = cam_getccb(device);
4011 #ifndef MINIMALISTIC
4013 mode_sense(struct cam_device *device, int dbd, int pc, int page, int subpage,
4014 int task_attr, int retry_count, int timeout, u_int8_t *data,
4020 ccb = cam_getccb(device);
4023 errx(1, "mode_sense: couldn't allocate CCB");
4025 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4027 scsi_mode_sense_subpage(&ccb->csio,
4028 /* retries */ retry_count,
4030 /* tag_action */ task_attr,
4034 /* subpage */ subpage,
4035 /* param_buf */ data,
4036 /* param_len */ datalen,
4037 /* minimum_cmd_size */ 0,
4038 /* sense_len */ SSD_FULL_SIZE,
4039 /* timeout */ timeout ? timeout : 5000);
4041 if (arglist & CAM_ARG_ERR_RECOVER)
4042 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4044 /* Disable freezing the device queue */
4045 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4047 if (((retval = cam_send_ccb(device, ccb)) < 0)
4048 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4049 if (arglist & CAM_ARG_VERBOSE) {
4050 cam_error_print(device, ccb, CAM_ESF_ALL,
4051 CAM_EPF_ALL, stderr);
4054 cam_close_device(device);
4056 err(1, "error sending mode sense command");
4058 errx(1, "error sending mode sense command");
4065 mode_select(struct cam_device *device, int save_pages, int task_attr,
4066 int retry_count, int timeout, u_int8_t *data, int datalen)
4071 ccb = cam_getccb(device);
4074 errx(1, "mode_select: couldn't allocate CCB");
4076 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4078 scsi_mode_select(&ccb->csio,
4079 /* retries */ retry_count,
4081 /* tag_action */ task_attr,
4082 /* scsi_page_fmt */ 1,
4083 /* save_pages */ save_pages,
4084 /* param_buf */ data,
4085 /* param_len */ datalen,
4086 /* sense_len */ SSD_FULL_SIZE,
4087 /* timeout */ timeout ? timeout : 5000);
4089 if (arglist & CAM_ARG_ERR_RECOVER)
4090 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4092 /* Disable freezing the device queue */
4093 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4095 if (((retval = cam_send_ccb(device, ccb)) < 0)
4096 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4097 if (arglist & CAM_ARG_VERBOSE) {
4098 cam_error_print(device, ccb, CAM_ESF_ALL,
4099 CAM_EPF_ALL, stderr);
4102 cam_close_device(device);
4105 err(1, "error sending mode select command");
4107 errx(1, "error sending mode select command");
4115 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4116 int task_attr, int retry_count, int timeout)
4119 int c, page = -1, subpage = -1, pc = 0;
4120 int binary = 0, dbd = 0, edit = 0, list = 0;
4122 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4137 str_subpage = optarg;
4138 strsep(&str_subpage, ",");
4139 page = strtol(optarg, NULL, 0);
4141 subpage = strtol(str_subpage, NULL, 0);
4145 errx(1, "invalid mode page %d", page);
4147 errx(1, "invalid mode subpage %d", subpage);
4150 pc = strtol(optarg, NULL, 0);
4151 if ((pc < 0) || (pc > 3))
4152 errx(1, "invalid page control field %d", pc);
4159 if (page == -1 && list == 0)
4160 errx(1, "you must specify a mode page!");
4163 mode_list(device, dbd, pc, list > 1, task_attr, retry_count,
4166 mode_edit(device, dbd, pc, page, subpage, edit, binary,
4167 task_attr, retry_count, timeout);
4172 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4173 int task_attr, int retry_count, int timeout)
4176 u_int32_t flags = CAM_DIR_NONE;
4177 u_int8_t *data_ptr = NULL;
4179 u_int8_t atacmd[12];
4180 struct get_hook hook;
4181 int c, data_bytes = 0, valid_bytes;
4187 char *datastr = NULL, *tstr, *resstr = NULL;
4189 int fd_data = 0, fd_res = 0;
4192 ccb = cam_getccb(device);
4195 warnx("scsicmd: error allocating ccb");
4199 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4201 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4205 while (isspace(*tstr) && (*tstr != '\0'))
4207 hook.argc = argc - optind;
4208 hook.argv = argv + optind;
4210 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4213 * Increment optind by the number of arguments the
4214 * encoding routine processed. After each call to
4215 * getopt(3), optind points to the argument that
4216 * getopt should process _next_. In this case,
4217 * that means it points to the first command string
4218 * argument, if there is one. Once we increment
4219 * this, it should point to either the next command
4220 * line argument, or it should be past the end of
4227 while (isspace(*tstr) && (*tstr != '\0'))
4229 hook.argc = argc - optind;
4230 hook.argv = argv + optind;
4232 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4235 * Increment optind by the number of arguments the
4236 * encoding routine processed. After each call to
4237 * getopt(3), optind points to the argument that
4238 * getopt should process _next_. In this case,
4239 * that means it points to the first command string
4240 * argument, if there is one. Once we increment
4241 * this, it should point to either the next command
4242 * line argument, or it should be past the end of
4254 if (arglist & CAM_ARG_CMD_OUT) {
4255 warnx("command must either be "
4256 "read or write, not both");
4258 goto scsicmd_bailout;
4260 arglist |= CAM_ARG_CMD_IN;
4262 data_bytes = strtol(optarg, NULL, 0);
4263 if (data_bytes <= 0) {
4264 warnx("invalid number of input bytes %d",
4267 goto scsicmd_bailout;
4269 hook.argc = argc - optind;
4270 hook.argv = argv + optind;
4273 datastr = cget(&hook, NULL);
4275 * If the user supplied "-" instead of a format, he
4276 * wants the data to be written to stdout.
4278 if ((datastr != NULL)
4279 && (datastr[0] == '-'))
4282 data_ptr = (u_int8_t *)malloc(data_bytes);
4283 if (data_ptr == NULL) {
4284 warnx("can't malloc memory for data_ptr");
4286 goto scsicmd_bailout;
4290 if (arglist & CAM_ARG_CMD_IN) {
4291 warnx("command must either be "
4292 "read or write, not both");
4294 goto scsicmd_bailout;
4296 arglist |= CAM_ARG_CMD_OUT;
4297 flags = CAM_DIR_OUT;
4298 data_bytes = strtol(optarg, NULL, 0);
4299 if (data_bytes <= 0) {
4300 warnx("invalid number of output bytes %d",
4303 goto scsicmd_bailout;
4305 hook.argc = argc - optind;
4306 hook.argv = argv + optind;
4308 datastr = cget(&hook, NULL);
4309 data_ptr = (u_int8_t *)malloc(data_bytes);
4310 if (data_ptr == NULL) {
4311 warnx("can't malloc memory for data_ptr");
4313 goto scsicmd_bailout;
4315 bzero(data_ptr, data_bytes);
4317 * If the user supplied "-" instead of a format, he
4318 * wants the data to be read from stdin.
4320 if ((datastr != NULL)
4321 && (datastr[0] == '-'))
4324 buff_encode_visit(data_ptr, data_bytes, datastr,
4330 hook.argc = argc - optind;
4331 hook.argv = argv + optind;
4333 resstr = cget(&hook, NULL);
4334 if ((resstr != NULL) && (resstr[0] == '-'))
4344 * If fd_data is set, and we're writing to the device, we need to
4345 * read the data the user wants written from stdin.
4347 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4349 int amt_to_read = data_bytes;
4350 u_int8_t *buf_ptr = data_ptr;
4352 for (amt_read = 0; amt_to_read > 0;
4353 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4354 if (amt_read == -1) {
4355 warn("error reading data from stdin");
4357 goto scsicmd_bailout;
4359 amt_to_read -= amt_read;
4360 buf_ptr += amt_read;
4364 if (arglist & CAM_ARG_ERR_RECOVER)
4365 flags |= CAM_PASS_ERR_RECOVER;
4367 /* Disable freezing the device queue */
4368 flags |= CAM_DEV_QFRZDIS;
4372 * This is taken from the SCSI-3 draft spec.
4373 * (T10/1157D revision 0.3)
4374 * The top 3 bits of an opcode are the group code.
4375 * The next 5 bits are the command code.
4376 * Group 0: six byte commands
4377 * Group 1: ten byte commands
4378 * Group 2: ten byte commands
4380 * Group 4: sixteen byte commands
4381 * Group 5: twelve byte commands
4382 * Group 6: vendor specific
4383 * Group 7: vendor specific
4385 switch((cdb[0] >> 5) & 0x7) {
4396 /* computed by buff_encode_visit */
4407 * We should probably use csio_build_visit or something like that
4408 * here, but it's easier to encode arguments as you go. The
4409 * alternative would be skipping the CDB argument and then encoding
4410 * it here, since we've got the data buffer argument by now.
4412 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4414 cam_fill_csio(&ccb->csio,
4415 /*retries*/ retry_count,
4418 /*tag_action*/ task_attr,
4419 /*data_ptr*/ data_ptr,
4420 /*dxfer_len*/ data_bytes,
4421 /*sense_len*/ SSD_FULL_SIZE,
4422 /*cdb_len*/ cdb_len,
4423 /*timeout*/ timeout ? timeout : 5000);
4426 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4428 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4430 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4432 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4434 cam_fill_ataio(&ccb->ataio,
4435 /*retries*/ retry_count,
4439 /*data_ptr*/ data_ptr,
4440 /*dxfer_len*/ data_bytes,
4441 /*timeout*/ timeout ? timeout : 5000);
4444 if (((retval = cam_send_ccb(device, ccb)) < 0)
4445 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4446 const char warnstr[] = "error sending command";
4453 if (arglist & CAM_ARG_VERBOSE) {
4454 cam_error_print(device, ccb, CAM_ESF_ALL,
4455 CAM_EPF_ALL, stderr);
4459 goto scsicmd_bailout;
4462 if (atacmd_len && need_res) {
4464 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4466 fprintf(stdout, "\n");
4469 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4470 ccb->ataio.res.status,
4471 ccb->ataio.res.error,
4472 ccb->ataio.res.lba_low,
4473 ccb->ataio.res.lba_mid,
4474 ccb->ataio.res.lba_high,
4475 ccb->ataio.res.device,
4476 ccb->ataio.res.lba_low_exp,
4477 ccb->ataio.res.lba_mid_exp,
4478 ccb->ataio.res.lba_high_exp,
4479 ccb->ataio.res.sector_count,
4480 ccb->ataio.res.sector_count_exp);
4486 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4488 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4489 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4490 && (arglist & CAM_ARG_CMD_IN)
4491 && (valid_bytes > 0)) {
4493 buff_decode_visit(data_ptr, valid_bytes, datastr,
4495 fprintf(stdout, "\n");
4497 ssize_t amt_written;
4498 int amt_to_write = valid_bytes;
4499 u_int8_t *buf_ptr = data_ptr;
4501 for (amt_written = 0; (amt_to_write > 0) &&
4502 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4503 amt_to_write -= amt_written;
4504 buf_ptr += amt_written;
4506 if (amt_written == -1) {
4507 warn("error writing data to stdout");
4509 goto scsicmd_bailout;
4510 } else if ((amt_written == 0)
4511 && (amt_to_write > 0)) {
4512 warnx("only wrote %u bytes out of %u",
4513 valid_bytes - amt_to_write, valid_bytes);
4520 if ((data_bytes > 0) && (data_ptr != NULL))
4529 camdebug(int argc, char **argv, char *combinedopt)
4532 path_id_t bus = CAM_BUS_WILDCARD;
4533 target_id_t target = CAM_TARGET_WILDCARD;
4534 lun_id_t lun = CAM_LUN_WILDCARD;
4535 char *tstr, *tmpstr = NULL;
4539 bzero(&ccb, sizeof(union ccb));
4541 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4544 arglist |= CAM_ARG_DEBUG_INFO;
4545 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4548 arglist |= CAM_ARG_DEBUG_PERIPH;
4549 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4552 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4553 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4556 arglist |= CAM_ARG_DEBUG_TRACE;
4557 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4560 arglist |= CAM_ARG_DEBUG_XPT;
4561 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4564 arglist |= CAM_ARG_DEBUG_CDB;
4565 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4568 arglist |= CAM_ARG_DEBUG_PROBE;
4569 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4576 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4577 warnx("error opening transport layer device %s", XPT_DEVICE);
4578 warn("%s", XPT_DEVICE);
4585 warnx("you must specify \"off\", \"all\" or a bus,");
4586 warnx("bus:target, or bus:target:lun");
4593 while (isspace(*tstr) && (*tstr != '\0'))
4596 if (strncmp(tstr, "off", 3) == 0) {
4597 ccb.cdbg.flags = CAM_DEBUG_NONE;
4598 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4599 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4600 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4601 } else if (strncmp(tstr, "all", 3) != 0) {
4602 tmpstr = (char *)strtok(tstr, ":");
4603 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4604 bus = strtol(tmpstr, NULL, 0);
4605 arglist |= CAM_ARG_BUS;
4606 tmpstr = (char *)strtok(NULL, ":");
4607 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4608 target = strtol(tmpstr, NULL, 0);
4609 arglist |= CAM_ARG_TARGET;
4610 tmpstr = (char *)strtok(NULL, ":");
4611 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4612 lun = strtol(tmpstr, NULL, 0);
4613 arglist |= CAM_ARG_LUN;
4618 warnx("you must specify \"all\", \"off\", or a bus,");
4619 warnx("bus:target, or bus:target:lun to debug");
4625 ccb.ccb_h.func_code = XPT_DEBUG;
4626 ccb.ccb_h.path_id = bus;
4627 ccb.ccb_h.target_id = target;
4628 ccb.ccb_h.target_lun = lun;
4630 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4631 warn("CAMIOCOMMAND ioctl failed");
4636 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4637 CAM_FUNC_NOTAVAIL) {
4638 warnx("CAM debugging not available");
4639 warnx("you need to put options CAMDEBUG in"
4640 " your kernel config file!");
4642 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4644 warnx("XPT_DEBUG CCB failed with status %#x",
4648 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4650 "Debugging turned off\n");
4653 "Debugging enabled for "
4655 bus, target, (uintmax_t)lun);
4666 tagcontrol(struct cam_device *device, int argc, char **argv,
4676 ccb = cam_getccb(device);
4679 warnx("tagcontrol: error allocating ccb");
4683 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4686 numtags = strtol(optarg, NULL, 0);
4688 warnx("tag count %d is < 0", numtags);
4690 goto tagcontrol_bailout;
4701 cam_path_string(device, pathstr, sizeof(pathstr));
4704 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
4705 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4706 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4707 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4708 ccb->crs.openings = numtags;
4711 if (cam_send_ccb(device, ccb) < 0) {
4712 perror("error sending XPT_REL_SIMQ CCB");
4714 goto tagcontrol_bailout;
4717 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4718 warnx("XPT_REL_SIMQ CCB failed");
4719 cam_error_print(device, ccb, CAM_ESF_ALL,
4720 CAM_EPF_ALL, stderr);
4722 goto tagcontrol_bailout;
4727 fprintf(stdout, "%stagged openings now %d\n",
4728 pathstr, ccb->crs.openings);
4731 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
4733 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4735 if (cam_send_ccb(device, ccb) < 0) {
4736 perror("error sending XPT_GDEV_STATS CCB");
4738 goto tagcontrol_bailout;
4741 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4742 warnx("XPT_GDEV_STATS CCB failed");
4743 cam_error_print(device, ccb, CAM_ESF_ALL,
4744 CAM_EPF_ALL, stderr);
4746 goto tagcontrol_bailout;
4749 if (arglist & CAM_ARG_VERBOSE) {
4750 fprintf(stdout, "%s", pathstr);
4751 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4752 fprintf(stdout, "%s", pathstr);
4753 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4754 fprintf(stdout, "%s", pathstr);
4755 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
4756 fprintf(stdout, "%s", pathstr);
4757 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
4758 fprintf(stdout, "%s", pathstr);
4759 fprintf(stdout, "held %d\n", ccb->cgds.held);
4760 fprintf(stdout, "%s", pathstr);
4761 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4762 fprintf(stdout, "%s", pathstr);
4763 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4766 fprintf(stdout, "%s", pathstr);
4767 fprintf(stdout, "device openings: ");
4769 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4770 ccb->cgds.dev_active);
4780 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4784 cam_path_string(device, pathstr, sizeof(pathstr));
4786 if (cts->transport == XPORT_SPI) {
4787 struct ccb_trans_settings_spi *spi =
4788 &cts->xport_specific.spi;
4790 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4792 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4795 if (spi->sync_offset != 0) {
4798 freq = scsi_calc_syncsrate(spi->sync_period);
4799 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4800 pathstr, freq / 1000, freq % 1000);
4804 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4805 fprintf(stdout, "%soffset: %d\n", pathstr,
4809 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4810 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4811 (0x01 << spi->bus_width) * 8);
4814 if (spi->valid & CTS_SPI_VALID_DISC) {
4815 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4816 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4817 "enabled" : "disabled");
4820 if (cts->transport == XPORT_FC) {
4821 struct ccb_trans_settings_fc *fc =
4822 &cts->xport_specific.fc;
4824 if (fc->valid & CTS_FC_VALID_WWNN)
4825 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
4826 (long long) fc->wwnn);
4827 if (fc->valid & CTS_FC_VALID_WWPN)
4828 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
4829 (long long) fc->wwpn);
4830 if (fc->valid & CTS_FC_VALID_PORT)
4831 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
4832 if (fc->valid & CTS_FC_VALID_SPEED)
4833 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4834 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4836 if (cts->transport == XPORT_SAS) {
4837 struct ccb_trans_settings_sas *sas =
4838 &cts->xport_specific.sas;
4840 if (sas->valid & CTS_SAS_VALID_SPEED)
4841 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4842 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4844 if (cts->transport == XPORT_ATA) {
4845 struct ccb_trans_settings_pata *pata =
4846 &cts->xport_specific.ata;
4848 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4849 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4850 ata_mode2string(pata->mode));
4852 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4853 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4856 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4857 fprintf(stdout, "%sPIO transaction length: %d\n",
4858 pathstr, pata->bytecount);
4861 if (cts->transport == XPORT_SATA) {
4862 struct ccb_trans_settings_sata *sata =
4863 &cts->xport_specific.sata;
4865 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4866 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4869 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4870 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4871 ata_mode2string(sata->mode));
4873 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4874 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4877 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4878 fprintf(stdout, "%sPIO transaction length: %d\n",
4879 pathstr, sata->bytecount);
4881 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4882 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4885 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4886 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4889 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4890 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
4894 if (cts->protocol == PROTO_ATA) {
4895 struct ccb_trans_settings_ata *ata=
4896 &cts->proto_specific.ata;
4898 if (ata->valid & CTS_ATA_VALID_TQ) {
4899 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4900 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
4901 "enabled" : "disabled");
4904 if (cts->protocol == PROTO_SCSI) {
4905 struct ccb_trans_settings_scsi *scsi=
4906 &cts->proto_specific.scsi;
4908 if (scsi->valid & CTS_SCSI_VALID_TQ) {
4909 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
4910 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
4911 "enabled" : "disabled");
4918 * Get a path inquiry CCB for the specified device.
4921 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
4926 ccb = cam_getccb(device);
4928 warnx("get_cpi: couldn't allocate CCB");
4931 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
4932 ccb->ccb_h.func_code = XPT_PATH_INQ;
4933 if (cam_send_ccb(device, ccb) < 0) {
4934 warn("get_cpi: error sending Path Inquiry CCB");
4935 if (arglist & CAM_ARG_VERBOSE)
4936 cam_error_print(device, ccb, CAM_ESF_ALL,
4937 CAM_EPF_ALL, stderr);
4939 goto get_cpi_bailout;
4941 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4942 if (arglist & CAM_ARG_VERBOSE)
4943 cam_error_print(device, ccb, CAM_ESF_ALL,
4944 CAM_EPF_ALL, stderr);
4946 goto get_cpi_bailout;
4948 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
4956 * Get a get device CCB for the specified device.
4959 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
4964 ccb = cam_getccb(device);
4966 warnx("get_cgd: couldn't allocate CCB");
4969 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
4970 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
4971 if (cam_send_ccb(device, ccb) < 0) {
4972 warn("get_cgd: error sending Path Inquiry CCB");
4973 if (arglist & CAM_ARG_VERBOSE)
4974 cam_error_print(device, ccb, CAM_ESF_ALL,
4975 CAM_EPF_ALL, stderr);
4977 goto get_cgd_bailout;
4979 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4980 if (arglist & CAM_ARG_VERBOSE)
4981 cam_error_print(device, ccb, CAM_ESF_ALL,
4982 CAM_EPF_ALL, stderr);
4984 goto get_cgd_bailout;
4986 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
4994 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
4998 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
4999 int timeout, int verbosemode)
5001 union ccb *ccb = NULL;
5002 struct scsi_vpd_supported_page_list sup_pages;
5006 ccb = cam_getccb(dev);
5008 warn("Unable to allocate CCB");
5013 /* cam_getccb cleans up the header, caller has to zero the payload */
5014 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5016 bzero(&sup_pages, sizeof(sup_pages));
5018 scsi_inquiry(&ccb->csio,
5019 /*retries*/ retry_count,
5021 /* tag_action */ MSG_SIMPLE_Q_TAG,
5022 /* inq_buf */ (u_int8_t *)&sup_pages,
5023 /* inq_len */ sizeof(sup_pages),
5025 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5026 /* sense_len */ SSD_FULL_SIZE,
5027 /* timeout */ timeout ? timeout : 5000);
5029 /* Disable freezing the device queue */
5030 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5032 if (retry_count != 0)
5033 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5035 if (cam_send_ccb(dev, ccb) < 0) {
5042 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5043 if (verbosemode != 0)
5044 cam_error_print(dev, ccb, CAM_ESF_ALL,
5045 CAM_EPF_ALL, stderr);
5050 for (i = 0; i < sup_pages.length; i++) {
5051 if (sup_pages.list[i] == page_id) {
5064 * devtype is filled in with the type of device.
5065 * Returns 0 for success, non-zero for failure.
5068 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5069 int verbosemode, camcontrol_devtype *devtype)
5071 struct ccb_getdev cgd;
5074 retval = get_cgd(dev, &cgd);
5078 switch (cgd.protocol) {
5084 *devtype = CC_DT_ATA;
5086 break; /*NOTREACHED*/
5088 *devtype = CC_DT_UNKNOWN;
5090 break; /*NOTREACHED*/
5094 * Check for the ATA Information VPD page (0x89). If this is an
5095 * ATA device behind a SCSI to ATA translation layer, this VPD page
5096 * should be present.
5098 * If that VPD page isn't present, or we get an error back from the
5099 * INQUIRY command, we'll just treat it as a normal SCSI device.
5101 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5102 timeout, verbosemode);
5104 *devtype = CC_DT_ATA_BEHIND_SCSI;
5106 *devtype = CC_DT_SCSI;
5115 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5116 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5117 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5118 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5119 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5120 int is48bit, camcontrol_devtype devtype)
5124 if (devtype == CC_DT_ATA) {
5125 cam_fill_ataio(&ccb->ataio,
5126 /*retries*/ retry_count,
5129 /*tag_action*/ tag_action,
5130 /*data_ptr*/ data_ptr,
5131 /*dxfer_len*/ dxfer_len,
5132 /*timeout*/ timeout);
5133 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5134 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5137 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5140 if (auxiliary != 0) {
5141 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5142 ccb->ataio.aux = auxiliary;
5145 if (ata_flags & AP_FLAG_CHK_COND)
5146 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5148 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5149 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5150 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5151 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5153 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5154 protocol |= AP_EXTEND;
5156 retval = scsi_ata_pass(&ccb->csio,
5157 /*retries*/ retry_count,
5160 /*tag_action*/ tag_action,
5161 /*protocol*/ protocol,
5162 /*ata_flags*/ ata_flags,
5163 /*features*/ features,
5164 /*sector_count*/ sector_count,
5166 /*command*/ command,
5169 /*auxiliary*/ auxiliary,
5171 /*data_ptr*/ data_ptr,
5172 /*dxfer_len*/ dxfer_len,
5173 /*cdb_storage*/ cdb_storage,
5174 /*cdb_storage_len*/ cdb_storage_len,
5175 /*minimum_cmd_size*/ 0,
5176 /*sense_len*/ sense_len,
5177 /*timeout*/ timeout);
5184 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5185 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5189 switch (ccb->ccb_h.func_code) {
5192 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5195 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5196 * or 16 byte, and need to see what
5198 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5199 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5201 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5202 if ((opcode != ATA_PASS_12)
5203 && (opcode != ATA_PASS_16)) {
5205 warnx("%s: unsupported opcode %02x", __func__, opcode);
5209 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5211 /* Note: the _ccb() variant returns 0 for an error */
5218 switch (error_code) {
5219 case SSD_DESC_CURRENT_ERROR:
5220 case SSD_DESC_DEFERRED_ERROR: {
5221 struct scsi_sense_data_desc *sense;
5222 struct scsi_sense_ata_ret_desc *desc;
5225 sense = (struct scsi_sense_data_desc *)
5226 &ccb->csio.sense_data;
5228 desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len -
5229 ccb->csio.sense_resid, SSD_DESC_ATA);
5230 if (desc_ptr == NULL) {
5231 cam_error_print(dev, ccb, CAM_ESF_ALL,
5232 CAM_EPF_ALL, stderr);
5236 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5238 *error = desc->error;
5239 *count = (desc->count_15_8 << 8) |
5241 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5242 ((uint64_t)desc->lba_39_32 << 32) |
5243 ((uint64_t)desc->lba_31_24 << 24) |
5244 (desc->lba_23_16 << 16) |
5245 (desc->lba_15_8 << 8) |
5247 *device = desc->device;
5248 *status = desc->status;
5251 * If the extend bit isn't set, the result is for a
5252 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5253 * command without the extend bit set. This means
5254 * that the device is supposed to return 28-bit
5255 * status. The count field is only 8 bits, and the
5256 * LBA field is only 8 bits.
5258 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5264 case SSD_CURRENT_ERROR:
5265 case SSD_DEFERRED_ERROR: {
5267 struct scsi_sense_data_fixed *sense;
5270 * XXX KDM need to support fixed sense data.
5272 warnx("%s: Fixed sense data not supported yet",
5276 break; /*NOTREACHED*/
5287 struct ata_res *res;
5290 * In this case, we have an ATA command, and we need to
5291 * fill in the requested values from the result register
5294 res = &ccb->ataio.res;
5295 *error = res->error;
5296 *status = res->status;
5297 *device = res->device;
5298 *count = res->sector_count;
5299 *lba = (res->lba_high << 16) |
5300 (res->lba_mid << 8) |
5302 if (res->flags & CAM_ATAIO_48BIT) {
5303 *count |= (res->sector_count_exp << 8);
5304 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5305 ((uint64_t)res->lba_mid_exp << 32) |
5306 ((uint64_t)res->lba_high_exp << 40);
5308 *lba |= (res->device & 0xf) << 24;
5321 cpi_print(struct ccb_pathinq *cpi)
5323 char adapter_str[1024];
5326 snprintf(adapter_str, sizeof(adapter_str),
5327 "%s%d:", cpi->dev_name, cpi->unit_number);
5329 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5332 for (i = 1; i < 0xff; i = i << 1) {
5335 if ((i & cpi->hba_inquiry) == 0)
5338 fprintf(stdout, "%s supports ", adapter_str);
5342 str = "MDP message";
5345 str = "32 bit wide SCSI";
5348 str = "16 bit wide SCSI";
5351 str = "SDTR message";
5354 str = "linked CDBs";
5357 str = "tag queue messages";
5360 str = "soft reset alternative";
5363 str = "SATA Port Multiplier";
5366 str = "unknown PI bit set";
5369 fprintf(stdout, "%s\n", str);
5372 for (i = 1; i < 0xff; i = i << 1) {
5375 if ((i & cpi->hba_misc) == 0)
5378 fprintf(stdout, "%s ", adapter_str);
5382 str = "bus scans from high ID to low ID";
5385 str = "removable devices not included in scan";
5387 case PIM_NOINITIATOR:
5388 str = "initiator role not supported";
5390 case PIM_NOBUSRESET:
5391 str = "user has disabled initial BUS RESET or"
5392 " controller is in target/mixed mode";
5395 str = "do not send 6-byte commands";
5398 str = "scan bus sequentially";
5401 str = "unknown PIM bit set";
5404 fprintf(stdout, "%s\n", str);
5407 for (i = 1; i < 0xff; i = i << 1) {
5410 if ((i & cpi->target_sprt) == 0)
5413 fprintf(stdout, "%s supports ", adapter_str);
5416 str = "target mode processor mode";
5419 str = "target mode phase cog. mode";
5421 case PIT_DISCONNECT:
5422 str = "disconnects in target mode";
5425 str = "terminate I/O message in target mode";
5428 str = "group 6 commands in target mode";
5431 str = "group 7 commands in target mode";
5434 str = "unknown PIT bit set";
5438 fprintf(stdout, "%s\n", str);
5440 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5442 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5444 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5446 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5447 adapter_str, cpi->hpath_id);
5448 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5450 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5451 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5452 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5453 adapter_str, cpi->hba_vendor);
5454 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5455 adapter_str, cpi->hba_device);
5456 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5457 adapter_str, cpi->hba_subvendor);
5458 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5459 adapter_str, cpi->hba_subdevice);
5460 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5461 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5462 if (cpi->base_transfer_speed > 1000)
5463 fprintf(stdout, "%d.%03dMB/sec\n",
5464 cpi->base_transfer_speed / 1000,
5465 cpi->base_transfer_speed % 1000);
5467 fprintf(stdout, "%dKB/sec\n",
5468 (cpi->base_transfer_speed % 1000) * 1000);
5469 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5470 adapter_str, cpi->maxio);
5474 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5475 struct ccb_trans_settings *cts)
5481 ccb = cam_getccb(device);
5484 warnx("get_print_cts: error allocating ccb");
5488 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5490 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5492 if (user_settings == 0)
5493 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5495 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5497 if (cam_send_ccb(device, ccb) < 0) {
5498 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5499 if (arglist & CAM_ARG_VERBOSE)
5500 cam_error_print(device, ccb, CAM_ESF_ALL,
5501 CAM_EPF_ALL, stderr);
5503 goto get_print_cts_bailout;
5506 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5507 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5508 if (arglist & CAM_ARG_VERBOSE)
5509 cam_error_print(device, ccb, CAM_ESF_ALL,
5510 CAM_EPF_ALL, stderr);
5512 goto get_print_cts_bailout;
5516 cts_print(device, &ccb->cts);
5519 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5521 get_print_cts_bailout:
5529 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
5530 int timeout, int argc, char **argv, char *combinedopt)
5534 int user_settings = 0;
5536 int disc_enable = -1, tag_enable = -1;
5539 double syncrate = -1;
5542 int change_settings = 0, send_tur = 0;
5543 struct ccb_pathinq cpi;
5545 ccb = cam_getccb(device);
5547 warnx("ratecontrol: error allocating ccb");
5550 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5559 if (strncasecmp(optarg, "enable", 6) == 0)
5561 else if (strncasecmp(optarg, "disable", 7) == 0)
5564 warnx("-D argument \"%s\" is unknown", optarg);
5566 goto ratecontrol_bailout;
5568 change_settings = 1;
5571 mode = ata_string2mode(optarg);
5573 warnx("unknown mode '%s'", optarg);
5575 goto ratecontrol_bailout;
5577 change_settings = 1;
5580 offset = strtol(optarg, NULL, 0);
5582 warnx("offset value %d is < 0", offset);
5584 goto ratecontrol_bailout;
5586 change_settings = 1;
5592 syncrate = atof(optarg);
5594 warnx("sync rate %f is < 0", syncrate);
5596 goto ratecontrol_bailout;
5598 change_settings = 1;
5601 if (strncasecmp(optarg, "enable", 6) == 0)
5603 else if (strncasecmp(optarg, "disable", 7) == 0)
5606 warnx("-T argument \"%s\" is unknown", optarg);
5608 goto ratecontrol_bailout;
5610 change_settings = 1;
5616 bus_width = strtol(optarg, NULL, 0);
5617 if (bus_width < 0) {
5618 warnx("bus width %d is < 0", bus_width);
5620 goto ratecontrol_bailout;
5622 change_settings = 1;
5628 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5630 * Grab path inquiry information, so we can determine whether
5631 * or not the initiator is capable of the things that the user
5634 ccb->ccb_h.func_code = XPT_PATH_INQ;
5635 if (cam_send_ccb(device, ccb) < 0) {
5636 perror("error sending XPT_PATH_INQ CCB");
5637 if (arglist & CAM_ARG_VERBOSE) {
5638 cam_error_print(device, ccb, CAM_ESF_ALL,
5639 CAM_EPF_ALL, stderr);
5642 goto ratecontrol_bailout;
5644 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5645 warnx("XPT_PATH_INQ CCB failed");
5646 if (arglist & CAM_ARG_VERBOSE) {
5647 cam_error_print(device, ccb, CAM_ESF_ALL,
5648 CAM_EPF_ALL, stderr);
5651 goto ratecontrol_bailout;
5653 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5654 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5656 fprintf(stdout, "%s parameters:\n",
5657 user_settings ? "User" : "Current");
5659 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5661 goto ratecontrol_bailout;
5663 if (arglist & CAM_ARG_VERBOSE)
5666 if (change_settings) {
5667 int didsettings = 0;
5668 struct ccb_trans_settings_spi *spi = NULL;
5669 struct ccb_trans_settings_pata *pata = NULL;
5670 struct ccb_trans_settings_sata *sata = NULL;
5671 struct ccb_trans_settings_ata *ata = NULL;
5672 struct ccb_trans_settings_scsi *scsi = NULL;
5674 if (ccb->cts.transport == XPORT_SPI)
5675 spi = &ccb->cts.xport_specific.spi;
5676 if (ccb->cts.transport == XPORT_ATA)
5677 pata = &ccb->cts.xport_specific.ata;
5678 if (ccb->cts.transport == XPORT_SATA)
5679 sata = &ccb->cts.xport_specific.sata;
5680 if (ccb->cts.protocol == PROTO_ATA)
5681 ata = &ccb->cts.proto_specific.ata;
5682 if (ccb->cts.protocol == PROTO_SCSI)
5683 scsi = &ccb->cts.proto_specific.scsi;
5684 ccb->cts.xport_specific.valid = 0;
5685 ccb->cts.proto_specific.valid = 0;
5686 if (spi && disc_enable != -1) {
5687 spi->valid |= CTS_SPI_VALID_DISC;
5688 if (disc_enable == 0)
5689 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5691 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5694 if (tag_enable != -1) {
5695 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5696 warnx("HBA does not support tagged queueing, "
5697 "so you cannot modify tag settings");
5699 goto ratecontrol_bailout;
5702 ata->valid |= CTS_SCSI_VALID_TQ;
5703 if (tag_enable == 0)
5704 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5706 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5709 scsi->valid |= CTS_SCSI_VALID_TQ;
5710 if (tag_enable == 0)
5711 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5713 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5717 if (spi && offset != -1) {
5718 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5719 warnx("HBA is not capable of changing offset");
5721 goto ratecontrol_bailout;
5723 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5724 spi->sync_offset = offset;
5727 if (spi && syncrate != -1) {
5728 int prelim_sync_period;
5730 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5731 warnx("HBA is not capable of changing "
5734 goto ratecontrol_bailout;
5736 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5738 * The sync rate the user gives us is in MHz.
5739 * We need to translate it into KHz for this
5744 * Next, we calculate a "preliminary" sync period
5745 * in tenths of a nanosecond.
5748 prelim_sync_period = 0;
5750 prelim_sync_period = 10000000 / syncrate;
5752 scsi_calc_syncparam(prelim_sync_period);
5755 if (sata && syncrate != -1) {
5756 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5757 warnx("HBA is not capable of changing "
5760 goto ratecontrol_bailout;
5762 if (!user_settings) {
5763 warnx("You can modify only user rate "
5764 "settings for SATA");
5766 goto ratecontrol_bailout;
5768 sata->revision = ata_speed2revision(syncrate * 100);
5769 if (sata->revision < 0) {
5770 warnx("Invalid rate %f", syncrate);
5772 goto ratecontrol_bailout;
5774 sata->valid |= CTS_SATA_VALID_REVISION;
5777 if ((pata || sata) && mode != -1) {
5778 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5779 warnx("HBA is not capable of changing "
5782 goto ratecontrol_bailout;
5784 if (!user_settings) {
5785 warnx("You can modify only user mode "
5786 "settings for ATA/SATA");
5788 goto ratecontrol_bailout;
5792 pata->valid |= CTS_ATA_VALID_MODE;
5795 sata->valid |= CTS_SATA_VALID_MODE;
5800 * The bus_width argument goes like this:
5804 * Therefore, if you shift the number of bits given on the
5805 * command line right by 4, you should get the correct
5808 if (spi && bus_width != -1) {
5810 * We might as well validate things here with a
5811 * decipherable error message, rather than what
5812 * will probably be an indecipherable error message
5813 * by the time it gets back to us.
5815 if ((bus_width == 16)
5816 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5817 warnx("HBA does not support 16 bit bus width");
5819 goto ratecontrol_bailout;
5820 } else if ((bus_width == 32)
5821 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5822 warnx("HBA does not support 32 bit bus width");
5824 goto ratecontrol_bailout;
5825 } else if ((bus_width != 8)
5826 && (bus_width != 16)
5827 && (bus_width != 32)) {
5828 warnx("Invalid bus width %d", bus_width);
5830 goto ratecontrol_bailout;
5832 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5833 spi->bus_width = bus_width >> 4;
5836 if (didsettings == 0) {
5837 goto ratecontrol_bailout;
5839 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5840 if (cam_send_ccb(device, ccb) < 0) {
5841 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5842 if (arglist & CAM_ARG_VERBOSE) {
5843 cam_error_print(device, ccb, CAM_ESF_ALL,
5844 CAM_EPF_ALL, stderr);
5847 goto ratecontrol_bailout;
5849 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5850 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5851 if (arglist & CAM_ARG_VERBOSE) {
5852 cam_error_print(device, ccb, CAM_ESF_ALL,
5853 CAM_EPF_ALL, stderr);
5856 goto ratecontrol_bailout;
5860 retval = testunitready(device, task_attr, retry_count, timeout,
5861 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5863 * If the TUR didn't succeed, just bail.
5867 fprintf(stderr, "Test Unit Ready failed\n");
5868 goto ratecontrol_bailout;
5871 if ((change_settings || send_tur) && !quiet &&
5872 (ccb->cts.transport == XPORT_ATA ||
5873 ccb->cts.transport == XPORT_SATA || send_tur)) {
5874 fprintf(stdout, "New parameters:\n");
5875 retval = get_print_cts(device, user_settings, 0, NULL);
5878 ratecontrol_bailout:
5884 scsiformat(struct cam_device *device, int argc, char **argv,
5885 char *combinedopt, int task_attr, int retry_count, int timeout)
5889 int ycount = 0, quiet = 0;
5890 int error = 0, retval = 0;
5891 int use_timeout = 10800 * 1000;
5893 struct format_defect_list_header fh;
5894 u_int8_t *data_ptr = NULL;
5895 u_int32_t dxfer_len = 0;
5897 int num_warnings = 0;
5900 ccb = cam_getccb(device);
5903 warnx("scsiformat: error allocating ccb");
5907 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5909 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5930 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5931 "following device:\n");
5933 error = scsidoinquiry(device, argc, argv, combinedopt,
5934 task_attr, retry_count, timeout);
5937 warnx("scsiformat: error sending inquiry");
5938 goto scsiformat_bailout;
5943 if (!get_confirmation()) {
5945 goto scsiformat_bailout;
5950 use_timeout = timeout;
5953 fprintf(stdout, "Current format timeout is %d seconds\n",
5954 use_timeout / 1000);
5958 * If the user hasn't disabled questions and didn't specify a
5959 * timeout on the command line, ask them if they want the current
5963 && (timeout == 0)) {
5965 int new_timeout = 0;
5967 fprintf(stdout, "Enter new timeout in seconds or press\n"
5968 "return to keep the current timeout [%d] ",
5969 use_timeout / 1000);
5971 if (fgets(str, sizeof(str), stdin) != NULL) {
5973 new_timeout = atoi(str);
5976 if (new_timeout != 0) {
5977 use_timeout = new_timeout * 1000;
5978 fprintf(stdout, "Using new timeout value %d\n",
5979 use_timeout / 1000);
5984 * Keep this outside the if block below to silence any unused
5985 * variable warnings.
5987 bzero(&fh, sizeof(fh));
5990 * If we're in immediate mode, we've got to include the format
5993 if (immediate != 0) {
5994 fh.byte2 = FU_DLH_IMMED;
5995 data_ptr = (u_int8_t *)&fh;
5996 dxfer_len = sizeof(fh);
5997 byte2 = FU_FMT_DATA;
5998 } else if (quiet == 0) {
5999 fprintf(stdout, "Formatting...");
6003 scsi_format_unit(&ccb->csio,
6004 /* retries */ retry_count,
6006 /* tag_action */ task_attr,
6009 /* data_ptr */ data_ptr,
6010 /* dxfer_len */ dxfer_len,
6011 /* sense_len */ SSD_FULL_SIZE,
6012 /* timeout */ use_timeout);
6014 /* Disable freezing the device queue */
6015 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6017 if (arglist & CAM_ARG_ERR_RECOVER)
6018 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6020 if (((retval = cam_send_ccb(device, ccb)) < 0)
6021 || ((immediate == 0)
6022 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6023 const char errstr[] = "error sending format command";
6030 if (arglist & CAM_ARG_VERBOSE) {
6031 cam_error_print(device, ccb, CAM_ESF_ALL,
6032 CAM_EPF_ALL, stderr);
6035 goto scsiformat_bailout;
6039 * If we ran in non-immediate mode, we already checked for errors
6040 * above and printed out any necessary information. If we're in
6041 * immediate mode, we need to loop through and get status
6042 * information periodically.
6044 if (immediate == 0) {
6046 fprintf(stdout, "Format Complete\n");
6048 goto scsiformat_bailout;
6055 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6058 * There's really no need to do error recovery or
6059 * retries here, since we're just going to sit in a
6060 * loop and wait for the device to finish formatting.
6062 scsi_test_unit_ready(&ccb->csio,
6065 /* tag_action */ task_attr,
6066 /* sense_len */ SSD_FULL_SIZE,
6067 /* timeout */ 5000);
6069 /* Disable freezing the device queue */
6070 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6072 retval = cam_send_ccb(device, ccb);
6075 * If we get an error from the ioctl, bail out. SCSI
6076 * errors are expected.
6079 warn("error sending CAMIOCOMMAND ioctl");
6080 if (arglist & CAM_ARG_VERBOSE) {
6081 cam_error_print(device, ccb, CAM_ESF_ALL,
6082 CAM_EPF_ALL, stderr);
6085 goto scsiformat_bailout;
6088 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6090 if ((status != CAM_REQ_CMP)
6091 && (status == CAM_SCSI_STATUS_ERROR)
6092 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6093 struct scsi_sense_data *sense;
6094 int error_code, sense_key, asc, ascq;
6096 sense = &ccb->csio.sense_data;
6097 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6098 ccb->csio.sense_resid, &error_code, &sense_key,
6099 &asc, &ascq, /*show_errors*/ 1);
6102 * According to the SCSI-2 and SCSI-3 specs, a
6103 * drive that is in the middle of a format should
6104 * return NOT READY with an ASC of "logical unit
6105 * not ready, format in progress". The sense key
6106 * specific bytes will then be a progress indicator.
6108 if ((sense_key == SSD_KEY_NOT_READY)
6109 && (asc == 0x04) && (ascq == 0x04)) {
6112 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6113 ccb->csio.sense_resid, sks) == 0)
6116 u_int64_t percentage;
6118 val = scsi_2btoul(&sks[1]);
6119 percentage = 10000 * val;
6122 "\rFormatting: %ju.%02u %% "
6124 (uintmax_t)(percentage /
6126 (unsigned)((percentage /
6130 } else if ((quiet == 0)
6131 && (++num_warnings <= 1)) {
6132 warnx("Unexpected SCSI Sense Key "
6133 "Specific value returned "
6135 scsi_sense_print(device, &ccb->csio,
6137 warnx("Unable to print status "
6138 "information, but format will "
6140 warnx("will exit when format is "
6145 warnx("Unexpected SCSI error during format");
6146 cam_error_print(device, ccb, CAM_ESF_ALL,
6147 CAM_EPF_ALL, stderr);
6149 goto scsiformat_bailout;
6152 } else if (status != CAM_REQ_CMP) {
6153 warnx("Unexpected CAM status %#x", status);
6154 if (arglist & CAM_ARG_VERBOSE)
6155 cam_error_print(device, ccb, CAM_ESF_ALL,
6156 CAM_EPF_ALL, stderr);
6158 goto scsiformat_bailout;
6161 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6164 fprintf(stdout, "\nFormat Complete\n");
6174 scsisanitize(struct cam_device *device, int argc, char **argv,
6175 char *combinedopt, int task_attr, int retry_count, int timeout)
6178 u_int8_t action = 0;
6180 int ycount = 0, quiet = 0;
6181 int error = 0, retval = 0;
6182 int use_timeout = 10800 * 1000;
6188 const char *pattern = NULL;
6189 u_int8_t *data_ptr = NULL;
6190 u_int32_t dxfer_len = 0;
6192 int num_warnings = 0;
6195 ccb = cam_getccb(device);
6198 warnx("scsisanitize: error allocating ccb");
6202 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6204 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6207 if (strcasecmp(optarg, "overwrite") == 0)
6208 action = SSZ_SERVICE_ACTION_OVERWRITE;
6209 else if (strcasecmp(optarg, "block") == 0)
6210 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6211 else if (strcasecmp(optarg, "crypto") == 0)
6212 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6213 else if (strcasecmp(optarg, "exitfailure") == 0)
6214 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6216 warnx("invalid service operation \"%s\"",
6219 goto scsisanitize_bailout;
6223 passes = strtol(optarg, NULL, 0);
6224 if (passes < 1 || passes > 31) {
6225 warnx("invalid passes value %d", passes);
6227 goto scsisanitize_bailout;
6258 warnx("an action is required");
6260 goto scsisanitize_bailout;
6261 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6262 struct scsi_sanitize_parameter_list *pl;
6266 if (pattern == NULL) {
6267 warnx("overwrite action requires -P argument");
6269 goto scsisanitize_bailout;
6271 fd = open(pattern, O_RDONLY);
6273 warn("cannot open pattern file %s", pattern);
6275 goto scsisanitize_bailout;
6277 if (fstat(fd, &sb) < 0) {
6278 warn("cannot stat pattern file %s", pattern);
6280 goto scsisanitize_bailout;
6283 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6284 warnx("pattern file size exceeds maximum value %d",
6285 SSZPL_MAX_PATTERN_LENGTH);
6287 goto scsisanitize_bailout;
6289 dxfer_len = sizeof(*pl) + sz;
6290 data_ptr = calloc(1, dxfer_len);
6291 if (data_ptr == NULL) {
6292 warnx("cannot allocate parameter list buffer");
6294 goto scsisanitize_bailout;
6297 amt = read(fd, data_ptr + sizeof(*pl), sz);
6299 warn("cannot read pattern file");
6301 goto scsisanitize_bailout;
6302 } else if (amt != sz) {
6303 warnx("short pattern file read");
6305 goto scsisanitize_bailout;
6308 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6314 pl->byte1 |= SSZPL_INVERT;
6315 scsi_ulto2b(sz, pl->length);
6321 else if (invert != 0)
6323 else if (pattern != NULL)
6328 warnx("%s argument only valid with overwrite "
6331 goto scsisanitize_bailout;
6336 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6337 "following device:\n");
6339 error = scsidoinquiry(device, argc, argv, combinedopt,
6340 task_attr, retry_count, timeout);
6343 warnx("scsisanitize: error sending inquiry");
6344 goto scsisanitize_bailout;
6349 if (!get_confirmation()) {
6351 goto scsisanitize_bailout;
6356 use_timeout = timeout;
6359 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6360 use_timeout / 1000);
6364 * If the user hasn't disabled questions and didn't specify a
6365 * timeout on the command line, ask them if they want the current
6369 && (timeout == 0)) {
6371 int new_timeout = 0;
6373 fprintf(stdout, "Enter new timeout in seconds or press\n"
6374 "return to keep the current timeout [%d] ",
6375 use_timeout / 1000);
6377 if (fgets(str, sizeof(str), stdin) != NULL) {
6379 new_timeout = atoi(str);
6382 if (new_timeout != 0) {
6383 use_timeout = new_timeout * 1000;
6384 fprintf(stdout, "Using new timeout value %d\n",
6385 use_timeout / 1000);
6391 byte2 |= SSZ_UNRESTRICTED_EXIT;
6395 scsi_sanitize(&ccb->csio,
6396 /* retries */ retry_count,
6398 /* tag_action */ task_attr,
6401 /* data_ptr */ data_ptr,
6402 /* dxfer_len */ dxfer_len,
6403 /* sense_len */ SSD_FULL_SIZE,
6404 /* timeout */ use_timeout);
6406 /* Disable freezing the device queue */
6407 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6409 if (arglist & CAM_ARG_ERR_RECOVER)
6410 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6412 if (cam_send_ccb(device, ccb) < 0) {
6413 warn("error sending sanitize command");
6415 goto scsisanitize_bailout;
6418 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6419 struct scsi_sense_data *sense;
6420 int error_code, sense_key, asc, ascq;
6422 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6423 CAM_SCSI_STATUS_ERROR) {
6424 sense = &ccb->csio.sense_data;
6425 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6426 ccb->csio.sense_resid, &error_code, &sense_key,
6427 &asc, &ascq, /*show_errors*/ 1);
6429 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6430 asc == 0x20 && ascq == 0x00)
6431 warnx("sanitize is not supported by "
6434 warnx("error sanitizing this device");
6436 warnx("error sanitizing this device");
6438 if (arglist & CAM_ARG_VERBOSE) {
6439 cam_error_print(device, ccb, CAM_ESF_ALL,
6440 CAM_EPF_ALL, stderr);
6443 goto scsisanitize_bailout;
6447 * If we ran in non-immediate mode, we already checked for errors
6448 * above and printed out any necessary information. If we're in
6449 * immediate mode, we need to loop through and get status
6450 * information periodically.
6452 if (immediate == 0) {
6454 fprintf(stdout, "Sanitize Complete\n");
6456 goto scsisanitize_bailout;
6463 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6466 * There's really no need to do error recovery or
6467 * retries here, since we're just going to sit in a
6468 * loop and wait for the device to finish sanitizing.
6470 scsi_test_unit_ready(&ccb->csio,
6473 /* tag_action */ task_attr,
6474 /* sense_len */ SSD_FULL_SIZE,
6475 /* timeout */ 5000);
6477 /* Disable freezing the device queue */
6478 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6480 retval = cam_send_ccb(device, ccb);
6483 * If we get an error from the ioctl, bail out. SCSI
6484 * errors are expected.
6487 warn("error sending CAMIOCOMMAND ioctl");
6488 if (arglist & CAM_ARG_VERBOSE) {
6489 cam_error_print(device, ccb, CAM_ESF_ALL,
6490 CAM_EPF_ALL, stderr);
6493 goto scsisanitize_bailout;
6496 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6498 if ((status != CAM_REQ_CMP)
6499 && (status == CAM_SCSI_STATUS_ERROR)
6500 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6501 struct scsi_sense_data *sense;
6502 int error_code, sense_key, asc, ascq;
6504 sense = &ccb->csio.sense_data;
6505 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6506 ccb->csio.sense_resid, &error_code, &sense_key,
6507 &asc, &ascq, /*show_errors*/ 1);
6510 * According to the SCSI-3 spec, a drive that is in the
6511 * middle of a sanitize should return NOT READY with an
6512 * ASC of "logical unit not ready, sanitize in
6513 * progress". The sense key specific bytes will then
6514 * be a progress indicator.
6516 if ((sense_key == SSD_KEY_NOT_READY)
6517 && (asc == 0x04) && (ascq == 0x1b)) {
6520 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6521 ccb->csio.sense_resid, sks) == 0)
6524 u_int64_t percentage;
6526 val = scsi_2btoul(&sks[1]);
6527 percentage = 10000 * val;
6530 "\rSanitizing: %ju.%02u %% "
6532 (uintmax_t)(percentage /
6534 (unsigned)((percentage /
6538 } else if ((quiet == 0)
6539 && (++num_warnings <= 1)) {
6540 warnx("Unexpected SCSI Sense Key "
6541 "Specific value returned "
6542 "during sanitize:");
6543 scsi_sense_print(device, &ccb->csio,
6545 warnx("Unable to print status "
6546 "information, but sanitze will "
6548 warnx("will exit when sanitize is "
6553 warnx("Unexpected SCSI error during sanitize");
6554 cam_error_print(device, ccb, CAM_ESF_ALL,
6555 CAM_EPF_ALL, stderr);
6557 goto scsisanitize_bailout;
6560 } else if (status != CAM_REQ_CMP) {
6561 warnx("Unexpected CAM status %#x", status);
6562 if (arglist & CAM_ARG_VERBOSE)
6563 cam_error_print(device, ccb, CAM_ESF_ALL,
6564 CAM_EPF_ALL, stderr);
6566 goto scsisanitize_bailout;
6568 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6571 fprintf(stdout, "\nSanitize Complete\n");
6573 scsisanitize_bailout:
6576 if (data_ptr != NULL)
6584 scsireportluns(struct cam_device *device, int argc, char **argv,
6585 char *combinedopt, int task_attr, int retry_count, int timeout)
6588 int c, countonly, lunsonly;
6589 struct scsi_report_luns_data *lundata;
6591 uint8_t report_type;
6592 uint32_t list_len, i, j;
6597 report_type = RPL_REPORT_DEFAULT;
6598 ccb = cam_getccb(device);
6601 warnx("%s: error allocating ccb", __func__);
6605 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6610 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6619 if (strcasecmp(optarg, "default") == 0)
6620 report_type = RPL_REPORT_DEFAULT;
6621 else if (strcasecmp(optarg, "wellknown") == 0)
6622 report_type = RPL_REPORT_WELLKNOWN;
6623 else if (strcasecmp(optarg, "all") == 0)
6624 report_type = RPL_REPORT_ALL;
6626 warnx("%s: invalid report type \"%s\"",
6637 if ((countonly != 0)
6638 && (lunsonly != 0)) {
6639 warnx("%s: you can only specify one of -c or -l", __func__);
6644 * According to SPC-4, the allocation length must be at least 16
6645 * bytes -- enough for the header and one LUN.
6647 alloc_len = sizeof(*lundata) + 8;
6651 lundata = malloc(alloc_len);
6653 if (lundata == NULL) {
6654 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6659 scsi_report_luns(&ccb->csio,
6660 /*retries*/ retry_count,
6662 /*tag_action*/ task_attr,
6663 /*select_report*/ report_type,
6664 /*rpl_buf*/ lundata,
6665 /*alloc_len*/ alloc_len,
6666 /*sense_len*/ SSD_FULL_SIZE,
6667 /*timeout*/ timeout ? timeout : 5000);
6669 /* Disable freezing the device queue */
6670 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6672 if (arglist & CAM_ARG_ERR_RECOVER)
6673 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6675 if (cam_send_ccb(device, ccb) < 0) {
6676 warn("error sending REPORT LUNS command");
6678 if (arglist & CAM_ARG_VERBOSE)
6679 cam_error_print(device, ccb, CAM_ESF_ALL,
6680 CAM_EPF_ALL, stderr);
6686 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6687 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6693 list_len = scsi_4btoul(lundata->length);
6696 * If we need to list the LUNs, and our allocation
6697 * length was too short, reallocate and retry.
6699 if ((countonly == 0)
6700 && (list_len > (alloc_len - sizeof(*lundata)))) {
6701 alloc_len = list_len + sizeof(*lundata);
6707 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6708 ((list_len / 8) > 1) ? "s" : "");
6713 for (i = 0; i < (list_len / 8); i++) {
6717 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6719 fprintf(stdout, ",");
6720 switch (lundata->luns[i].lundata[j] &
6721 RPL_LUNDATA_ATYP_MASK) {
6722 case RPL_LUNDATA_ATYP_PERIPH:
6723 if ((lundata->luns[i].lundata[j] &
6724 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6725 fprintf(stdout, "%d:",
6726 lundata->luns[i].lundata[j] &
6727 RPL_LUNDATA_PERIPH_BUS_MASK);
6729 && ((lundata->luns[i].lundata[j+2] &
6730 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6733 fprintf(stdout, "%d",
6734 lundata->luns[i].lundata[j+1]);
6736 case RPL_LUNDATA_ATYP_FLAT: {
6738 tmplun[0] = lundata->luns[i].lundata[j] &
6739 RPL_LUNDATA_FLAT_LUN_MASK;
6740 tmplun[1] = lundata->luns[i].lundata[j+1];
6742 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6746 case RPL_LUNDATA_ATYP_LUN:
6747 fprintf(stdout, "%d:%d:%d",
6748 (lundata->luns[i].lundata[j+1] &
6749 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6750 lundata->luns[i].lundata[j] &
6751 RPL_LUNDATA_LUN_TARG_MASK,
6752 lundata->luns[i].lundata[j+1] &
6753 RPL_LUNDATA_LUN_LUN_MASK);
6755 case RPL_LUNDATA_ATYP_EXTLUN: {
6756 int field_len_code, eam_code;
6758 eam_code = lundata->luns[i].lundata[j] &
6759 RPL_LUNDATA_EXT_EAM_MASK;
6760 field_len_code = (lundata->luns[i].lundata[j] &
6761 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6763 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6764 && (field_len_code == 0x00)) {
6765 fprintf(stdout, "%d",
6766 lundata->luns[i].lundata[j+1]);
6767 } else if ((eam_code ==
6768 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6769 && (field_len_code == 0x03)) {
6773 * This format takes up all 8 bytes.
6774 * If we aren't starting at offset 0,
6778 fprintf(stdout, "Invalid "
6781 "specified format", j);
6785 bzero(tmp_lun, sizeof(tmp_lun));
6786 bcopy(&lundata->luns[i].lundata[j+1],
6787 &tmp_lun[1], sizeof(tmp_lun) - 1);
6788 fprintf(stdout, "%#jx",
6789 (intmax_t)scsi_8btou64(tmp_lun));
6792 fprintf(stderr, "Unknown Extended LUN"
6793 "Address method %#x, length "
6794 "code %#x", eam_code,
6801 fprintf(stderr, "Unknown LUN address method "
6802 "%#x\n", lundata->luns[i].lundata[0] &
6803 RPL_LUNDATA_ATYP_MASK);
6807 * For the flat addressing method, there are no
6808 * other levels after it.
6813 fprintf(stdout, "\n");
6826 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6827 char *combinedopt, int task_attr, int retry_count, int timeout)
6830 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6831 struct scsi_read_capacity_data rcap;
6832 struct scsi_read_capacity_data_long rcaplong;
6846 ccb = cam_getccb(device);
6849 warnx("%s: error allocating ccb", __func__);
6853 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6855 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6882 if ((blocksizeonly != 0)
6883 && (numblocks != 0)) {
6884 warnx("%s: you can only specify one of -b or -N", __func__);
6889 if ((blocksizeonly != 0)
6890 && (sizeonly != 0)) {
6891 warnx("%s: you can only specify one of -b or -s", __func__);
6898 warnx("%s: you can only specify one of -h/-H or -q", __func__);
6904 && (blocksizeonly != 0)) {
6905 warnx("%s: you can only specify one of -h/-H or -b", __func__);
6910 scsi_read_capacity(&ccb->csio,
6911 /*retries*/ retry_count,
6913 /*tag_action*/ task_attr,
6916 /*timeout*/ timeout ? timeout : 5000);
6918 /* Disable freezing the device queue */
6919 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6921 if (arglist & CAM_ARG_ERR_RECOVER)
6922 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6924 if (cam_send_ccb(device, ccb) < 0) {
6925 warn("error sending READ CAPACITY command");
6927 if (arglist & CAM_ARG_VERBOSE)
6928 cam_error_print(device, ccb, CAM_ESF_ALL,
6929 CAM_EPF_ALL, stderr);
6935 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6936 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6941 maxsector = scsi_4btoul(rcap.addr);
6942 block_len = scsi_4btoul(rcap.length);
6945 * A last block of 2^32-1 means that the true capacity is over 2TB,
6946 * and we need to issue the long READ CAPACITY to get the real
6947 * capacity. Otherwise, we're all set.
6949 if (maxsector != 0xffffffff)
6952 scsi_read_capacity_16(&ccb->csio,
6953 /*retries*/ retry_count,
6955 /*tag_action*/ task_attr,
6959 /*rcap_buf*/ (uint8_t *)&rcaplong,
6960 /*rcap_buf_len*/ sizeof(rcaplong),
6961 /*sense_len*/ SSD_FULL_SIZE,
6962 /*timeout*/ timeout ? timeout : 5000);
6964 /* Disable freezing the device queue */
6965 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6967 if (arglist & CAM_ARG_ERR_RECOVER)
6968 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6970 if (cam_send_ccb(device, ccb) < 0) {
6971 warn("error sending READ CAPACITY (16) command");
6973 if (arglist & CAM_ARG_VERBOSE)
6974 cam_error_print(device, ccb, CAM_ESF_ALL,
6975 CAM_EPF_ALL, stderr);
6981 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6982 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6987 maxsector = scsi_8btou64(rcaplong.addr);
6988 block_len = scsi_4btoul(rcaplong.length);
6991 if (blocksizeonly == 0) {
6993 * Humanize implies !quiet, and also implies numblocks.
6995 if (humanize != 0) {
7000 tmpbytes = (maxsector + 1) * block_len;
7001 ret = humanize_number(tmpstr, sizeof(tmpstr),
7002 tmpbytes, "", HN_AUTOSCALE,
7005 HN_DIVISOR_1000 : 0));
7007 warnx("%s: humanize_number failed!", __func__);
7011 fprintf(stdout, "Device Size: %s%s", tmpstr,
7012 (sizeonly == 0) ? ", " : "\n");
7013 } else if (numblocks != 0) {
7014 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7015 "Blocks: " : "", (uintmax_t)maxsector + 1,
7016 (sizeonly == 0) ? ", " : "\n");
7018 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7019 "Last Block: " : "", (uintmax_t)maxsector,
7020 (sizeonly == 0) ? ", " : "\n");
7024 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7025 "Block Length: " : "", block_len, (quiet == 0) ?
7034 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7035 int retry_count, int timeout)
7039 uint8_t *smp_request = NULL, *smp_response = NULL;
7040 int request_size = 0, response_size = 0;
7041 int fd_request = 0, fd_response = 0;
7042 char *datastr = NULL;
7043 struct get_hook hook;
7048 * Note that at the moment we don't support sending SMP CCBs to
7049 * devices that aren't probed by CAM.
7051 ccb = cam_getccb(device);
7053 warnx("%s: error allocating CCB", __func__);
7057 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7059 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7062 arglist |= CAM_ARG_CMD_IN;
7063 response_size = strtol(optarg, NULL, 0);
7064 if (response_size <= 0) {
7065 warnx("invalid number of response bytes %d",
7068 goto smpcmd_bailout;
7070 hook.argc = argc - optind;
7071 hook.argv = argv + optind;
7074 datastr = cget(&hook, NULL);
7076 * If the user supplied "-" instead of a format, he
7077 * wants the data to be written to stdout.
7079 if ((datastr != NULL)
7080 && (datastr[0] == '-'))
7083 smp_response = (u_int8_t *)malloc(response_size);
7084 if (smp_response == NULL) {
7085 warn("can't malloc memory for SMP response");
7087 goto smpcmd_bailout;
7091 arglist |= CAM_ARG_CMD_OUT;
7092 request_size = strtol(optarg, NULL, 0);
7093 if (request_size <= 0) {
7094 warnx("invalid number of request bytes %d",
7097 goto smpcmd_bailout;
7099 hook.argc = argc - optind;
7100 hook.argv = argv + optind;
7102 datastr = cget(&hook, NULL);
7103 smp_request = (u_int8_t *)malloc(request_size);
7104 if (smp_request == NULL) {
7105 warn("can't malloc memory for SMP request");
7107 goto smpcmd_bailout;
7109 bzero(smp_request, request_size);
7111 * If the user supplied "-" instead of a format, he
7112 * wants the data to be read from stdin.
7114 if ((datastr != NULL)
7115 && (datastr[0] == '-'))
7118 buff_encode_visit(smp_request, request_size,
7129 * If fd_data is set, and we're writing to the device, we need to
7130 * read the data the user wants written from stdin.
7132 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7134 int amt_to_read = request_size;
7135 u_int8_t *buf_ptr = smp_request;
7137 for (amt_read = 0; amt_to_read > 0;
7138 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7139 if (amt_read == -1) {
7140 warn("error reading data from stdin");
7142 goto smpcmd_bailout;
7144 amt_to_read -= amt_read;
7145 buf_ptr += amt_read;
7149 if (((arglist & CAM_ARG_CMD_IN) == 0)
7150 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7151 warnx("%s: need both the request (-r) and response (-R) "
7152 "arguments", __func__);
7154 goto smpcmd_bailout;
7157 flags |= CAM_DEV_QFRZDIS;
7159 cam_fill_smpio(&ccb->smpio,
7160 /*retries*/ retry_count,
7163 /*smp_request*/ smp_request,
7164 /*smp_request_len*/ request_size,
7165 /*smp_response*/ smp_response,
7166 /*smp_response_len*/ response_size,
7167 /*timeout*/ timeout ? timeout : 5000);
7169 ccb->smpio.flags = SMP_FLAG_NONE;
7171 if (((retval = cam_send_ccb(device, ccb)) < 0)
7172 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7173 const char warnstr[] = "error sending command";
7180 if (arglist & CAM_ARG_VERBOSE) {
7181 cam_error_print(device, ccb, CAM_ESF_ALL,
7182 CAM_EPF_ALL, stderr);
7186 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7187 && (response_size > 0)) {
7188 if (fd_response == 0) {
7189 buff_decode_visit(smp_response, response_size,
7190 datastr, arg_put, NULL);
7191 fprintf(stdout, "\n");
7193 ssize_t amt_written;
7194 int amt_to_write = response_size;
7195 u_int8_t *buf_ptr = smp_response;
7197 for (amt_written = 0; (amt_to_write > 0) &&
7198 (amt_written = write(STDOUT_FILENO, buf_ptr,
7199 amt_to_write)) > 0;){
7200 amt_to_write -= amt_written;
7201 buf_ptr += amt_written;
7203 if (amt_written == -1) {
7204 warn("error writing data to stdout");
7206 goto smpcmd_bailout;
7207 } else if ((amt_written == 0)
7208 && (amt_to_write > 0)) {
7209 warnx("only wrote %u bytes out of %u",
7210 response_size - amt_to_write,
7219 if (smp_request != NULL)
7222 if (smp_response != NULL)
7229 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7230 char *combinedopt, int retry_count, int timeout)
7233 struct smp_report_general_request *request = NULL;
7234 struct smp_report_general_response *response = NULL;
7235 struct sbuf *sb = NULL;
7237 int c, long_response = 0;
7241 * Note that at the moment we don't support sending SMP CCBs to
7242 * devices that aren't probed by CAM.
7244 ccb = cam_getccb(device);
7246 warnx("%s: error allocating CCB", __func__);
7250 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7252 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7261 request = malloc(sizeof(*request));
7262 if (request == NULL) {
7263 warn("%s: unable to allocate %zd bytes", __func__,
7269 response = malloc(sizeof(*response));
7270 if (response == NULL) {
7271 warn("%s: unable to allocate %zd bytes", __func__,
7278 smp_report_general(&ccb->smpio,
7282 /*request_len*/ sizeof(*request),
7283 (uint8_t *)response,
7284 /*response_len*/ sizeof(*response),
7285 /*long_response*/ long_response,
7288 if (((retval = cam_send_ccb(device, ccb)) < 0)
7289 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7290 const char warnstr[] = "error sending command";
7297 if (arglist & CAM_ARG_VERBOSE) {
7298 cam_error_print(device, ccb, CAM_ESF_ALL,
7299 CAM_EPF_ALL, stderr);
7306 * If the device supports the long response bit, try again and see
7307 * if we can get all of the data.
7309 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7310 && (long_response == 0)) {
7311 ccb->ccb_h.status = CAM_REQ_INPROG;
7312 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7318 * XXX KDM detect and decode SMP errors here.
7320 sb = sbuf_new_auto();
7322 warnx("%s: error allocating sbuf", __func__);
7326 smp_report_general_sbuf(response, sizeof(*response), sb);
7328 if (sbuf_finish(sb) != 0) {
7329 warnx("%s: sbuf_finish", __func__);
7333 printf("%s", sbuf_data(sb));
7339 if (request != NULL)
7342 if (response != NULL)
7351 static struct camcontrol_opts phy_ops[] = {
7352 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7353 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7354 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7355 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7356 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7357 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7358 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7359 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7360 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7365 smpphycontrol(struct cam_device *device, int argc, char **argv,
7366 char *combinedopt, int retry_count, int timeout)
7369 struct smp_phy_control_request *request = NULL;
7370 struct smp_phy_control_response *response = NULL;
7371 int long_response = 0;
7374 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7376 uint64_t attached_dev_name = 0;
7377 int dev_name_set = 0;
7378 uint32_t min_plr = 0, max_plr = 0;
7379 uint32_t pp_timeout_val = 0;
7380 int slumber_partial = 0;
7381 int set_pp_timeout_val = 0;
7385 * Note that at the moment we don't support sending SMP CCBs to
7386 * devices that aren't probed by CAM.
7388 ccb = cam_getccb(device);
7390 warnx("%s: error allocating CCB", __func__);
7394 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7396 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7404 if (strcasecmp(optarg, "enable") == 0)
7406 else if (strcasecmp(optarg, "disable") == 0)
7409 warnx("%s: Invalid argument %s", __func__,
7416 slumber_partial |= enable <<
7417 SMP_PC_SAS_SLUMBER_SHIFT;
7420 slumber_partial |= enable <<
7421 SMP_PC_SAS_PARTIAL_SHIFT;
7424 slumber_partial |= enable <<
7425 SMP_PC_SATA_SLUMBER_SHIFT;
7428 slumber_partial |= enable <<
7429 SMP_PC_SATA_PARTIAL_SHIFT;
7432 warnx("%s: programmer error", __func__);
7435 break; /*NOTREACHED*/
7440 attached_dev_name = (uintmax_t)strtoumax(optarg,
7449 * We don't do extensive checking here, so this
7450 * will continue to work when new speeds come out.
7452 min_plr = strtoul(optarg, NULL, 0);
7454 || (min_plr > 0xf)) {
7455 warnx("%s: invalid link rate %x",
7463 * We don't do extensive checking here, so this
7464 * will continue to work when new speeds come out.
7466 max_plr = strtoul(optarg, NULL, 0);
7468 || (max_plr > 0xf)) {
7469 warnx("%s: invalid link rate %x",
7476 camcontrol_optret optreturn;
7477 cam_argmask argnums;
7480 if (phy_op_set != 0) {
7481 warnx("%s: only one phy operation argument "
7482 "(-o) allowed", __func__);
7490 * Allow the user to specify the phy operation
7491 * numerically, as well as with a name. This will
7492 * future-proof it a bit, so options that are added
7493 * in future specs can be used.
7495 if (isdigit(optarg[0])) {
7496 phy_operation = strtoul(optarg, NULL, 0);
7497 if ((phy_operation == 0)
7498 || (phy_operation > 0xff)) {
7499 warnx("%s: invalid phy operation %#x",
7500 __func__, phy_operation);
7506 optreturn = getoption(phy_ops, optarg, &phy_operation,
7509 if (optreturn == CC_OR_AMBIGUOUS) {
7510 warnx("%s: ambiguous option %s", __func__,
7515 } else if (optreturn == CC_OR_NOT_FOUND) {
7516 warnx("%s: option %s not found", __func__,
7528 pp_timeout_val = strtoul(optarg, NULL, 0);
7529 if (pp_timeout_val > 15) {
7530 warnx("%s: invalid partial pathway timeout "
7531 "value %u, need a value less than 16",
7532 __func__, pp_timeout_val);
7536 set_pp_timeout_val = 1;
7544 warnx("%s: a PHY (-p phy) argument is required",__func__);
7549 if (((dev_name_set != 0)
7550 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
7551 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
7552 && (dev_name_set == 0))) {
7553 warnx("%s: -d name and -o setdevname arguments both "
7554 "required to set device name", __func__);
7559 request = malloc(sizeof(*request));
7560 if (request == NULL) {
7561 warn("%s: unable to allocate %zd bytes", __func__,
7567 response = malloc(sizeof(*response));
7568 if (response == NULL) {
7569 warn("%s: unable to allocate %zd bytes", __func__,
7575 smp_phy_control(&ccb->smpio,
7580 (uint8_t *)response,
7583 /*expected_exp_change_count*/ 0,
7586 (set_pp_timeout_val != 0) ? 1 : 0,
7594 if (((retval = cam_send_ccb(device, ccb)) < 0)
7595 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7596 const char warnstr[] = "error sending command";
7603 if (arglist & CAM_ARG_VERBOSE) {
7605 * Use CAM_EPF_NORMAL so we only get one line of
7606 * SMP command decoding.
7608 cam_error_print(device, ccb, CAM_ESF_ALL,
7609 CAM_EPF_NORMAL, stderr);
7615 /* XXX KDM print out something here for success? */
7620 if (request != NULL)
7623 if (response != NULL)
7630 smpmaninfo(struct cam_device *device, int argc, char **argv,
7631 char *combinedopt, int retry_count, int timeout)
7634 struct smp_report_manuf_info_request request;
7635 struct smp_report_manuf_info_response response;
7636 struct sbuf *sb = NULL;
7637 int long_response = 0;
7642 * Note that at the moment we don't support sending SMP CCBs to
7643 * devices that aren't probed by CAM.
7645 ccb = cam_getccb(device);
7647 warnx("%s: error allocating CCB", __func__);
7651 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7653 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7662 bzero(&request, sizeof(request));
7663 bzero(&response, sizeof(response));
7665 smp_report_manuf_info(&ccb->smpio,
7670 (uint8_t *)&response,
7675 if (((retval = cam_send_ccb(device, ccb)) < 0)
7676 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7677 const char warnstr[] = "error sending command";
7684 if (arglist & CAM_ARG_VERBOSE) {
7685 cam_error_print(device, ccb, CAM_ESF_ALL,
7686 CAM_EPF_ALL, stderr);
7692 sb = sbuf_new_auto();
7694 warnx("%s: error allocating sbuf", __func__);
7698 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7700 if (sbuf_finish(sb) != 0) {
7701 warnx("%s: sbuf_finish", __func__);
7705 printf("%s", sbuf_data(sb));
7719 getdevid(struct cam_devitem *item)
7722 union ccb *ccb = NULL;
7724 struct cam_device *dev;
7726 dev = cam_open_btl(item->dev_match.path_id,
7727 item->dev_match.target_id,
7728 item->dev_match.target_lun, O_RDWR, NULL);
7731 warnx("%s", cam_errbuf);
7736 item->device_id_len = 0;
7738 ccb = cam_getccb(dev);
7740 warnx("%s: error allocating CCB", __func__);
7745 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
7748 * On the first try, we just probe for the size of the data, and
7749 * then allocate that much memory and try again.
7752 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7753 ccb->ccb_h.flags = CAM_DIR_IN;
7754 ccb->cdai.flags = CDAI_FLAG_NONE;
7755 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7756 ccb->cdai.bufsiz = item->device_id_len;
7757 if (item->device_id_len != 0)
7758 ccb->cdai.buf = (uint8_t *)item->device_id;
7760 if (cam_send_ccb(dev, ccb) < 0) {
7761 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7766 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7767 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7772 if (item->device_id_len == 0) {
7774 * This is our first time through. Allocate the buffer,
7775 * and then go back to get the data.
7777 if (ccb->cdai.provsiz == 0) {
7778 warnx("%s: invalid .provsiz field returned with "
7779 "XPT_GDEV_ADVINFO CCB", __func__);
7783 item->device_id_len = ccb->cdai.provsiz;
7784 item->device_id = malloc(item->device_id_len);
7785 if (item->device_id == NULL) {
7786 warn("%s: unable to allocate %d bytes", __func__,
7787 item->device_id_len);
7791 ccb->ccb_h.status = CAM_REQ_INPROG;
7797 cam_close_device(dev);
7806 * XXX KDM merge this code with getdevtree()?
7809 buildbusdevlist(struct cam_devlist *devlist)
7812 int bufsize, fd = -1;
7813 struct dev_match_pattern *patterns;
7814 struct cam_devitem *item = NULL;
7815 int skip_device = 0;
7818 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7819 warn("couldn't open %s", XPT_DEVICE);
7823 bzero(&ccb, sizeof(union ccb));
7825 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7826 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7827 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7829 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7830 bufsize = sizeof(struct dev_match_result) * 100;
7831 ccb.cdm.match_buf_len = bufsize;
7832 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7833 if (ccb.cdm.matches == NULL) {
7834 warnx("can't malloc memory for matches");
7838 ccb.cdm.num_matches = 0;
7839 ccb.cdm.num_patterns = 2;
7840 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7841 ccb.cdm.num_patterns;
7843 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7844 if (patterns == NULL) {
7845 warnx("can't malloc memory for patterns");
7850 ccb.cdm.patterns = patterns;
7851 bzero(patterns, ccb.cdm.pattern_buf_len);
7853 patterns[0].type = DEV_MATCH_DEVICE;
7854 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7855 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7856 patterns[1].type = DEV_MATCH_PERIPH;
7857 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7858 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7861 * We do the ioctl multiple times if necessary, in case there are
7862 * more than 100 nodes in the EDT.
7867 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7868 warn("error sending CAMIOCOMMAND ioctl");
7873 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7874 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7875 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7876 warnx("got CAM error %#x, CDM error %d\n",
7877 ccb.ccb_h.status, ccb.cdm.status);
7882 for (i = 0; i < ccb.cdm.num_matches; i++) {
7883 switch (ccb.cdm.matches[i].type) {
7884 case DEV_MATCH_DEVICE: {
7885 struct device_match_result *dev_result;
7888 &ccb.cdm.matches[i].result.device_result;
7890 if (dev_result->flags &
7891 DEV_RESULT_UNCONFIGURED) {
7897 item = malloc(sizeof(*item));
7899 warn("%s: unable to allocate %zd bytes",
7900 __func__, sizeof(*item));
7904 bzero(item, sizeof(*item));
7905 bcopy(dev_result, &item->dev_match,
7906 sizeof(*dev_result));
7907 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
7910 if (getdevid(item) != 0) {
7916 case DEV_MATCH_PERIPH: {
7917 struct periph_match_result *periph_result;
7920 &ccb.cdm.matches[i].result.periph_result;
7922 if (skip_device != 0)
7924 item->num_periphs++;
7925 item->periph_matches = realloc(
7926 item->periph_matches,
7928 sizeof(struct periph_match_result));
7929 if (item->periph_matches == NULL) {
7930 warn("%s: error allocating periph "
7935 bcopy(periph_result, &item->periph_matches[
7936 item->num_periphs - 1],
7937 sizeof(*periph_result));
7941 fprintf(stderr, "%s: unexpected match "
7942 "type %d\n", __func__,
7943 ccb.cdm.matches[i].type);
7946 break; /*NOTREACHED*/
7949 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
7950 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
7958 free(ccb.cdm.matches);
7961 freebusdevlist(devlist);
7967 freebusdevlist(struct cam_devlist *devlist)
7969 struct cam_devitem *item, *item2;
7971 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
7972 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
7974 free(item->device_id);
7975 free(item->periph_matches);
7980 static struct cam_devitem *
7981 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
7983 struct cam_devitem *item;
7985 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
7986 struct scsi_vpd_id_descriptor *idd;
7989 * XXX KDM look for LUN IDs as well?
7991 idd = scsi_get_devid(item->device_id,
7992 item->device_id_len,
7993 scsi_devid_is_sas_target);
7997 if (scsi_8btou64(idd->identifier) == sasaddr)
8005 smpphylist(struct cam_device *device, int argc, char **argv,
8006 char *combinedopt, int retry_count, int timeout)
8008 struct smp_report_general_request *rgrequest = NULL;
8009 struct smp_report_general_response *rgresponse = NULL;
8010 struct smp_discover_request *disrequest = NULL;
8011 struct smp_discover_response *disresponse = NULL;
8012 struct cam_devlist devlist;
8014 int long_response = 0;
8021 * Note that at the moment we don't support sending SMP CCBs to
8022 * devices that aren't probed by CAM.
8024 ccb = cam_getccb(device);
8026 warnx("%s: error allocating CCB", __func__);
8030 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8031 STAILQ_INIT(&devlist.dev_queue);
8033 rgrequest = malloc(sizeof(*rgrequest));
8034 if (rgrequest == NULL) {
8035 warn("%s: unable to allocate %zd bytes", __func__,
8036 sizeof(*rgrequest));
8041 rgresponse = malloc(sizeof(*rgresponse));
8042 if (rgresponse == NULL) {
8043 warn("%s: unable to allocate %zd bytes", __func__,
8044 sizeof(*rgresponse));
8049 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8062 smp_report_general(&ccb->smpio,
8066 /*request_len*/ sizeof(*rgrequest),
8067 (uint8_t *)rgresponse,
8068 /*response_len*/ sizeof(*rgresponse),
8069 /*long_response*/ long_response,
8072 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8074 if (((retval = cam_send_ccb(device, ccb)) < 0)
8075 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8076 const char warnstr[] = "error sending command";
8083 if (arglist & CAM_ARG_VERBOSE) {
8084 cam_error_print(device, ccb, CAM_ESF_ALL,
8085 CAM_EPF_ALL, stderr);
8091 num_phys = rgresponse->num_phys;
8093 if (num_phys == 0) {
8095 fprintf(stdout, "%s: No Phys reported\n", __func__);
8100 devlist.path_id = device->path_id;
8102 retval = buildbusdevlist(&devlist);
8107 fprintf(stdout, "%d PHYs:\n", num_phys);
8108 fprintf(stdout, "PHY Attached SAS Address\n");
8111 disrequest = malloc(sizeof(*disrequest));
8112 if (disrequest == NULL) {
8113 warn("%s: unable to allocate %zd bytes", __func__,
8114 sizeof(*disrequest));
8119 disresponse = malloc(sizeof(*disresponse));
8120 if (disresponse == NULL) {
8121 warn("%s: unable to allocate %zd bytes", __func__,
8122 sizeof(*disresponse));
8127 for (i = 0; i < num_phys; i++) {
8128 struct cam_devitem *item;
8129 struct device_match_result *dev_match;
8130 char vendor[16], product[48], revision[16];
8134 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8136 ccb->ccb_h.status = CAM_REQ_INPROG;
8137 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8139 smp_discover(&ccb->smpio,
8143 sizeof(*disrequest),
8144 (uint8_t *)disresponse,
8145 sizeof(*disresponse),
8147 /*ignore_zone_group*/ 0,
8151 if (((retval = cam_send_ccb(device, ccb)) < 0)
8152 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
8153 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
8154 const char warnstr[] = "error sending command";
8161 if (arglist & CAM_ARG_VERBOSE) {
8162 cam_error_print(device, ccb, CAM_ESF_ALL,
8163 CAM_EPF_ALL, stderr);
8169 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
8171 fprintf(stdout, "%3d <vacant>\n", i);
8175 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
8178 item = findsasdevice(&devlist,
8179 scsi_8btou64(disresponse->attached_sas_address));
8183 || (item != NULL)) {
8184 fprintf(stdout, "%3d 0x%016jx", i,
8185 (uintmax_t)scsi_8btou64(
8186 disresponse->attached_sas_address));
8188 fprintf(stdout, "\n");
8191 } else if (quiet != 0)
8194 dev_match = &item->dev_match;
8196 if (dev_match->protocol == PROTO_SCSI) {
8197 cam_strvis(vendor, dev_match->inq_data.vendor,
8198 sizeof(dev_match->inq_data.vendor),
8200 cam_strvis(product, dev_match->inq_data.product,
8201 sizeof(dev_match->inq_data.product),
8203 cam_strvis(revision, dev_match->inq_data.revision,
8204 sizeof(dev_match->inq_data.revision),
8206 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8208 } else if ((dev_match->protocol == PROTO_ATA)
8209 || (dev_match->protocol == PROTO_SATAPM)) {
8210 cam_strvis(product, dev_match->ident_data.model,
8211 sizeof(dev_match->ident_data.model),
8213 cam_strvis(revision, dev_match->ident_data.revision,
8214 sizeof(dev_match->ident_data.revision),
8216 sprintf(tmpstr, "<%s %s>", product, revision);
8218 sprintf(tmpstr, "<>");
8220 fprintf(stdout, " %-33s ", tmpstr);
8223 * If we have 0 periphs, that's a bug...
8225 if (item->num_periphs == 0) {
8226 fprintf(stdout, "\n");
8230 fprintf(stdout, "(");
8231 for (j = 0; j < item->num_periphs; j++) {
8233 fprintf(stdout, ",");
8235 fprintf(stdout, "%s%d",
8236 item->periph_matches[j].periph_name,
8237 item->periph_matches[j].unit_number);
8240 fprintf(stdout, ")\n");
8254 freebusdevlist(&devlist);
8260 atapm(struct cam_device *device, int argc, char **argv,
8261 char *combinedopt, int retry_count, int timeout)
8269 ccb = cam_getccb(device);
8272 warnx("%s: error allocating ccb", __func__);
8276 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8285 if (strcmp(argv[1], "idle") == 0) {
8287 cmd = ATA_IDLE_IMMEDIATE;
8290 } else if (strcmp(argv[1], "standby") == 0) {
8292 cmd = ATA_STANDBY_IMMEDIATE;
8294 cmd = ATA_STANDBY_CMD;
8302 else if (t <= (240 * 5))
8304 else if (t <= (252 * 5))
8305 /* special encoding for 21 minutes */
8307 else if (t <= (11 * 30 * 60))
8308 sc = (t - 1) / (30 * 60) + 241;
8312 retval = ata_do_28bit_cmd(device,
8314 /*retries*/retry_count,
8315 /*flags*/CAM_DIR_NONE,
8316 /*protocol*/AP_PROTO_NON_DATA,
8317 /*tag_action*/MSG_SIMPLE_Q_TAG,
8324 /*timeout*/timeout ? timeout : 30 * 1000,
8332 ataaxm(struct cam_device *device, int argc, char **argv,
8333 char *combinedopt, int retry_count, int timeout)
8341 ccb = cam_getccb(device);
8344 warnx("%s: error allocating ccb", __func__);
8348 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8358 if (strcmp(argv[1], "apm") == 0) {
8374 retval = ata_do_28bit_cmd(device,
8376 /*retries*/retry_count,
8377 /*flags*/CAM_DIR_NONE,
8378 /*protocol*/AP_PROTO_NON_DATA,
8379 /*tag_action*/MSG_SIMPLE_Q_TAG,
8380 /*command*/ATA_SETFEATURES,
8386 /*timeout*/timeout ? timeout : 30 * 1000,
8394 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
8395 int show_sa_errors, int sa_set, int service_action,
8396 int timeout_desc, int task_attr, int retry_count, int timeout,
8397 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
8399 union ccb *ccb = NULL;
8400 uint8_t *buf = NULL;
8401 uint32_t alloc_len = 0, num_opcodes;
8402 uint32_t valid_len = 0;
8403 uint32_t avail_len = 0;
8404 struct scsi_report_supported_opcodes_all *all_hdr;
8405 struct scsi_report_supported_opcodes_one *one;
8410 * Make it clear that we haven't yet allocated or filled anything.
8415 ccb = cam_getccb(device);
8417 warnx("couldn't allocate CCB");
8422 /* cam_getccb cleans up the header, caller has to zero the payload */
8423 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8425 if (opcode_set != 0) {
8426 options |= RSO_OPTIONS_OC;
8428 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
8431 alloc_len = sizeof(*all_hdr) + (num_opcodes *
8432 sizeof(struct scsi_report_supported_opcodes_descr));
8435 if (timeout_desc != 0) {
8436 options |= RSO_RCTD;
8437 alloc_len += num_opcodes *
8438 sizeof(struct scsi_report_supported_opcodes_timeout);
8442 options |= RSO_OPTIONS_OC_SA;
8443 if (show_sa_errors != 0)
8444 options &= ~RSO_OPTIONS_OC;
8453 buf = malloc(alloc_len);
8455 warn("Unable to allocate %u bytes", alloc_len);
8459 bzero(buf, alloc_len);
8461 scsi_report_supported_opcodes(&ccb->csio,
8462 /*retries*/ retry_count,
8464 /*tag_action*/ task_attr,
8465 /*options*/ options,
8466 /*req_opcode*/ opcode,
8467 /*req_service_action*/ service_action,
8469 /*dxfer_len*/ alloc_len,
8470 /*sense_len*/ SSD_FULL_SIZE,
8471 /*timeout*/ timeout ? timeout : 10000);
8473 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8475 if (retry_count != 0)
8476 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
8478 if (cam_send_ccb(device, ccb) < 0) {
8479 perror("error sending REPORT SUPPORTED OPERATION CODES");
8484 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8485 if (verbosemode != 0)
8486 cam_error_print(device, ccb, CAM_ESF_ALL,
8487 CAM_EPF_ALL, stderr);
8493 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
8495 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
8496 && (valid_len >= sizeof(*all_hdr))) {
8497 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
8498 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
8499 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
8500 && (valid_len >= sizeof(*one))) {
8501 uint32_t cdb_length;
8503 one = (struct scsi_report_supported_opcodes_one *)buf;
8504 cdb_length = scsi_2btoul(one->cdb_length);
8505 avail_len = sizeof(*one) + cdb_length;
8506 if (one->support & RSO_ONE_CTDP) {
8507 struct scsi_report_supported_opcodes_timeout *td;
8509 td = (struct scsi_report_supported_opcodes_timeout *)
8511 if (valid_len >= (avail_len + sizeof(td->length))) {
8512 avail_len += scsi_2btoul(td->length) +
8515 avail_len += sizeof(*td);
8521 * avail_len could be zero if we didn't get enough data back from
8522 * thet target to determine
8524 if ((avail_len != 0)
8525 && (avail_len > valid_len)) {
8526 alloc_len = avail_len;
8530 *fill_len = valid_len;
8542 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
8543 int req_sa, uint8_t *buf, uint32_t valid_len)
8545 struct scsi_report_supported_opcodes_one *one;
8546 struct scsi_report_supported_opcodes_timeout *td;
8547 uint32_t cdb_len = 0, td_len = 0;
8548 const char *op_desc = NULL;
8552 one = (struct scsi_report_supported_opcodes_one *)buf;
8555 * If we don't have the full single opcode descriptor, no point in
8558 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8560 warnx("Only %u bytes returned, not enough to verify support",
8566 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
8568 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
8571 printf(", SA 0x%x", req_sa);
8574 switch (one->support & RSO_ONE_SUP_MASK) {
8575 case RSO_ONE_SUP_UNAVAIL:
8576 printf("No command support information currently available\n");
8578 case RSO_ONE_SUP_NOT_SUP:
8579 printf("Command not supported\n");
8582 break; /*NOTREACHED*/
8583 case RSO_ONE_SUP_AVAIL:
8584 printf("Command is supported, complies with a SCSI standard\n");
8586 case RSO_ONE_SUP_VENDOR:
8587 printf("Command is supported, vendor-specific "
8588 "implementation\n");
8591 printf("Unknown command support flags 0x%#x\n",
8592 one->support & RSO_ONE_SUP_MASK);
8597 * If we don't have the CDB length, it isn't exactly an error, the
8598 * command probably isn't supported.
8600 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8604 cdb_len = scsi_2btoul(one->cdb_length);
8607 * If our valid data doesn't include the full reported length,
8608 * return. The caller should have detected this and adjusted his
8609 * allocation length to get all of the available data.
8611 if (valid_len < sizeof(*one) + cdb_len) {
8617 * If all we have is the opcode, there is no point in printing out
8625 printf("CDB usage bitmap:");
8626 for (i = 0; i < cdb_len; i++) {
8627 printf(" %02x", one->cdb_usage[i]);
8632 * If we don't have a timeout descriptor, we're done.
8634 if ((one->support & RSO_ONE_CTDP) == 0)
8638 * If we don't have enough valid length to include the timeout
8639 * descriptor length, we're done.
8641 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
8644 td = (struct scsi_report_supported_opcodes_timeout *)
8645 &buf[sizeof(*one) + cdb_len];
8646 td_len = scsi_2btoul(td->length);
8647 td_len += sizeof(td->length);
8650 * If we don't have the full timeout descriptor, we're done.
8652 if (td_len < sizeof(*td))
8656 * If we don't have enough valid length to contain the full timeout
8657 * descriptor, we're done.
8659 if (valid_len < (sizeof(*one) + cdb_len + td_len))
8662 printf("Timeout information:\n");
8663 printf("Command-specific: 0x%02x\n", td->cmd_specific);
8664 printf("Nominal timeout: %u seconds\n",
8665 scsi_4btoul(td->nominal_time));
8666 printf("Recommended timeout: %u seconds\n",
8667 scsi_4btoul(td->recommended_time));
8674 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
8677 struct scsi_report_supported_opcodes_all *hdr;
8678 struct scsi_report_supported_opcodes_descr *desc;
8679 uint32_t avail_len = 0, used_len = 0;
8683 if (valid_len < sizeof(*hdr)) {
8684 warnx("%s: not enough returned data (%u bytes) opcode list",
8685 __func__, valid_len);
8689 hdr = (struct scsi_report_supported_opcodes_all *)buf;
8690 avail_len = scsi_4btoul(hdr->length);
8691 avail_len += sizeof(hdr->length);
8693 * Take the lesser of the amount of data the drive claims is
8694 * available, and the amount of data the HBA says was returned.
8696 avail_len = MIN(avail_len, valid_len);
8698 used_len = sizeof(hdr->length);
8700 printf("%-6s %4s %8s ",
8701 "Opcode", "SA", "CDB len" );
8704 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
8705 printf(" Description\n");
8707 while ((avail_len - used_len) > sizeof(*desc)) {
8708 struct scsi_report_supported_opcodes_timeout *td;
8710 const char *op_desc = NULL;
8712 cur_ptr = &buf[used_len];
8713 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
8715 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
8716 if (op_desc == NULL)
8717 op_desc = "UNKNOWN";
8719 printf("0x%02x %#4x %8u ", desc->opcode,
8720 scsi_2btoul(desc->service_action),
8721 scsi_2btoul(desc->cdb_length));
8723 used_len += sizeof(*desc);
8725 if ((desc->flags & RSO_CTDP) == 0) {
8726 printf(" %s\n", op_desc);
8731 * If we don't have enough space to fit a timeout
8732 * descriptor, then we're done.
8734 if (avail_len - used_len < sizeof(*td)) {
8735 used_len = avail_len;
8736 printf(" %s\n", op_desc);
8739 cur_ptr = &buf[used_len];
8740 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
8741 td_len = scsi_2btoul(td->length);
8742 td_len += sizeof(td->length);
8746 * If the given timeout descriptor length is less than what
8747 * we understand, skip it.
8749 if (td_len < sizeof(*td)) {
8750 printf(" %s\n", op_desc);
8754 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
8755 scsi_4btoul(td->nominal_time),
8756 scsi_4btoul(td->recommended_time), op_desc);
8763 scsiopcodes(struct cam_device *device, int argc, char **argv,
8764 char *combinedopt, int task_attr, int retry_count, int timeout,
8768 uint32_t opcode = 0, service_action = 0;
8769 int td_set = 0, opcode_set = 0, sa_set = 0;
8770 int show_sa_errors = 1;
8771 uint32_t valid_len = 0;
8772 uint8_t *buf = NULL;
8776 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8782 opcode = strtoul(optarg, &endptr, 0);
8783 if (*endptr != '\0') {
8784 warnx("Invalid opcode \"%s\", must be a number",
8789 if (opcode > 0xff) {
8790 warnx("Invalid opcode 0x%#x, must be between"
8791 "0 and 0xff inclusive", opcode);
8798 service_action = strtoul(optarg, &endptr, 0);
8799 if (*endptr != '\0') {
8800 warnx("Invalid service action \"%s\", must "
8801 "be a number", optarg);
8805 if (service_action > 0xffff) {
8806 warnx("Invalid service action 0x%#x, must "
8807 "be between 0 and 0xffff inclusive",
8822 && (opcode_set == 0)) {
8823 warnx("You must specify an opcode with -o if a service "
8828 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
8829 sa_set, service_action, td_set, task_attr,
8830 retry_count, timeout, verbosemode, &valid_len,
8835 if ((opcode_set != 0)
8837 retval = scsiprintoneopcode(device, opcode, sa_set,
8838 service_action, buf, valid_len);
8840 retval = scsiprintopcodes(device, td_set, buf, valid_len);
8849 #endif /* MINIMALISTIC */
8852 scsireprobe(struct cam_device *device)
8857 ccb = cam_getccb(device);
8860 warnx("%s: error allocating ccb", __func__);
8864 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8866 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
8868 if (cam_send_ccb(device, ccb) < 0) {
8869 warn("error sending XPT_REPROBE_LUN CCB");
8874 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8875 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
8887 usage(int printlong)
8890 fprintf(printlong ? stdout : stderr,
8891 "usage: camcontrol <command> [device id][generic args][command args]\n"
8892 " camcontrol devlist [-b] [-v]\n"
8893 #ifndef MINIMALISTIC
8894 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
8895 " camcontrol tur [dev_id][generic args]\n"
8896 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
8897 " camcontrol identify [dev_id][generic args] [-v]\n"
8898 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
8899 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
8901 " camcontrol start [dev_id][generic args]\n"
8902 " camcontrol stop [dev_id][generic args]\n"
8903 " camcontrol load [dev_id][generic args]\n"
8904 " camcontrol eject [dev_id][generic args]\n"
8905 " camcontrol reprobe [dev_id][generic args]\n"
8906 #endif /* MINIMALISTIC */
8907 " camcontrol rescan <all | bus[:target:lun]>\n"
8908 " camcontrol reset <all | bus[:target:lun]>\n"
8909 #ifndef MINIMALISTIC
8910 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
8911 " [-q][-s][-S offset][-X]\n"
8912 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
8913 " [-P pagectl][-e | -b][-d]\n"
8914 " camcontrol cmd [dev_id][generic args]\n"
8915 " <-a cmd [args] | -c cmd [args]>\n"
8916 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
8917 " camcontrol smpcmd [dev_id][generic args]\n"
8918 " <-r len fmt [args]> <-R len fmt [args]>\n"
8919 " camcontrol smprg [dev_id][generic args][-l]\n"
8920 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
8921 " [-o operation][-d name][-m rate][-M rate]\n"
8922 " [-T pp_timeout][-a enable|disable]\n"
8923 " [-A enable|disable][-s enable|disable]\n"
8924 " [-S enable|disable]\n"
8925 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
8926 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
8927 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
8928 " <all|bus[:target[:lun]]|off>\n"
8929 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
8930 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
8931 " [-D <enable|disable>][-M mode][-O offset]\n"
8932 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
8933 " [-U][-W bus_width]\n"
8934 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
8935 " camcontrol sanitize [dev_id][generic args]\n"
8936 " [-a overwrite|block|crypto|exitfailure]\n"
8937 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
8939 " camcontrol idle [dev_id][generic args][-t time]\n"
8940 " camcontrol standby [dev_id][generic args][-t time]\n"
8941 " camcontrol sleep [dev_id][generic args]\n"
8942 " camcontrol apm [dev_id][generic args][-l level]\n"
8943 " camcontrol aam [dev_id][generic args][-l level]\n"
8944 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
8946 " camcontrol security [dev_id][generic args]\n"
8947 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
8948 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
8949 " [-U <user|master>] [-y]\n"
8950 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
8951 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
8952 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
8953 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
8954 " [-s scope][-S][-T type][-U]\n"
8955 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
8956 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
8957 " [-p part][-s start][-T type][-V vol]\n"
8958 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
8960 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
8961 " [-o rep_opts] [-P print_opts]\n"
8962 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
8963 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
8964 " [-S power_src] [-T timer]\n"
8965 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
8966 " <-s <-f format -T time | -U >>\n"
8968 #endif /* MINIMALISTIC */
8969 " camcontrol help\n");
8972 #ifndef MINIMALISTIC
8974 "Specify one of the following options:\n"
8975 "devlist list all CAM devices\n"
8976 "periphlist list all CAM peripheral drivers attached to a device\n"
8977 "tur send a test unit ready to the named device\n"
8978 "inquiry send a SCSI inquiry command to the named device\n"
8979 "identify send a ATA identify command to the named device\n"
8980 "reportluns send a SCSI report luns command to the device\n"
8981 "readcap send a SCSI read capacity command to the device\n"
8982 "start send a Start Unit command to the device\n"
8983 "stop send a Stop Unit command to the device\n"
8984 "load send a Start Unit command to the device with the load bit set\n"
8985 "eject send a Stop Unit command to the device with the eject bit set\n"
8986 "reprobe update capacity information of the given device\n"
8987 "rescan rescan all buses, the given bus, or bus:target:lun\n"
8988 "reset reset all buses, the given bus, or bus:target:lun\n"
8989 "defects read the defect list of the specified device\n"
8990 "modepage display or edit (-e) the given mode page\n"
8991 "cmd send the given SCSI command, may need -i or -o as well\n"
8992 "smpcmd send the given SMP command, requires -o and -i\n"
8993 "smprg send the SMP Report General command\n"
8994 "smppc send the SMP PHY Control command, requires -p\n"
8995 "smpphylist display phys attached to a SAS expander\n"
8996 "smpmaninfo send the SMP Report Manufacturer Info command\n"
8997 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
8998 "tags report or set the number of transaction slots for a device\n"
8999 "negotiate report or set device negotiation parameters\n"
9000 "format send the SCSI FORMAT UNIT command to the named device\n"
9001 "sanitize send the SCSI SANITIZE command to the named device\n"
9002 "idle send the ATA IDLE command to the named device\n"
9003 "standby send the ATA STANDBY command to the named device\n"
9004 "sleep send the ATA SLEEP command to the named device\n"
9005 "fwdownload program firmware of the named device with the given image\n"
9006 "security report or send ATA security commands to the named device\n"
9007 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9008 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9009 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9010 "zone manage Zoned Block (Shingled) devices\n"
9011 "epc send ATA Extended Power Conditions commands\n"
9012 "timestamp report or set the device's timestamp\n"
9013 "help this message\n"
9014 "Device Identifiers:\n"
9015 "bus:target specify the bus and target, lun defaults to 0\n"
9016 "bus:target:lun specify the bus, target and lun\n"
9017 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
9018 "Generic arguments:\n"
9019 "-v be verbose, print out sense information\n"
9020 "-t timeout command timeout in seconds, overrides default timeout\n"
9021 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
9022 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
9023 "-E have the kernel attempt to perform SCSI error recovery\n"
9024 "-C count specify the SCSI command retry count (needs -E to work)\n"
9025 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
9026 "modepage arguments:\n"
9027 "-l list all available mode pages\n"
9028 "-m page specify the mode page to view or edit\n"
9029 "-e edit the specified mode page\n"
9030 "-b force view to binary mode\n"
9031 "-d disable block descriptors for mode sense\n"
9032 "-P pgctl page control field 0-3\n"
9033 "defects arguments:\n"
9034 "-f format specify defect list format (block, bfi or phys)\n"
9035 "-G get the grown defect list\n"
9036 "-P get the permanent defect list\n"
9037 "inquiry arguments:\n"
9038 "-D get the standard inquiry data\n"
9039 "-S get the serial number\n"
9040 "-R get the transfer rate, etc.\n"
9041 "reportluns arguments:\n"
9042 "-c only report a count of available LUNs\n"
9043 "-l only print out luns, and not a count\n"
9044 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
9045 "readcap arguments\n"
9046 "-b only report the blocksize\n"
9047 "-h human readable device size, base 2\n"
9048 "-H human readable device size, base 10\n"
9049 "-N print the number of blocks instead of last block\n"
9050 "-q quiet, print numbers only\n"
9051 "-s only report the last block/device size\n"
9053 "-c cdb [args] specify the SCSI CDB\n"
9054 "-i len fmt specify input data and input data format\n"
9055 "-o len fmt [args] specify output data and output data fmt\n"
9056 "smpcmd arguments:\n"
9057 "-r len fmt [args] specify the SMP command to be sent\n"
9058 "-R len fmt [args] specify SMP response format\n"
9059 "smprg arguments:\n"
9060 "-l specify the long response format\n"
9061 "smppc arguments:\n"
9062 "-p phy specify the PHY to operate on\n"
9063 "-l specify the long request/response format\n"
9064 "-o operation specify the phy control operation\n"
9065 "-d name set the attached device name\n"
9066 "-m rate set the minimum physical link rate\n"
9067 "-M rate set the maximum physical link rate\n"
9068 "-T pp_timeout set the partial pathway timeout value\n"
9069 "-a enable|disable enable or disable SATA slumber\n"
9070 "-A enable|disable enable or disable SATA partial phy power\n"
9071 "-s enable|disable enable or disable SAS slumber\n"
9072 "-S enable|disable enable or disable SAS partial phy power\n"
9073 "smpphylist arguments:\n"
9074 "-l specify the long response format\n"
9075 "-q only print phys with attached devices\n"
9076 "smpmaninfo arguments:\n"
9077 "-l specify the long response format\n"
9078 "debug arguments:\n"
9079 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
9080 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
9081 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
9082 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
9084 "-N tags specify the number of tags to use for this device\n"
9085 "-q be quiet, don't report the number of tags\n"
9086 "-v report a number of tag-related parameters\n"
9087 "negotiate arguments:\n"
9088 "-a send a test unit ready after negotiation\n"
9089 "-c report/set current negotiation settings\n"
9090 "-D <arg> \"enable\" or \"disable\" disconnection\n"
9091 "-M mode set ATA mode\n"
9092 "-O offset set command delay offset\n"
9093 "-q be quiet, don't report anything\n"
9094 "-R syncrate synchronization rate in MHz\n"
9095 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
9096 "-U report/set user negotiation settings\n"
9097 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
9098 "-v also print a Path Inquiry CCB for the controller\n"
9099 "format arguments:\n"
9100 "-q be quiet, don't print status messages\n"
9101 "-r run in report only mode\n"
9102 "-w don't send immediate format command\n"
9103 "-y don't ask any questions\n"
9104 "sanitize arguments:\n"
9105 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
9106 "-c passes overwrite passes to perform (1 to 31)\n"
9107 "-I invert overwrite pattern after each pass\n"
9108 "-P pattern path to overwrite pattern file\n"
9109 "-q be quiet, don't print status messages\n"
9110 "-r run in report only mode\n"
9111 "-U run operation in unrestricted completion exit mode\n"
9112 "-w don't send immediate sanitize command\n"
9113 "-y don't ask any questions\n"
9114 "idle/standby arguments:\n"
9115 "-t <arg> number of seconds before respective state.\n"
9116 "fwdownload arguments:\n"
9117 "-f fw_image path to firmware image file\n"
9118 "-q don't print informational messages, only errors\n"
9119 "-s run in simulation mode\n"
9120 "-v print info for every firmware segment sent to device\n"
9121 "-y don't ask any questions\n"
9122 "security arguments:\n"
9123 "-d pwd disable security using the given password for the selected\n"
9125 "-e pwd erase the device using the given pwd for the selected user\n"
9126 "-f freeze the security configuration of the specified device\n"
9127 "-h pwd enhanced erase the device using the given pwd for the\n"
9129 "-k pwd unlock the device using the given pwd for the selected\n"
9131 "-l <high|maximum> specifies which security level to set: high or maximum\n"
9132 "-q be quiet, do not print any status messages\n"
9133 "-s pwd password the device (enable security) using the given\n"
9134 " pwd for the selected user\n"
9135 "-T timeout overrides the timeout (seconds) used for erase operation\n"
9136 "-U <user|master> specifies which user to set: user or master\n"
9137 "-y don't ask any questions\n"
9139 "-f freeze the HPA configuration of the device\n"
9140 "-l lock the HPA configuration of the device\n"
9141 "-P make the HPA max sectors persist\n"
9142 "-p pwd Set the HPA configuration password required for unlock\n"
9144 "-q be quiet, do not print any status messages\n"
9145 "-s sectors configures the maximum user accessible sectors of the\n"
9147 "-U pwd unlock the HPA configuration of the device\n"
9148 "-y don't ask any questions\n"
9149 "persist arguments:\n"
9150 "-i action specify read_keys, read_reservation, report_cap, or\n"
9151 " read_full_status\n"
9152 "-o action specify register, register_ignore, reserve, release,\n"
9153 " clear, preempt, preempt_abort, register_move, replace_lost\n"
9154 "-a set the All Target Ports (ALL_TG_PT) bit\n"
9155 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
9156 "-k key specify the Reservation Key\n"
9157 "-K sa_key specify the Service Action Reservation Key\n"
9158 "-p set the Activate Persist Through Power Loss bit\n"
9159 "-R rtp specify the Relative Target Port\n"
9160 "-s scope specify the scope: lun, extent, element or a number\n"
9161 "-S specify Transport ID for register, requires -I\n"
9162 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
9163 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
9164 "-U unregister the current initiator for register_move\n"
9165 "attrib arguments:\n"
9166 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
9168 "-w attr specify an attribute to write, one -w argument per attr\n"
9169 "-a attr_num only display this attribute number\n"
9170 "-c get cached attributes\n"
9171 "-e elem_addr request attributes for the given element in a changer\n"
9172 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
9173 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
9174 " field_none, field_desc, field_num, field_size, field_rw\n"
9175 "-p partition request attributes for the given partition\n"
9176 "-s start_attr request attributes starting at the given number\n"
9177 "-T elem_type specify the element type (used with -e)\n"
9178 "-V logical_vol specify the logical volume ID\n"
9179 "opcodes arguments:\n"
9180 "-o opcode specify the individual opcode to list\n"
9181 "-s service_action specify the service action for the opcode\n"
9182 "-N do not return SCSI error for unsupported SA\n"
9183 "-T request nominal and recommended timeout values\n"
9185 "-c cmd required: rz, open, close, finish, or rwp\n"
9186 "-a apply the action to all zones\n"
9187 "-l LBA specify the zone starting LBA\n"
9188 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
9189 " closed, full, ro, offline, reset, nonseq, nonwp\n"
9190 "-P print_opt report zones printing: normal, summary, script\n"
9192 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
9193 " source, status, list\n"
9194 "-d disable power mode (timer, state)\n"
9195 "-D delayed entry (goto)\n"
9196 "-e enable power mode (timer, state)\n"
9197 "-H hold power mode (goto)\n"
9198 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
9200 "-P only display power mode (status)\n"
9201 "-r rst_src restore settings from: default, saved (restore)\n"
9202 "-s save mode (timer, state, restore)\n"
9203 "-S power_src set power source: battery, nonbattery (source)\n"
9204 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
9205 "timestamp arguments:\n"
9206 "-r report the timestamp of the device\n"
9207 "-f format report the timestamp of the device with the given\n"
9208 " strftime(3) format string\n"
9209 "-m report the timestamp of the device as milliseconds since\n"
9210 " January 1st, 1970\n"
9211 "-U report the time with UTC instead of the local time zone\n"
9212 "-s set the timestamp of the device\n"
9213 "-f format the format of the time string passed into strptime(3)\n"
9214 "-T time the time value passed into strptime(3)\n"
9215 "-U set the timestamp of the device to UTC time\n"
9217 #endif /* MINIMALISTIC */
9221 main(int argc, char **argv)
9224 char *device = NULL;
9226 struct cam_device *cam_dev = NULL;
9227 int timeout = 0, retry_count = 1;
9228 camcontrol_optret optreturn;
9230 const char *mainopt = "C:En:Q:t:u:v";
9231 const char *subopt = NULL;
9232 char combinedopt[256];
9233 int error = 0, optstart = 2;
9234 int task_attr = MSG_SIMPLE_Q_TAG;
9236 #ifndef MINIMALISTIC
9240 #endif /* MINIMALISTIC */
9242 cmdlist = CAM_CMD_NONE;
9243 arglist = CAM_ARG_NONE;
9251 * Get the base option.
9253 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
9255 if (optreturn == CC_OR_AMBIGUOUS) {
9256 warnx("ambiguous option %s", argv[1]);
9259 } else if (optreturn == CC_OR_NOT_FOUND) {
9260 warnx("option %s not found", argv[1]);
9266 * Ahh, getopt(3) is a pain.
9268 * This is a gross hack. There really aren't many other good
9269 * options (excuse the pun) for parsing options in a situation like
9270 * this. getopt is kinda braindead, so you end up having to run
9271 * through the options twice, and give each invocation of getopt
9272 * the option string for the other invocation.
9274 * You would think that you could just have two groups of options.
9275 * The first group would get parsed by the first invocation of
9276 * getopt, and the second group would get parsed by the second
9277 * invocation of getopt. It doesn't quite work out that way. When
9278 * the first invocation of getopt finishes, it leaves optind pointing
9279 * to the argument _after_ the first argument in the second group.
9280 * So when the second invocation of getopt comes around, it doesn't
9281 * recognize the first argument it gets and then bails out.
9283 * A nice alternative would be to have a flag for getopt that says
9284 * "just keep parsing arguments even when you encounter an unknown
9285 * argument", but there isn't one. So there's no real clean way to
9286 * easily parse two sets of arguments without having one invocation
9287 * of getopt know about the other.
9289 * Without this hack, the first invocation of getopt would work as
9290 * long as the generic arguments are first, but the second invocation
9291 * (in the subfunction) would fail in one of two ways. In the case
9292 * where you don't set optreset, it would fail because optind may be
9293 * pointing to the argument after the one it should be pointing at.
9294 * In the case where you do set optreset, and reset optind, it would
9295 * fail because getopt would run into the first set of options, which
9296 * it doesn't understand.
9298 * All of this would "sort of" work if you could somehow figure out
9299 * whether optind had been incremented one option too far. The
9300 * mechanics of that, however, are more daunting than just giving
9301 * both invocations all of the expect options for either invocation.
9303 * Needless to say, I wouldn't mind if someone invented a better
9304 * (non-GPL!) command line parsing interface than getopt. I
9305 * wouldn't mind if someone added more knobs to getopt to make it
9306 * work better. Who knows, I may talk myself into doing it someday,
9307 * if the standards weenies let me. As it is, it just leads to
9308 * hackery like this and causes people to avoid it in some cases.
9310 * KDM, September 8th, 1998
9313 sprintf(combinedopt, "%s%s", mainopt, subopt);
9315 sprintf(combinedopt, "%s", mainopt);
9318 * For these options we do not parse optional device arguments and
9319 * we do not open a passthrough device.
9321 if ((cmdlist == CAM_CMD_RESCAN)
9322 || (cmdlist == CAM_CMD_RESET)
9323 || (cmdlist == CAM_CMD_DEVTREE)
9324 || (cmdlist == CAM_CMD_USAGE)
9325 || (cmdlist == CAM_CMD_DEBUG))
9328 #ifndef MINIMALISTIC
9330 && (argc > 2 && argv[2][0] != '-')) {
9334 if (isdigit(argv[2][0])) {
9335 /* device specified as bus:target[:lun] */
9336 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9338 errx(1, "numeric device specification must "
9339 "be either bus:target, or "
9341 /* default to 0 if lun was not specified */
9342 if ((arglist & CAM_ARG_LUN) == 0) {
9344 arglist |= CAM_ARG_LUN;
9348 if (cam_get_device(argv[2], name, sizeof name, &unit)
9350 errx(1, "%s", cam_errbuf);
9351 device = strdup(name);
9352 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
9356 #endif /* MINIMALISTIC */
9358 * Start getopt processing at argv[2/3], since we've already
9359 * accepted argv[1..2] as the command name, and as a possible
9365 * Now we run through the argument list looking for generic
9366 * options, and ignoring options that possibly belong to
9369 while ((c = getopt(argc, argv, combinedopt))!= -1){
9372 retry_count = strtol(optarg, NULL, 0);
9373 if (retry_count < 0)
9374 errx(1, "retry count %d is < 0",
9376 arglist |= CAM_ARG_RETRIES;
9379 arglist |= CAM_ARG_ERR_RECOVER;
9382 arglist |= CAM_ARG_DEVICE;
9384 while (isspace(*tstr) && (*tstr != '\0'))
9386 device = (char *)strdup(tstr);
9390 int table_entry = 0;
9393 while (isspace(*tstr) && (*tstr != '\0'))
9395 if (isdigit(*tstr)) {
9396 task_attr = strtol(tstr, &endptr, 0);
9397 if (*endptr != '\0') {
9398 errx(1, "Invalid queue option "
9403 scsi_nv_status status;
9405 table_size = sizeof(task_attrs) /
9406 sizeof(task_attrs[0]);
9407 status = scsi_get_nv(task_attrs,
9408 table_size, tstr, &table_entry,
9409 SCSI_NV_FLAG_IG_CASE);
9410 if (status == SCSI_NV_FOUND)
9411 task_attr = task_attrs[
9414 errx(1, "%s option %s",
9415 (status == SCSI_NV_AMBIGUOUS)?
9416 "ambiguous" : "invalid",
9423 timeout = strtol(optarg, NULL, 0);
9425 errx(1, "invalid timeout %d", timeout);
9426 /* Convert the timeout from seconds to ms */
9428 arglist |= CAM_ARG_TIMEOUT;
9431 arglist |= CAM_ARG_UNIT;
9432 unit = strtol(optarg, NULL, 0);
9435 arglist |= CAM_ARG_VERBOSE;
9442 #ifndef MINIMALISTIC
9444 * For most commands we'll want to open the passthrough device
9445 * associated with the specified device. In the case of the rescan
9446 * commands, we don't use a passthrough device at all, just the
9447 * transport layer device.
9450 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
9451 && (((arglist & CAM_ARG_DEVICE) == 0)
9452 || ((arglist & CAM_ARG_UNIT) == 0))) {
9453 errx(1, "subcommand \"%s\" requires a valid device "
9454 "identifier", argv[1]);
9457 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
9458 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
9459 cam_open_spec_device(device,unit,O_RDWR,NULL)))
9461 errx(1,"%s", cam_errbuf);
9463 #endif /* MINIMALISTIC */
9466 * Reset optind to 2, and reset getopt, so these routines can parse
9467 * the arguments again.
9473 #ifndef MINIMALISTIC
9474 case CAM_CMD_DEVLIST:
9475 error = getdevlist(cam_dev);
9478 error = atahpa(cam_dev, retry_count, timeout,
9479 argc, argv, combinedopt);
9481 #endif /* MINIMALISTIC */
9482 case CAM_CMD_DEVTREE:
9483 error = getdevtree(argc, argv, combinedopt);
9485 #ifndef MINIMALISTIC
9487 error = testunitready(cam_dev, task_attr, retry_count,
9490 case CAM_CMD_INQUIRY:
9491 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
9492 task_attr, retry_count, timeout);
9494 case CAM_CMD_IDENTIFY:
9495 error = ataidentify(cam_dev, retry_count, timeout);
9497 case CAM_CMD_STARTSTOP:
9498 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
9499 arglist & CAM_ARG_EJECT, task_attr,
9500 retry_count, timeout);
9502 #endif /* MINIMALISTIC */
9503 case CAM_CMD_RESCAN:
9504 error = dorescan_or_reset(argc, argv, 1);
9507 error = dorescan_or_reset(argc, argv, 0);
9509 #ifndef MINIMALISTIC
9510 case CAM_CMD_READ_DEFECTS:
9511 error = readdefects(cam_dev, argc, argv, combinedopt,
9512 task_attr, retry_count, timeout);
9514 case CAM_CMD_MODE_PAGE:
9515 modepage(cam_dev, argc, argv, combinedopt,
9516 task_attr, retry_count, timeout);
9518 case CAM_CMD_SCSI_CMD:
9519 error = scsicmd(cam_dev, argc, argv, combinedopt,
9520 task_attr, retry_count, timeout);
9522 case CAM_CMD_SMP_CMD:
9523 error = smpcmd(cam_dev, argc, argv, combinedopt,
9524 retry_count, timeout);
9526 case CAM_CMD_SMP_RG:
9527 error = smpreportgeneral(cam_dev, argc, argv,
9528 combinedopt, retry_count,
9531 case CAM_CMD_SMP_PC:
9532 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
9533 retry_count, timeout);
9535 case CAM_CMD_SMP_PHYLIST:
9536 error = smpphylist(cam_dev, argc, argv, combinedopt,
9537 retry_count, timeout);
9539 case CAM_CMD_SMP_MANINFO:
9540 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
9541 retry_count, timeout);
9544 error = camdebug(argc, argv, combinedopt);
9547 error = tagcontrol(cam_dev, argc, argv, combinedopt);
9550 error = ratecontrol(cam_dev, task_attr, retry_count,
9551 timeout, argc, argv, combinedopt);
9553 case CAM_CMD_FORMAT:
9554 error = scsiformat(cam_dev, argc, argv,
9555 combinedopt, task_attr, retry_count,
9558 case CAM_CMD_REPORTLUNS:
9559 error = scsireportluns(cam_dev, argc, argv,
9560 combinedopt, task_attr,
9561 retry_count, timeout);
9563 case CAM_CMD_READCAP:
9564 error = scsireadcapacity(cam_dev, argc, argv,
9565 combinedopt, task_attr,
9566 retry_count, timeout);
9569 case CAM_CMD_STANDBY:
9571 error = atapm(cam_dev, argc, argv,
9572 combinedopt, retry_count, timeout);
9576 error = ataaxm(cam_dev, argc, argv,
9577 combinedopt, retry_count, timeout);
9579 case CAM_CMD_SECURITY:
9580 error = atasecurity(cam_dev, retry_count, timeout,
9581 argc, argv, combinedopt);
9583 case CAM_CMD_DOWNLOAD_FW:
9584 error = fwdownload(cam_dev, argc, argv, combinedopt,
9585 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
9588 case CAM_CMD_SANITIZE:
9589 error = scsisanitize(cam_dev, argc, argv,
9590 combinedopt, task_attr,
9591 retry_count, timeout);
9593 case CAM_CMD_PERSIST:
9594 error = scsipersist(cam_dev, argc, argv, combinedopt,
9595 task_attr, retry_count, timeout,
9596 arglist & CAM_ARG_VERBOSE,
9597 arglist & CAM_ARG_ERR_RECOVER);
9599 case CAM_CMD_ATTRIB:
9600 error = scsiattrib(cam_dev, argc, argv, combinedopt,
9601 task_attr, retry_count, timeout,
9602 arglist & CAM_ARG_VERBOSE,
9603 arglist & CAM_ARG_ERR_RECOVER);
9605 case CAM_CMD_OPCODES:
9606 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
9607 task_attr, retry_count, timeout,
9608 arglist & CAM_ARG_VERBOSE);
9610 case CAM_CMD_REPROBE:
9611 error = scsireprobe(cam_dev);
9614 error = zone(cam_dev, argc, argv, combinedopt,
9615 task_attr, retry_count, timeout,
9616 arglist & CAM_ARG_VERBOSE);
9619 error = epc(cam_dev, argc, argv, combinedopt,
9620 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9622 case CAM_CMD_TIMESTAMP:
9623 error = timestamp(cam_dev, argc, argv, combinedopt,
9624 task_attr, retry_count, timeout,
9625 arglist & CAM_ARG_VERBOSE);
9627 #endif /* MINIMALISTIC */
9637 if (cam_dev != NULL)
9638 cam_close_device(cam_dev);