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 < UINT8_MAX; 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 < UINT32_MAX; i = i << 1) {
5375 if ((i & cpi->hba_misc) == 0)
5378 fprintf(stdout, "%s ", adapter_str);
5382 str = "can understand ata_ext requests";
5385 str = "64bit extended LUNs supported";
5388 str = "bus scans from high ID to low ID";
5391 str = "removable devices not included in scan";
5393 case PIM_NOINITIATOR:
5394 str = "initiator role not supported";
5396 case PIM_NOBUSRESET:
5397 str = "user has disabled initial BUS RESET or"
5398 " controller is in target/mixed mode";
5401 str = "do not send 6-byte commands";
5404 str = "scan bus sequentially";
5407 str = "unmapped I/O supported";
5410 str = "does its own scanning";
5413 str = "unknown PIM bit set";
5416 fprintf(stdout, "%s\n", str);
5419 for (i = 1; i < UINT16_MAX; i = i << 1) {
5422 if ((i & cpi->target_sprt) == 0)
5425 fprintf(stdout, "%s supports ", adapter_str);
5428 str = "target mode processor mode";
5431 str = "target mode phase cog. mode";
5433 case PIT_DISCONNECT:
5434 str = "disconnects in target mode";
5437 str = "terminate I/O message in target mode";
5440 str = "group 6 commands in target mode";
5443 str = "group 7 commands in target mode";
5446 str = "unknown PIT bit set";
5450 fprintf(stdout, "%s\n", str);
5452 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5454 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5456 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5458 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5459 adapter_str, cpi->hpath_id);
5460 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5462 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5463 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5464 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5465 adapter_str, cpi->hba_vendor);
5466 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5467 adapter_str, cpi->hba_device);
5468 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5469 adapter_str, cpi->hba_subvendor);
5470 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5471 adapter_str, cpi->hba_subdevice);
5472 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5473 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5474 if (cpi->base_transfer_speed > 1000)
5475 fprintf(stdout, "%d.%03dMB/sec\n",
5476 cpi->base_transfer_speed / 1000,
5477 cpi->base_transfer_speed % 1000);
5479 fprintf(stdout, "%dKB/sec\n",
5480 (cpi->base_transfer_speed % 1000) * 1000);
5481 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5482 adapter_str, cpi->maxio);
5486 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5487 struct ccb_trans_settings *cts)
5493 ccb = cam_getccb(device);
5496 warnx("get_print_cts: error allocating ccb");
5500 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5502 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5504 if (user_settings == 0)
5505 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5507 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5509 if (cam_send_ccb(device, ccb) < 0) {
5510 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5511 if (arglist & CAM_ARG_VERBOSE)
5512 cam_error_print(device, ccb, CAM_ESF_ALL,
5513 CAM_EPF_ALL, stderr);
5515 goto get_print_cts_bailout;
5518 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5519 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5520 if (arglist & CAM_ARG_VERBOSE)
5521 cam_error_print(device, ccb, CAM_ESF_ALL,
5522 CAM_EPF_ALL, stderr);
5524 goto get_print_cts_bailout;
5528 cts_print(device, &ccb->cts);
5531 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5533 get_print_cts_bailout:
5541 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
5542 int timeout, int argc, char **argv, char *combinedopt)
5546 int user_settings = 0;
5548 int disc_enable = -1, tag_enable = -1;
5551 double syncrate = -1;
5554 int change_settings = 0, send_tur = 0;
5555 struct ccb_pathinq cpi;
5557 ccb = cam_getccb(device);
5559 warnx("ratecontrol: error allocating ccb");
5562 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5571 if (strncasecmp(optarg, "enable", 6) == 0)
5573 else if (strncasecmp(optarg, "disable", 7) == 0)
5576 warnx("-D argument \"%s\" is unknown", optarg);
5578 goto ratecontrol_bailout;
5580 change_settings = 1;
5583 mode = ata_string2mode(optarg);
5585 warnx("unknown mode '%s'", optarg);
5587 goto ratecontrol_bailout;
5589 change_settings = 1;
5592 offset = strtol(optarg, NULL, 0);
5594 warnx("offset value %d is < 0", offset);
5596 goto ratecontrol_bailout;
5598 change_settings = 1;
5604 syncrate = atof(optarg);
5606 warnx("sync rate %f is < 0", syncrate);
5608 goto ratecontrol_bailout;
5610 change_settings = 1;
5613 if (strncasecmp(optarg, "enable", 6) == 0)
5615 else if (strncasecmp(optarg, "disable", 7) == 0)
5618 warnx("-T argument \"%s\" is unknown", optarg);
5620 goto ratecontrol_bailout;
5622 change_settings = 1;
5628 bus_width = strtol(optarg, NULL, 0);
5629 if (bus_width < 0) {
5630 warnx("bus width %d is < 0", bus_width);
5632 goto ratecontrol_bailout;
5634 change_settings = 1;
5640 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5642 * Grab path inquiry information, so we can determine whether
5643 * or not the initiator is capable of the things that the user
5646 ccb->ccb_h.func_code = XPT_PATH_INQ;
5647 if (cam_send_ccb(device, ccb) < 0) {
5648 perror("error sending XPT_PATH_INQ CCB");
5649 if (arglist & CAM_ARG_VERBOSE) {
5650 cam_error_print(device, ccb, CAM_ESF_ALL,
5651 CAM_EPF_ALL, stderr);
5654 goto ratecontrol_bailout;
5656 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5657 warnx("XPT_PATH_INQ CCB failed");
5658 if (arglist & CAM_ARG_VERBOSE) {
5659 cam_error_print(device, ccb, CAM_ESF_ALL,
5660 CAM_EPF_ALL, stderr);
5663 goto ratecontrol_bailout;
5665 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5666 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5668 fprintf(stdout, "%s parameters:\n",
5669 user_settings ? "User" : "Current");
5671 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5673 goto ratecontrol_bailout;
5675 if (arglist & CAM_ARG_VERBOSE)
5678 if (change_settings) {
5679 int didsettings = 0;
5680 struct ccb_trans_settings_spi *spi = NULL;
5681 struct ccb_trans_settings_pata *pata = NULL;
5682 struct ccb_trans_settings_sata *sata = NULL;
5683 struct ccb_trans_settings_ata *ata = NULL;
5684 struct ccb_trans_settings_scsi *scsi = NULL;
5686 if (ccb->cts.transport == XPORT_SPI)
5687 spi = &ccb->cts.xport_specific.spi;
5688 if (ccb->cts.transport == XPORT_ATA)
5689 pata = &ccb->cts.xport_specific.ata;
5690 if (ccb->cts.transport == XPORT_SATA)
5691 sata = &ccb->cts.xport_specific.sata;
5692 if (ccb->cts.protocol == PROTO_ATA)
5693 ata = &ccb->cts.proto_specific.ata;
5694 if (ccb->cts.protocol == PROTO_SCSI)
5695 scsi = &ccb->cts.proto_specific.scsi;
5696 ccb->cts.xport_specific.valid = 0;
5697 ccb->cts.proto_specific.valid = 0;
5698 if (spi && disc_enable != -1) {
5699 spi->valid |= CTS_SPI_VALID_DISC;
5700 if (disc_enable == 0)
5701 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5703 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5706 if (tag_enable != -1) {
5707 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5708 warnx("HBA does not support tagged queueing, "
5709 "so you cannot modify tag settings");
5711 goto ratecontrol_bailout;
5714 ata->valid |= CTS_SCSI_VALID_TQ;
5715 if (tag_enable == 0)
5716 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5718 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5721 scsi->valid |= CTS_SCSI_VALID_TQ;
5722 if (tag_enable == 0)
5723 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5725 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5729 if (spi && offset != -1) {
5730 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5731 warnx("HBA is not capable of changing offset");
5733 goto ratecontrol_bailout;
5735 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5736 spi->sync_offset = offset;
5739 if (spi && syncrate != -1) {
5740 int prelim_sync_period;
5742 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5743 warnx("HBA is not capable of changing "
5746 goto ratecontrol_bailout;
5748 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5750 * The sync rate the user gives us is in MHz.
5751 * We need to translate it into KHz for this
5756 * Next, we calculate a "preliminary" sync period
5757 * in tenths of a nanosecond.
5760 prelim_sync_period = 0;
5762 prelim_sync_period = 10000000 / syncrate;
5764 scsi_calc_syncparam(prelim_sync_period);
5767 if (sata && syncrate != -1) {
5768 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5769 warnx("HBA is not capable of changing "
5772 goto ratecontrol_bailout;
5774 if (!user_settings) {
5775 warnx("You can modify only user rate "
5776 "settings for SATA");
5778 goto ratecontrol_bailout;
5780 sata->revision = ata_speed2revision(syncrate * 100);
5781 if (sata->revision < 0) {
5782 warnx("Invalid rate %f", syncrate);
5784 goto ratecontrol_bailout;
5786 sata->valid |= CTS_SATA_VALID_REVISION;
5789 if ((pata || sata) && mode != -1) {
5790 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5791 warnx("HBA is not capable of changing "
5794 goto ratecontrol_bailout;
5796 if (!user_settings) {
5797 warnx("You can modify only user mode "
5798 "settings for ATA/SATA");
5800 goto ratecontrol_bailout;
5804 pata->valid |= CTS_ATA_VALID_MODE;
5807 sata->valid |= CTS_SATA_VALID_MODE;
5812 * The bus_width argument goes like this:
5816 * Therefore, if you shift the number of bits given on the
5817 * command line right by 4, you should get the correct
5820 if (spi && bus_width != -1) {
5822 * We might as well validate things here with a
5823 * decipherable error message, rather than what
5824 * will probably be an indecipherable error message
5825 * by the time it gets back to us.
5827 if ((bus_width == 16)
5828 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5829 warnx("HBA does not support 16 bit bus width");
5831 goto ratecontrol_bailout;
5832 } else if ((bus_width == 32)
5833 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5834 warnx("HBA does not support 32 bit bus width");
5836 goto ratecontrol_bailout;
5837 } else if ((bus_width != 8)
5838 && (bus_width != 16)
5839 && (bus_width != 32)) {
5840 warnx("Invalid bus width %d", bus_width);
5842 goto ratecontrol_bailout;
5844 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5845 spi->bus_width = bus_width >> 4;
5848 if (didsettings == 0) {
5849 goto ratecontrol_bailout;
5851 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5852 if (cam_send_ccb(device, ccb) < 0) {
5853 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5854 if (arglist & CAM_ARG_VERBOSE) {
5855 cam_error_print(device, ccb, CAM_ESF_ALL,
5856 CAM_EPF_ALL, stderr);
5859 goto ratecontrol_bailout;
5861 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5862 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5863 if (arglist & CAM_ARG_VERBOSE) {
5864 cam_error_print(device, ccb, CAM_ESF_ALL,
5865 CAM_EPF_ALL, stderr);
5868 goto ratecontrol_bailout;
5872 retval = testunitready(device, task_attr, retry_count, timeout,
5873 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5875 * If the TUR didn't succeed, just bail.
5879 fprintf(stderr, "Test Unit Ready failed\n");
5880 goto ratecontrol_bailout;
5883 if ((change_settings || send_tur) && !quiet &&
5884 (ccb->cts.transport == XPORT_ATA ||
5885 ccb->cts.transport == XPORT_SATA || send_tur)) {
5886 fprintf(stdout, "New parameters:\n");
5887 retval = get_print_cts(device, user_settings, 0, NULL);
5890 ratecontrol_bailout:
5896 scsiformat(struct cam_device *device, int argc, char **argv,
5897 char *combinedopt, int task_attr, int retry_count, int timeout)
5901 int ycount = 0, quiet = 0;
5902 int error = 0, retval = 0;
5903 int use_timeout = 10800 * 1000;
5905 struct format_defect_list_header fh;
5906 u_int8_t *data_ptr = NULL;
5907 u_int32_t dxfer_len = 0;
5909 int num_warnings = 0;
5912 ccb = cam_getccb(device);
5915 warnx("scsiformat: error allocating ccb");
5919 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5921 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5942 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
5943 "following device:\n");
5945 error = scsidoinquiry(device, argc, argv, combinedopt,
5946 task_attr, retry_count, timeout);
5949 warnx("scsiformat: error sending inquiry");
5950 goto scsiformat_bailout;
5955 if (!get_confirmation()) {
5957 goto scsiformat_bailout;
5962 use_timeout = timeout;
5965 fprintf(stdout, "Current format timeout is %d seconds\n",
5966 use_timeout / 1000);
5970 * If the user hasn't disabled questions and didn't specify a
5971 * timeout on the command line, ask them if they want the current
5975 && (timeout == 0)) {
5977 int new_timeout = 0;
5979 fprintf(stdout, "Enter new timeout in seconds or press\n"
5980 "return to keep the current timeout [%d] ",
5981 use_timeout / 1000);
5983 if (fgets(str, sizeof(str), stdin) != NULL) {
5985 new_timeout = atoi(str);
5988 if (new_timeout != 0) {
5989 use_timeout = new_timeout * 1000;
5990 fprintf(stdout, "Using new timeout value %d\n",
5991 use_timeout / 1000);
5996 * Keep this outside the if block below to silence any unused
5997 * variable warnings.
5999 bzero(&fh, sizeof(fh));
6002 * If we're in immediate mode, we've got to include the format
6005 if (immediate != 0) {
6006 fh.byte2 = FU_DLH_IMMED;
6007 data_ptr = (u_int8_t *)&fh;
6008 dxfer_len = sizeof(fh);
6009 byte2 = FU_FMT_DATA;
6010 } else if (quiet == 0) {
6011 fprintf(stdout, "Formatting...");
6015 scsi_format_unit(&ccb->csio,
6016 /* retries */ retry_count,
6018 /* tag_action */ task_attr,
6021 /* data_ptr */ data_ptr,
6022 /* dxfer_len */ dxfer_len,
6023 /* sense_len */ SSD_FULL_SIZE,
6024 /* timeout */ use_timeout);
6026 /* Disable freezing the device queue */
6027 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6029 if (arglist & CAM_ARG_ERR_RECOVER)
6030 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6032 if (((retval = cam_send_ccb(device, ccb)) < 0)
6033 || ((immediate == 0)
6034 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6035 const char errstr[] = "error sending format command";
6042 if (arglist & CAM_ARG_VERBOSE) {
6043 cam_error_print(device, ccb, CAM_ESF_ALL,
6044 CAM_EPF_ALL, stderr);
6047 goto scsiformat_bailout;
6051 * If we ran in non-immediate mode, we already checked for errors
6052 * above and printed out any necessary information. If we're in
6053 * immediate mode, we need to loop through and get status
6054 * information periodically.
6056 if (immediate == 0) {
6058 fprintf(stdout, "Format Complete\n");
6060 goto scsiformat_bailout;
6067 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6070 * There's really no need to do error recovery or
6071 * retries here, since we're just going to sit in a
6072 * loop and wait for the device to finish formatting.
6074 scsi_test_unit_ready(&ccb->csio,
6077 /* tag_action */ task_attr,
6078 /* sense_len */ SSD_FULL_SIZE,
6079 /* timeout */ 5000);
6081 /* Disable freezing the device queue */
6082 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6084 retval = cam_send_ccb(device, ccb);
6087 * If we get an error from the ioctl, bail out. SCSI
6088 * errors are expected.
6091 warn("error sending CAMIOCOMMAND ioctl");
6092 if (arglist & CAM_ARG_VERBOSE) {
6093 cam_error_print(device, ccb, CAM_ESF_ALL,
6094 CAM_EPF_ALL, stderr);
6097 goto scsiformat_bailout;
6100 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6102 if ((status != CAM_REQ_CMP)
6103 && (status == CAM_SCSI_STATUS_ERROR)
6104 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6105 struct scsi_sense_data *sense;
6106 int error_code, sense_key, asc, ascq;
6108 sense = &ccb->csio.sense_data;
6109 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6110 ccb->csio.sense_resid, &error_code, &sense_key,
6111 &asc, &ascq, /*show_errors*/ 1);
6114 * According to the SCSI-2 and SCSI-3 specs, a
6115 * drive that is in the middle of a format should
6116 * return NOT READY with an ASC of "logical unit
6117 * not ready, format in progress". The sense key
6118 * specific bytes will then be a progress indicator.
6120 if ((sense_key == SSD_KEY_NOT_READY)
6121 && (asc == 0x04) && (ascq == 0x04)) {
6124 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6125 ccb->csio.sense_resid, sks) == 0)
6128 u_int64_t percentage;
6130 val = scsi_2btoul(&sks[1]);
6131 percentage = 10000 * val;
6134 "\rFormatting: %ju.%02u %% "
6136 (uintmax_t)(percentage /
6138 (unsigned)((percentage /
6142 } else if ((quiet == 0)
6143 && (++num_warnings <= 1)) {
6144 warnx("Unexpected SCSI Sense Key "
6145 "Specific value returned "
6147 scsi_sense_print(device, &ccb->csio,
6149 warnx("Unable to print status "
6150 "information, but format will "
6152 warnx("will exit when format is "
6157 warnx("Unexpected SCSI error during format");
6158 cam_error_print(device, ccb, CAM_ESF_ALL,
6159 CAM_EPF_ALL, stderr);
6161 goto scsiformat_bailout;
6164 } else if (status != CAM_REQ_CMP) {
6165 warnx("Unexpected CAM status %#x", status);
6166 if (arglist & CAM_ARG_VERBOSE)
6167 cam_error_print(device, ccb, CAM_ESF_ALL,
6168 CAM_EPF_ALL, stderr);
6170 goto scsiformat_bailout;
6173 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6176 fprintf(stdout, "\nFormat Complete\n");
6186 scsisanitize(struct cam_device *device, int argc, char **argv,
6187 char *combinedopt, int task_attr, int retry_count, int timeout)
6190 u_int8_t action = 0;
6192 int ycount = 0, quiet = 0;
6193 int error = 0, retval = 0;
6194 int use_timeout = 10800 * 1000;
6200 const char *pattern = NULL;
6201 u_int8_t *data_ptr = NULL;
6202 u_int32_t dxfer_len = 0;
6204 int num_warnings = 0;
6207 ccb = cam_getccb(device);
6210 warnx("scsisanitize: error allocating ccb");
6214 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6216 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6219 if (strcasecmp(optarg, "overwrite") == 0)
6220 action = SSZ_SERVICE_ACTION_OVERWRITE;
6221 else if (strcasecmp(optarg, "block") == 0)
6222 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6223 else if (strcasecmp(optarg, "crypto") == 0)
6224 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6225 else if (strcasecmp(optarg, "exitfailure") == 0)
6226 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6228 warnx("invalid service operation \"%s\"",
6231 goto scsisanitize_bailout;
6235 passes = strtol(optarg, NULL, 0);
6236 if (passes < 1 || passes > 31) {
6237 warnx("invalid passes value %d", passes);
6239 goto scsisanitize_bailout;
6270 warnx("an action is required");
6272 goto scsisanitize_bailout;
6273 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6274 struct scsi_sanitize_parameter_list *pl;
6278 if (pattern == NULL) {
6279 warnx("overwrite action requires -P argument");
6281 goto scsisanitize_bailout;
6283 fd = open(pattern, O_RDONLY);
6285 warn("cannot open pattern file %s", pattern);
6287 goto scsisanitize_bailout;
6289 if (fstat(fd, &sb) < 0) {
6290 warn("cannot stat pattern file %s", pattern);
6292 goto scsisanitize_bailout;
6295 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6296 warnx("pattern file size exceeds maximum value %d",
6297 SSZPL_MAX_PATTERN_LENGTH);
6299 goto scsisanitize_bailout;
6301 dxfer_len = sizeof(*pl) + sz;
6302 data_ptr = calloc(1, dxfer_len);
6303 if (data_ptr == NULL) {
6304 warnx("cannot allocate parameter list buffer");
6306 goto scsisanitize_bailout;
6309 amt = read(fd, data_ptr + sizeof(*pl), sz);
6311 warn("cannot read pattern file");
6313 goto scsisanitize_bailout;
6314 } else if (amt != sz) {
6315 warnx("short pattern file read");
6317 goto scsisanitize_bailout;
6320 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6326 pl->byte1 |= SSZPL_INVERT;
6327 scsi_ulto2b(sz, pl->length);
6333 else if (invert != 0)
6335 else if (pattern != NULL)
6340 warnx("%s argument only valid with overwrite "
6343 goto scsisanitize_bailout;
6348 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6349 "following device:\n");
6351 error = scsidoinquiry(device, argc, argv, combinedopt,
6352 task_attr, retry_count, timeout);
6355 warnx("scsisanitize: error sending inquiry");
6356 goto scsisanitize_bailout;
6361 if (!get_confirmation()) {
6363 goto scsisanitize_bailout;
6368 use_timeout = timeout;
6371 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6372 use_timeout / 1000);
6376 * If the user hasn't disabled questions and didn't specify a
6377 * timeout on the command line, ask them if they want the current
6381 && (timeout == 0)) {
6383 int new_timeout = 0;
6385 fprintf(stdout, "Enter new timeout in seconds or press\n"
6386 "return to keep the current timeout [%d] ",
6387 use_timeout / 1000);
6389 if (fgets(str, sizeof(str), stdin) != NULL) {
6391 new_timeout = atoi(str);
6394 if (new_timeout != 0) {
6395 use_timeout = new_timeout * 1000;
6396 fprintf(stdout, "Using new timeout value %d\n",
6397 use_timeout / 1000);
6403 byte2 |= SSZ_UNRESTRICTED_EXIT;
6407 scsi_sanitize(&ccb->csio,
6408 /* retries */ retry_count,
6410 /* tag_action */ task_attr,
6413 /* data_ptr */ data_ptr,
6414 /* dxfer_len */ dxfer_len,
6415 /* sense_len */ SSD_FULL_SIZE,
6416 /* timeout */ use_timeout);
6418 /* Disable freezing the device queue */
6419 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6421 if (arglist & CAM_ARG_ERR_RECOVER)
6422 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6424 if (cam_send_ccb(device, ccb) < 0) {
6425 warn("error sending sanitize command");
6427 goto scsisanitize_bailout;
6430 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6431 struct scsi_sense_data *sense;
6432 int error_code, sense_key, asc, ascq;
6434 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6435 CAM_SCSI_STATUS_ERROR) {
6436 sense = &ccb->csio.sense_data;
6437 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6438 ccb->csio.sense_resid, &error_code, &sense_key,
6439 &asc, &ascq, /*show_errors*/ 1);
6441 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6442 asc == 0x20 && ascq == 0x00)
6443 warnx("sanitize is not supported by "
6446 warnx("error sanitizing this device");
6448 warnx("error sanitizing this device");
6450 if (arglist & CAM_ARG_VERBOSE) {
6451 cam_error_print(device, ccb, CAM_ESF_ALL,
6452 CAM_EPF_ALL, stderr);
6455 goto scsisanitize_bailout;
6459 * If we ran in non-immediate mode, we already checked for errors
6460 * above and printed out any necessary information. If we're in
6461 * immediate mode, we need to loop through and get status
6462 * information periodically.
6464 if (immediate == 0) {
6466 fprintf(stdout, "Sanitize Complete\n");
6468 goto scsisanitize_bailout;
6475 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6478 * There's really no need to do error recovery or
6479 * retries here, since we're just going to sit in a
6480 * loop and wait for the device to finish sanitizing.
6482 scsi_test_unit_ready(&ccb->csio,
6485 /* tag_action */ task_attr,
6486 /* sense_len */ SSD_FULL_SIZE,
6487 /* timeout */ 5000);
6489 /* Disable freezing the device queue */
6490 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6492 retval = cam_send_ccb(device, ccb);
6495 * If we get an error from the ioctl, bail out. SCSI
6496 * errors are expected.
6499 warn("error sending CAMIOCOMMAND ioctl");
6500 if (arglist & CAM_ARG_VERBOSE) {
6501 cam_error_print(device, ccb, CAM_ESF_ALL,
6502 CAM_EPF_ALL, stderr);
6505 goto scsisanitize_bailout;
6508 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6510 if ((status != CAM_REQ_CMP)
6511 && (status == CAM_SCSI_STATUS_ERROR)
6512 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6513 struct scsi_sense_data *sense;
6514 int error_code, sense_key, asc, ascq;
6516 sense = &ccb->csio.sense_data;
6517 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6518 ccb->csio.sense_resid, &error_code, &sense_key,
6519 &asc, &ascq, /*show_errors*/ 1);
6522 * According to the SCSI-3 spec, a drive that is in the
6523 * middle of a sanitize should return NOT READY with an
6524 * ASC of "logical unit not ready, sanitize in
6525 * progress". The sense key specific bytes will then
6526 * be a progress indicator.
6528 if ((sense_key == SSD_KEY_NOT_READY)
6529 && (asc == 0x04) && (ascq == 0x1b)) {
6532 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6533 ccb->csio.sense_resid, sks) == 0)
6536 u_int64_t percentage;
6538 val = scsi_2btoul(&sks[1]);
6539 percentage = 10000 * val;
6542 "\rSanitizing: %ju.%02u %% "
6544 (uintmax_t)(percentage /
6546 (unsigned)((percentage /
6550 } else if ((quiet == 0)
6551 && (++num_warnings <= 1)) {
6552 warnx("Unexpected SCSI Sense Key "
6553 "Specific value returned "
6554 "during sanitize:");
6555 scsi_sense_print(device, &ccb->csio,
6557 warnx("Unable to print status "
6558 "information, but sanitze will "
6560 warnx("will exit when sanitize is "
6565 warnx("Unexpected SCSI error during sanitize");
6566 cam_error_print(device, ccb, CAM_ESF_ALL,
6567 CAM_EPF_ALL, stderr);
6569 goto scsisanitize_bailout;
6572 } else if (status != CAM_REQ_CMP) {
6573 warnx("Unexpected CAM status %#x", status);
6574 if (arglist & CAM_ARG_VERBOSE)
6575 cam_error_print(device, ccb, CAM_ESF_ALL,
6576 CAM_EPF_ALL, stderr);
6578 goto scsisanitize_bailout;
6580 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6583 fprintf(stdout, "\nSanitize Complete\n");
6585 scsisanitize_bailout:
6588 if (data_ptr != NULL)
6596 scsireportluns(struct cam_device *device, int argc, char **argv,
6597 char *combinedopt, int task_attr, int retry_count, int timeout)
6600 int c, countonly, lunsonly;
6601 struct scsi_report_luns_data *lundata;
6603 uint8_t report_type;
6604 uint32_t list_len, i, j;
6609 report_type = RPL_REPORT_DEFAULT;
6610 ccb = cam_getccb(device);
6613 warnx("%s: error allocating ccb", __func__);
6617 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6622 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6631 if (strcasecmp(optarg, "default") == 0)
6632 report_type = RPL_REPORT_DEFAULT;
6633 else if (strcasecmp(optarg, "wellknown") == 0)
6634 report_type = RPL_REPORT_WELLKNOWN;
6635 else if (strcasecmp(optarg, "all") == 0)
6636 report_type = RPL_REPORT_ALL;
6638 warnx("%s: invalid report type \"%s\"",
6649 if ((countonly != 0)
6650 && (lunsonly != 0)) {
6651 warnx("%s: you can only specify one of -c or -l", __func__);
6656 * According to SPC-4, the allocation length must be at least 16
6657 * bytes -- enough for the header and one LUN.
6659 alloc_len = sizeof(*lundata) + 8;
6663 lundata = malloc(alloc_len);
6665 if (lundata == NULL) {
6666 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6671 scsi_report_luns(&ccb->csio,
6672 /*retries*/ retry_count,
6674 /*tag_action*/ task_attr,
6675 /*select_report*/ report_type,
6676 /*rpl_buf*/ lundata,
6677 /*alloc_len*/ alloc_len,
6678 /*sense_len*/ SSD_FULL_SIZE,
6679 /*timeout*/ timeout ? timeout : 5000);
6681 /* Disable freezing the device queue */
6682 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6684 if (arglist & CAM_ARG_ERR_RECOVER)
6685 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6687 if (cam_send_ccb(device, ccb) < 0) {
6688 warn("error sending REPORT LUNS command");
6690 if (arglist & CAM_ARG_VERBOSE)
6691 cam_error_print(device, ccb, CAM_ESF_ALL,
6692 CAM_EPF_ALL, stderr);
6698 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6699 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6705 list_len = scsi_4btoul(lundata->length);
6708 * If we need to list the LUNs, and our allocation
6709 * length was too short, reallocate and retry.
6711 if ((countonly == 0)
6712 && (list_len > (alloc_len - sizeof(*lundata)))) {
6713 alloc_len = list_len + sizeof(*lundata);
6719 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6720 ((list_len / 8) > 1) ? "s" : "");
6725 for (i = 0; i < (list_len / 8); i++) {
6729 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6731 fprintf(stdout, ",");
6732 switch (lundata->luns[i].lundata[j] &
6733 RPL_LUNDATA_ATYP_MASK) {
6734 case RPL_LUNDATA_ATYP_PERIPH:
6735 if ((lundata->luns[i].lundata[j] &
6736 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6737 fprintf(stdout, "%d:",
6738 lundata->luns[i].lundata[j] &
6739 RPL_LUNDATA_PERIPH_BUS_MASK);
6741 && ((lundata->luns[i].lundata[j+2] &
6742 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6745 fprintf(stdout, "%d",
6746 lundata->luns[i].lundata[j+1]);
6748 case RPL_LUNDATA_ATYP_FLAT: {
6750 tmplun[0] = lundata->luns[i].lundata[j] &
6751 RPL_LUNDATA_FLAT_LUN_MASK;
6752 tmplun[1] = lundata->luns[i].lundata[j+1];
6754 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6758 case RPL_LUNDATA_ATYP_LUN:
6759 fprintf(stdout, "%d:%d:%d",
6760 (lundata->luns[i].lundata[j+1] &
6761 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6762 lundata->luns[i].lundata[j] &
6763 RPL_LUNDATA_LUN_TARG_MASK,
6764 lundata->luns[i].lundata[j+1] &
6765 RPL_LUNDATA_LUN_LUN_MASK);
6767 case RPL_LUNDATA_ATYP_EXTLUN: {
6768 int field_len_code, eam_code;
6770 eam_code = lundata->luns[i].lundata[j] &
6771 RPL_LUNDATA_EXT_EAM_MASK;
6772 field_len_code = (lundata->luns[i].lundata[j] &
6773 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6775 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6776 && (field_len_code == 0x00)) {
6777 fprintf(stdout, "%d",
6778 lundata->luns[i].lundata[j+1]);
6779 } else if ((eam_code ==
6780 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6781 && (field_len_code == 0x03)) {
6785 * This format takes up all 8 bytes.
6786 * If we aren't starting at offset 0,
6790 fprintf(stdout, "Invalid "
6793 "specified format", j);
6797 bzero(tmp_lun, sizeof(tmp_lun));
6798 bcopy(&lundata->luns[i].lundata[j+1],
6799 &tmp_lun[1], sizeof(tmp_lun) - 1);
6800 fprintf(stdout, "%#jx",
6801 (intmax_t)scsi_8btou64(tmp_lun));
6804 fprintf(stderr, "Unknown Extended LUN"
6805 "Address method %#x, length "
6806 "code %#x", eam_code,
6813 fprintf(stderr, "Unknown LUN address method "
6814 "%#x\n", lundata->luns[i].lundata[0] &
6815 RPL_LUNDATA_ATYP_MASK);
6819 * For the flat addressing method, there are no
6820 * other levels after it.
6825 fprintf(stdout, "\n");
6838 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6839 char *combinedopt, int task_attr, int retry_count, int timeout)
6842 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6843 struct scsi_read_capacity_data rcap;
6844 struct scsi_read_capacity_data_long rcaplong;
6858 ccb = cam_getccb(device);
6861 warnx("%s: error allocating ccb", __func__);
6865 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6867 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6894 if ((blocksizeonly != 0)
6895 && (numblocks != 0)) {
6896 warnx("%s: you can only specify one of -b or -N", __func__);
6901 if ((blocksizeonly != 0)
6902 && (sizeonly != 0)) {
6903 warnx("%s: you can only specify one of -b or -s", __func__);
6910 warnx("%s: you can only specify one of -h/-H or -q", __func__);
6916 && (blocksizeonly != 0)) {
6917 warnx("%s: you can only specify one of -h/-H or -b", __func__);
6922 scsi_read_capacity(&ccb->csio,
6923 /*retries*/ retry_count,
6925 /*tag_action*/ task_attr,
6928 /*timeout*/ timeout ? timeout : 5000);
6930 /* Disable freezing the device queue */
6931 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6933 if (arglist & CAM_ARG_ERR_RECOVER)
6934 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6936 if (cam_send_ccb(device, ccb) < 0) {
6937 warn("error sending READ CAPACITY command");
6939 if (arglist & CAM_ARG_VERBOSE)
6940 cam_error_print(device, ccb, CAM_ESF_ALL,
6941 CAM_EPF_ALL, stderr);
6947 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6948 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6953 maxsector = scsi_4btoul(rcap.addr);
6954 block_len = scsi_4btoul(rcap.length);
6957 * A last block of 2^32-1 means that the true capacity is over 2TB,
6958 * and we need to issue the long READ CAPACITY to get the real
6959 * capacity. Otherwise, we're all set.
6961 if (maxsector != 0xffffffff)
6964 scsi_read_capacity_16(&ccb->csio,
6965 /*retries*/ retry_count,
6967 /*tag_action*/ task_attr,
6971 /*rcap_buf*/ (uint8_t *)&rcaplong,
6972 /*rcap_buf_len*/ sizeof(rcaplong),
6973 /*sense_len*/ SSD_FULL_SIZE,
6974 /*timeout*/ timeout ? timeout : 5000);
6976 /* Disable freezing the device queue */
6977 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6979 if (arglist & CAM_ARG_ERR_RECOVER)
6980 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6982 if (cam_send_ccb(device, ccb) < 0) {
6983 warn("error sending READ CAPACITY (16) command");
6985 if (arglist & CAM_ARG_VERBOSE)
6986 cam_error_print(device, ccb, CAM_ESF_ALL,
6987 CAM_EPF_ALL, stderr);
6993 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6994 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6999 maxsector = scsi_8btou64(rcaplong.addr);
7000 block_len = scsi_4btoul(rcaplong.length);
7003 if (blocksizeonly == 0) {
7005 * Humanize implies !quiet, and also implies numblocks.
7007 if (humanize != 0) {
7012 tmpbytes = (maxsector + 1) * block_len;
7013 ret = humanize_number(tmpstr, sizeof(tmpstr),
7014 tmpbytes, "", HN_AUTOSCALE,
7017 HN_DIVISOR_1000 : 0));
7019 warnx("%s: humanize_number failed!", __func__);
7023 fprintf(stdout, "Device Size: %s%s", tmpstr,
7024 (sizeonly == 0) ? ", " : "\n");
7025 } else if (numblocks != 0) {
7026 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7027 "Blocks: " : "", (uintmax_t)maxsector + 1,
7028 (sizeonly == 0) ? ", " : "\n");
7030 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7031 "Last Block: " : "", (uintmax_t)maxsector,
7032 (sizeonly == 0) ? ", " : "\n");
7036 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7037 "Block Length: " : "", block_len, (quiet == 0) ?
7046 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7047 int retry_count, int timeout)
7051 uint8_t *smp_request = NULL, *smp_response = NULL;
7052 int request_size = 0, response_size = 0;
7053 int fd_request = 0, fd_response = 0;
7054 char *datastr = NULL;
7055 struct get_hook hook;
7060 * Note that at the moment we don't support sending SMP CCBs to
7061 * devices that aren't probed by CAM.
7063 ccb = cam_getccb(device);
7065 warnx("%s: error allocating CCB", __func__);
7069 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7071 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7074 arglist |= CAM_ARG_CMD_IN;
7075 response_size = strtol(optarg, NULL, 0);
7076 if (response_size <= 0) {
7077 warnx("invalid number of response bytes %d",
7080 goto smpcmd_bailout;
7082 hook.argc = argc - optind;
7083 hook.argv = argv + optind;
7086 datastr = cget(&hook, NULL);
7088 * If the user supplied "-" instead of a format, he
7089 * wants the data to be written to stdout.
7091 if ((datastr != NULL)
7092 && (datastr[0] == '-'))
7095 smp_response = (u_int8_t *)malloc(response_size);
7096 if (smp_response == NULL) {
7097 warn("can't malloc memory for SMP response");
7099 goto smpcmd_bailout;
7103 arglist |= CAM_ARG_CMD_OUT;
7104 request_size = strtol(optarg, NULL, 0);
7105 if (request_size <= 0) {
7106 warnx("invalid number of request bytes %d",
7109 goto smpcmd_bailout;
7111 hook.argc = argc - optind;
7112 hook.argv = argv + optind;
7114 datastr = cget(&hook, NULL);
7115 smp_request = (u_int8_t *)malloc(request_size);
7116 if (smp_request == NULL) {
7117 warn("can't malloc memory for SMP request");
7119 goto smpcmd_bailout;
7121 bzero(smp_request, request_size);
7123 * If the user supplied "-" instead of a format, he
7124 * wants the data to be read from stdin.
7126 if ((datastr != NULL)
7127 && (datastr[0] == '-'))
7130 buff_encode_visit(smp_request, request_size,
7141 * If fd_data is set, and we're writing to the device, we need to
7142 * read the data the user wants written from stdin.
7144 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7146 int amt_to_read = request_size;
7147 u_int8_t *buf_ptr = smp_request;
7149 for (amt_read = 0; amt_to_read > 0;
7150 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7151 if (amt_read == -1) {
7152 warn("error reading data from stdin");
7154 goto smpcmd_bailout;
7156 amt_to_read -= amt_read;
7157 buf_ptr += amt_read;
7161 if (((arglist & CAM_ARG_CMD_IN) == 0)
7162 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7163 warnx("%s: need both the request (-r) and response (-R) "
7164 "arguments", __func__);
7166 goto smpcmd_bailout;
7169 flags |= CAM_DEV_QFRZDIS;
7171 cam_fill_smpio(&ccb->smpio,
7172 /*retries*/ retry_count,
7175 /*smp_request*/ smp_request,
7176 /*smp_request_len*/ request_size,
7177 /*smp_response*/ smp_response,
7178 /*smp_response_len*/ response_size,
7179 /*timeout*/ timeout ? timeout : 5000);
7181 ccb->smpio.flags = SMP_FLAG_NONE;
7183 if (((retval = cam_send_ccb(device, ccb)) < 0)
7184 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7185 const char warnstr[] = "error sending command";
7192 if (arglist & CAM_ARG_VERBOSE) {
7193 cam_error_print(device, ccb, CAM_ESF_ALL,
7194 CAM_EPF_ALL, stderr);
7198 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7199 && (response_size > 0)) {
7200 if (fd_response == 0) {
7201 buff_decode_visit(smp_response, response_size,
7202 datastr, arg_put, NULL);
7203 fprintf(stdout, "\n");
7205 ssize_t amt_written;
7206 int amt_to_write = response_size;
7207 u_int8_t *buf_ptr = smp_response;
7209 for (amt_written = 0; (amt_to_write > 0) &&
7210 (amt_written = write(STDOUT_FILENO, buf_ptr,
7211 amt_to_write)) > 0;){
7212 amt_to_write -= amt_written;
7213 buf_ptr += amt_written;
7215 if (amt_written == -1) {
7216 warn("error writing data to stdout");
7218 goto smpcmd_bailout;
7219 } else if ((amt_written == 0)
7220 && (amt_to_write > 0)) {
7221 warnx("only wrote %u bytes out of %u",
7222 response_size - amt_to_write,
7231 if (smp_request != NULL)
7234 if (smp_response != NULL)
7241 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7242 char *combinedopt, int retry_count, int timeout)
7245 struct smp_report_general_request *request = NULL;
7246 struct smp_report_general_response *response = NULL;
7247 struct sbuf *sb = NULL;
7249 int c, long_response = 0;
7253 * Note that at the moment we don't support sending SMP CCBs to
7254 * devices that aren't probed by CAM.
7256 ccb = cam_getccb(device);
7258 warnx("%s: error allocating CCB", __func__);
7262 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7264 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7273 request = malloc(sizeof(*request));
7274 if (request == NULL) {
7275 warn("%s: unable to allocate %zd bytes", __func__,
7281 response = malloc(sizeof(*response));
7282 if (response == NULL) {
7283 warn("%s: unable to allocate %zd bytes", __func__,
7290 smp_report_general(&ccb->smpio,
7294 /*request_len*/ sizeof(*request),
7295 (uint8_t *)response,
7296 /*response_len*/ sizeof(*response),
7297 /*long_response*/ long_response,
7300 if (((retval = cam_send_ccb(device, ccb)) < 0)
7301 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7302 const char warnstr[] = "error sending command";
7309 if (arglist & CAM_ARG_VERBOSE) {
7310 cam_error_print(device, ccb, CAM_ESF_ALL,
7311 CAM_EPF_ALL, stderr);
7318 * If the device supports the long response bit, try again and see
7319 * if we can get all of the data.
7321 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7322 && (long_response == 0)) {
7323 ccb->ccb_h.status = CAM_REQ_INPROG;
7324 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7330 * XXX KDM detect and decode SMP errors here.
7332 sb = sbuf_new_auto();
7334 warnx("%s: error allocating sbuf", __func__);
7338 smp_report_general_sbuf(response, sizeof(*response), sb);
7340 if (sbuf_finish(sb) != 0) {
7341 warnx("%s: sbuf_finish", __func__);
7345 printf("%s", sbuf_data(sb));
7351 if (request != NULL)
7354 if (response != NULL)
7363 static struct camcontrol_opts phy_ops[] = {
7364 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7365 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7366 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7367 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7368 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7369 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7370 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7371 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7372 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7377 smpphycontrol(struct cam_device *device, int argc, char **argv,
7378 char *combinedopt, int retry_count, int timeout)
7381 struct smp_phy_control_request *request = NULL;
7382 struct smp_phy_control_response *response = NULL;
7383 int long_response = 0;
7386 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7388 uint64_t attached_dev_name = 0;
7389 int dev_name_set = 0;
7390 uint32_t min_plr = 0, max_plr = 0;
7391 uint32_t pp_timeout_val = 0;
7392 int slumber_partial = 0;
7393 int set_pp_timeout_val = 0;
7397 * Note that at the moment we don't support sending SMP CCBs to
7398 * devices that aren't probed by CAM.
7400 ccb = cam_getccb(device);
7402 warnx("%s: error allocating CCB", __func__);
7406 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7408 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7416 if (strcasecmp(optarg, "enable") == 0)
7418 else if (strcasecmp(optarg, "disable") == 0)
7421 warnx("%s: Invalid argument %s", __func__,
7428 slumber_partial |= enable <<
7429 SMP_PC_SAS_SLUMBER_SHIFT;
7432 slumber_partial |= enable <<
7433 SMP_PC_SAS_PARTIAL_SHIFT;
7436 slumber_partial |= enable <<
7437 SMP_PC_SATA_SLUMBER_SHIFT;
7440 slumber_partial |= enable <<
7441 SMP_PC_SATA_PARTIAL_SHIFT;
7444 warnx("%s: programmer error", __func__);
7447 break; /*NOTREACHED*/
7452 attached_dev_name = (uintmax_t)strtoumax(optarg,
7461 * We don't do extensive checking here, so this
7462 * will continue to work when new speeds come out.
7464 min_plr = strtoul(optarg, NULL, 0);
7466 || (min_plr > 0xf)) {
7467 warnx("%s: invalid link rate %x",
7475 * We don't do extensive checking here, so this
7476 * will continue to work when new speeds come out.
7478 max_plr = strtoul(optarg, NULL, 0);
7480 || (max_plr > 0xf)) {
7481 warnx("%s: invalid link rate %x",
7488 camcontrol_optret optreturn;
7489 cam_argmask argnums;
7492 if (phy_op_set != 0) {
7493 warnx("%s: only one phy operation argument "
7494 "(-o) allowed", __func__);
7502 * Allow the user to specify the phy operation
7503 * numerically, as well as with a name. This will
7504 * future-proof it a bit, so options that are added
7505 * in future specs can be used.
7507 if (isdigit(optarg[0])) {
7508 phy_operation = strtoul(optarg, NULL, 0);
7509 if ((phy_operation == 0)
7510 || (phy_operation > 0xff)) {
7511 warnx("%s: invalid phy operation %#x",
7512 __func__, phy_operation);
7518 optreturn = getoption(phy_ops, optarg, &phy_operation,
7521 if (optreturn == CC_OR_AMBIGUOUS) {
7522 warnx("%s: ambiguous option %s", __func__,
7527 } else if (optreturn == CC_OR_NOT_FOUND) {
7528 warnx("%s: option %s not found", __func__,
7540 pp_timeout_val = strtoul(optarg, NULL, 0);
7541 if (pp_timeout_val > 15) {
7542 warnx("%s: invalid partial pathway timeout "
7543 "value %u, need a value less than 16",
7544 __func__, pp_timeout_val);
7548 set_pp_timeout_val = 1;
7556 warnx("%s: a PHY (-p phy) argument is required",__func__);
7561 if (((dev_name_set != 0)
7562 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
7563 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
7564 && (dev_name_set == 0))) {
7565 warnx("%s: -d name and -o setdevname arguments both "
7566 "required to set device name", __func__);
7571 request = malloc(sizeof(*request));
7572 if (request == NULL) {
7573 warn("%s: unable to allocate %zd bytes", __func__,
7579 response = malloc(sizeof(*response));
7580 if (response == NULL) {
7581 warn("%s: unable to allocate %zd bytes", __func__,
7587 smp_phy_control(&ccb->smpio,
7592 (uint8_t *)response,
7595 /*expected_exp_change_count*/ 0,
7598 (set_pp_timeout_val != 0) ? 1 : 0,
7606 if (((retval = cam_send_ccb(device, ccb)) < 0)
7607 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7608 const char warnstr[] = "error sending command";
7615 if (arglist & CAM_ARG_VERBOSE) {
7617 * Use CAM_EPF_NORMAL so we only get one line of
7618 * SMP command decoding.
7620 cam_error_print(device, ccb, CAM_ESF_ALL,
7621 CAM_EPF_NORMAL, stderr);
7627 /* XXX KDM print out something here for success? */
7632 if (request != NULL)
7635 if (response != NULL)
7642 smpmaninfo(struct cam_device *device, int argc, char **argv,
7643 char *combinedopt, int retry_count, int timeout)
7646 struct smp_report_manuf_info_request request;
7647 struct smp_report_manuf_info_response response;
7648 struct sbuf *sb = NULL;
7649 int long_response = 0;
7654 * Note that at the moment we don't support sending SMP CCBs to
7655 * devices that aren't probed by CAM.
7657 ccb = cam_getccb(device);
7659 warnx("%s: error allocating CCB", __func__);
7663 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7665 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7674 bzero(&request, sizeof(request));
7675 bzero(&response, sizeof(response));
7677 smp_report_manuf_info(&ccb->smpio,
7682 (uint8_t *)&response,
7687 if (((retval = cam_send_ccb(device, ccb)) < 0)
7688 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7689 const char warnstr[] = "error sending command";
7696 if (arglist & CAM_ARG_VERBOSE) {
7697 cam_error_print(device, ccb, CAM_ESF_ALL,
7698 CAM_EPF_ALL, stderr);
7704 sb = sbuf_new_auto();
7706 warnx("%s: error allocating sbuf", __func__);
7710 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7712 if (sbuf_finish(sb) != 0) {
7713 warnx("%s: sbuf_finish", __func__);
7717 printf("%s", sbuf_data(sb));
7731 getdevid(struct cam_devitem *item)
7734 union ccb *ccb = NULL;
7736 struct cam_device *dev;
7738 dev = cam_open_btl(item->dev_match.path_id,
7739 item->dev_match.target_id,
7740 item->dev_match.target_lun, O_RDWR, NULL);
7743 warnx("%s", cam_errbuf);
7748 item->device_id_len = 0;
7750 ccb = cam_getccb(dev);
7752 warnx("%s: error allocating CCB", __func__);
7757 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
7760 * On the first try, we just probe for the size of the data, and
7761 * then allocate that much memory and try again.
7764 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7765 ccb->ccb_h.flags = CAM_DIR_IN;
7766 ccb->cdai.flags = CDAI_FLAG_NONE;
7767 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7768 ccb->cdai.bufsiz = item->device_id_len;
7769 if (item->device_id_len != 0)
7770 ccb->cdai.buf = (uint8_t *)item->device_id;
7772 if (cam_send_ccb(dev, ccb) < 0) {
7773 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7778 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7779 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7784 if (item->device_id_len == 0) {
7786 * This is our first time through. Allocate the buffer,
7787 * and then go back to get the data.
7789 if (ccb->cdai.provsiz == 0) {
7790 warnx("%s: invalid .provsiz field returned with "
7791 "XPT_GDEV_ADVINFO CCB", __func__);
7795 item->device_id_len = ccb->cdai.provsiz;
7796 item->device_id = malloc(item->device_id_len);
7797 if (item->device_id == NULL) {
7798 warn("%s: unable to allocate %d bytes", __func__,
7799 item->device_id_len);
7803 ccb->ccb_h.status = CAM_REQ_INPROG;
7809 cam_close_device(dev);
7818 * XXX KDM merge this code with getdevtree()?
7821 buildbusdevlist(struct cam_devlist *devlist)
7824 int bufsize, fd = -1;
7825 struct dev_match_pattern *patterns;
7826 struct cam_devitem *item = NULL;
7827 int skip_device = 0;
7830 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7831 warn("couldn't open %s", XPT_DEVICE);
7835 bzero(&ccb, sizeof(union ccb));
7837 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7838 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7839 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7841 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7842 bufsize = sizeof(struct dev_match_result) * 100;
7843 ccb.cdm.match_buf_len = bufsize;
7844 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7845 if (ccb.cdm.matches == NULL) {
7846 warnx("can't malloc memory for matches");
7850 ccb.cdm.num_matches = 0;
7851 ccb.cdm.num_patterns = 2;
7852 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7853 ccb.cdm.num_patterns;
7855 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7856 if (patterns == NULL) {
7857 warnx("can't malloc memory for patterns");
7862 ccb.cdm.patterns = patterns;
7863 bzero(patterns, ccb.cdm.pattern_buf_len);
7865 patterns[0].type = DEV_MATCH_DEVICE;
7866 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7867 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7868 patterns[1].type = DEV_MATCH_PERIPH;
7869 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7870 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7873 * We do the ioctl multiple times if necessary, in case there are
7874 * more than 100 nodes in the EDT.
7879 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7880 warn("error sending CAMIOCOMMAND ioctl");
7885 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7886 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7887 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7888 warnx("got CAM error %#x, CDM error %d\n",
7889 ccb.ccb_h.status, ccb.cdm.status);
7894 for (i = 0; i < ccb.cdm.num_matches; i++) {
7895 switch (ccb.cdm.matches[i].type) {
7896 case DEV_MATCH_DEVICE: {
7897 struct device_match_result *dev_result;
7900 &ccb.cdm.matches[i].result.device_result;
7902 if (dev_result->flags &
7903 DEV_RESULT_UNCONFIGURED) {
7909 item = malloc(sizeof(*item));
7911 warn("%s: unable to allocate %zd bytes",
7912 __func__, sizeof(*item));
7916 bzero(item, sizeof(*item));
7917 bcopy(dev_result, &item->dev_match,
7918 sizeof(*dev_result));
7919 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
7922 if (getdevid(item) != 0) {
7928 case DEV_MATCH_PERIPH: {
7929 struct periph_match_result *periph_result;
7932 &ccb.cdm.matches[i].result.periph_result;
7934 if (skip_device != 0)
7936 item->num_periphs++;
7937 item->periph_matches = realloc(
7938 item->periph_matches,
7940 sizeof(struct periph_match_result));
7941 if (item->periph_matches == NULL) {
7942 warn("%s: error allocating periph "
7947 bcopy(periph_result, &item->periph_matches[
7948 item->num_periphs - 1],
7949 sizeof(*periph_result));
7953 fprintf(stderr, "%s: unexpected match "
7954 "type %d\n", __func__,
7955 ccb.cdm.matches[i].type);
7958 break; /*NOTREACHED*/
7961 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
7962 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
7970 free(ccb.cdm.matches);
7973 freebusdevlist(devlist);
7979 freebusdevlist(struct cam_devlist *devlist)
7981 struct cam_devitem *item, *item2;
7983 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
7984 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
7986 free(item->device_id);
7987 free(item->periph_matches);
7992 static struct cam_devitem *
7993 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
7995 struct cam_devitem *item;
7997 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
7998 struct scsi_vpd_id_descriptor *idd;
8001 * XXX KDM look for LUN IDs as well?
8003 idd = scsi_get_devid(item->device_id,
8004 item->device_id_len,
8005 scsi_devid_is_sas_target);
8009 if (scsi_8btou64(idd->identifier) == sasaddr)
8017 smpphylist(struct cam_device *device, int argc, char **argv,
8018 char *combinedopt, int retry_count, int timeout)
8020 struct smp_report_general_request *rgrequest = NULL;
8021 struct smp_report_general_response *rgresponse = NULL;
8022 struct smp_discover_request *disrequest = NULL;
8023 struct smp_discover_response *disresponse = NULL;
8024 struct cam_devlist devlist;
8026 int long_response = 0;
8033 * Note that at the moment we don't support sending SMP CCBs to
8034 * devices that aren't probed by CAM.
8036 ccb = cam_getccb(device);
8038 warnx("%s: error allocating CCB", __func__);
8042 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8043 STAILQ_INIT(&devlist.dev_queue);
8045 rgrequest = malloc(sizeof(*rgrequest));
8046 if (rgrequest == NULL) {
8047 warn("%s: unable to allocate %zd bytes", __func__,
8048 sizeof(*rgrequest));
8053 rgresponse = malloc(sizeof(*rgresponse));
8054 if (rgresponse == NULL) {
8055 warn("%s: unable to allocate %zd bytes", __func__,
8056 sizeof(*rgresponse));
8061 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8074 smp_report_general(&ccb->smpio,
8078 /*request_len*/ sizeof(*rgrequest),
8079 (uint8_t *)rgresponse,
8080 /*response_len*/ sizeof(*rgresponse),
8081 /*long_response*/ long_response,
8084 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8086 if (((retval = cam_send_ccb(device, ccb)) < 0)
8087 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8088 const char warnstr[] = "error sending command";
8095 if (arglist & CAM_ARG_VERBOSE) {
8096 cam_error_print(device, ccb, CAM_ESF_ALL,
8097 CAM_EPF_ALL, stderr);
8103 num_phys = rgresponse->num_phys;
8105 if (num_phys == 0) {
8107 fprintf(stdout, "%s: No Phys reported\n", __func__);
8112 devlist.path_id = device->path_id;
8114 retval = buildbusdevlist(&devlist);
8119 fprintf(stdout, "%d PHYs:\n", num_phys);
8120 fprintf(stdout, "PHY Attached SAS Address\n");
8123 disrequest = malloc(sizeof(*disrequest));
8124 if (disrequest == NULL) {
8125 warn("%s: unable to allocate %zd bytes", __func__,
8126 sizeof(*disrequest));
8131 disresponse = malloc(sizeof(*disresponse));
8132 if (disresponse == NULL) {
8133 warn("%s: unable to allocate %zd bytes", __func__,
8134 sizeof(*disresponse));
8139 for (i = 0; i < num_phys; i++) {
8140 struct cam_devitem *item;
8141 struct device_match_result *dev_match;
8142 char vendor[16], product[48], revision[16];
8146 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8148 ccb->ccb_h.status = CAM_REQ_INPROG;
8149 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8151 smp_discover(&ccb->smpio,
8155 sizeof(*disrequest),
8156 (uint8_t *)disresponse,
8157 sizeof(*disresponse),
8159 /*ignore_zone_group*/ 0,
8163 if (((retval = cam_send_ccb(device, ccb)) < 0)
8164 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
8165 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
8166 const char warnstr[] = "error sending command";
8173 if (arglist & CAM_ARG_VERBOSE) {
8174 cam_error_print(device, ccb, CAM_ESF_ALL,
8175 CAM_EPF_ALL, stderr);
8181 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
8183 fprintf(stdout, "%3d <vacant>\n", i);
8187 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
8190 item = findsasdevice(&devlist,
8191 scsi_8btou64(disresponse->attached_sas_address));
8195 || (item != NULL)) {
8196 fprintf(stdout, "%3d 0x%016jx", i,
8197 (uintmax_t)scsi_8btou64(
8198 disresponse->attached_sas_address));
8200 fprintf(stdout, "\n");
8203 } else if (quiet != 0)
8206 dev_match = &item->dev_match;
8208 if (dev_match->protocol == PROTO_SCSI) {
8209 cam_strvis(vendor, dev_match->inq_data.vendor,
8210 sizeof(dev_match->inq_data.vendor),
8212 cam_strvis(product, dev_match->inq_data.product,
8213 sizeof(dev_match->inq_data.product),
8215 cam_strvis(revision, dev_match->inq_data.revision,
8216 sizeof(dev_match->inq_data.revision),
8218 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8220 } else if ((dev_match->protocol == PROTO_ATA)
8221 || (dev_match->protocol == PROTO_SATAPM)) {
8222 cam_strvis(product, dev_match->ident_data.model,
8223 sizeof(dev_match->ident_data.model),
8225 cam_strvis(revision, dev_match->ident_data.revision,
8226 sizeof(dev_match->ident_data.revision),
8228 sprintf(tmpstr, "<%s %s>", product, revision);
8230 sprintf(tmpstr, "<>");
8232 fprintf(stdout, " %-33s ", tmpstr);
8235 * If we have 0 periphs, that's a bug...
8237 if (item->num_periphs == 0) {
8238 fprintf(stdout, "\n");
8242 fprintf(stdout, "(");
8243 for (j = 0; j < item->num_periphs; j++) {
8245 fprintf(stdout, ",");
8247 fprintf(stdout, "%s%d",
8248 item->periph_matches[j].periph_name,
8249 item->periph_matches[j].unit_number);
8252 fprintf(stdout, ")\n");
8266 freebusdevlist(&devlist);
8272 atapm(struct cam_device *device, int argc, char **argv,
8273 char *combinedopt, int retry_count, int timeout)
8281 ccb = cam_getccb(device);
8284 warnx("%s: error allocating ccb", __func__);
8288 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8297 if (strcmp(argv[1], "idle") == 0) {
8299 cmd = ATA_IDLE_IMMEDIATE;
8302 } else if (strcmp(argv[1], "standby") == 0) {
8304 cmd = ATA_STANDBY_IMMEDIATE;
8306 cmd = ATA_STANDBY_CMD;
8314 else if (t <= (240 * 5))
8316 else if (t <= (252 * 5))
8317 /* special encoding for 21 minutes */
8319 else if (t <= (11 * 30 * 60))
8320 sc = (t - 1) / (30 * 60) + 241;
8324 retval = ata_do_28bit_cmd(device,
8326 /*retries*/retry_count,
8327 /*flags*/CAM_DIR_NONE,
8328 /*protocol*/AP_PROTO_NON_DATA,
8329 /*tag_action*/MSG_SIMPLE_Q_TAG,
8336 /*timeout*/timeout ? timeout : 30 * 1000,
8344 ataaxm(struct cam_device *device, int argc, char **argv,
8345 char *combinedopt, int retry_count, int timeout)
8353 ccb = cam_getccb(device);
8356 warnx("%s: error allocating ccb", __func__);
8360 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8370 if (strcmp(argv[1], "apm") == 0) {
8386 retval = ata_do_28bit_cmd(device,
8388 /*retries*/retry_count,
8389 /*flags*/CAM_DIR_NONE,
8390 /*protocol*/AP_PROTO_NON_DATA,
8391 /*tag_action*/MSG_SIMPLE_Q_TAG,
8392 /*command*/ATA_SETFEATURES,
8398 /*timeout*/timeout ? timeout : 30 * 1000,
8406 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
8407 int show_sa_errors, int sa_set, int service_action,
8408 int timeout_desc, int task_attr, int retry_count, int timeout,
8409 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
8411 union ccb *ccb = NULL;
8412 uint8_t *buf = NULL;
8413 uint32_t alloc_len = 0, num_opcodes;
8414 uint32_t valid_len = 0;
8415 uint32_t avail_len = 0;
8416 struct scsi_report_supported_opcodes_all *all_hdr;
8417 struct scsi_report_supported_opcodes_one *one;
8422 * Make it clear that we haven't yet allocated or filled anything.
8427 ccb = cam_getccb(device);
8429 warnx("couldn't allocate CCB");
8434 /* cam_getccb cleans up the header, caller has to zero the payload */
8435 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8437 if (opcode_set != 0) {
8438 options |= RSO_OPTIONS_OC;
8440 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
8443 alloc_len = sizeof(*all_hdr) + (num_opcodes *
8444 sizeof(struct scsi_report_supported_opcodes_descr));
8447 if (timeout_desc != 0) {
8448 options |= RSO_RCTD;
8449 alloc_len += num_opcodes *
8450 sizeof(struct scsi_report_supported_opcodes_timeout);
8454 options |= RSO_OPTIONS_OC_SA;
8455 if (show_sa_errors != 0)
8456 options &= ~RSO_OPTIONS_OC;
8465 buf = malloc(alloc_len);
8467 warn("Unable to allocate %u bytes", alloc_len);
8471 bzero(buf, alloc_len);
8473 scsi_report_supported_opcodes(&ccb->csio,
8474 /*retries*/ retry_count,
8476 /*tag_action*/ task_attr,
8477 /*options*/ options,
8478 /*req_opcode*/ opcode,
8479 /*req_service_action*/ service_action,
8481 /*dxfer_len*/ alloc_len,
8482 /*sense_len*/ SSD_FULL_SIZE,
8483 /*timeout*/ timeout ? timeout : 10000);
8485 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8487 if (retry_count != 0)
8488 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
8490 if (cam_send_ccb(device, ccb) < 0) {
8491 perror("error sending REPORT SUPPORTED OPERATION CODES");
8496 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8497 if (verbosemode != 0)
8498 cam_error_print(device, ccb, CAM_ESF_ALL,
8499 CAM_EPF_ALL, stderr);
8505 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
8507 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
8508 && (valid_len >= sizeof(*all_hdr))) {
8509 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
8510 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
8511 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
8512 && (valid_len >= sizeof(*one))) {
8513 uint32_t cdb_length;
8515 one = (struct scsi_report_supported_opcodes_one *)buf;
8516 cdb_length = scsi_2btoul(one->cdb_length);
8517 avail_len = sizeof(*one) + cdb_length;
8518 if (one->support & RSO_ONE_CTDP) {
8519 struct scsi_report_supported_opcodes_timeout *td;
8521 td = (struct scsi_report_supported_opcodes_timeout *)
8523 if (valid_len >= (avail_len + sizeof(td->length))) {
8524 avail_len += scsi_2btoul(td->length) +
8527 avail_len += sizeof(*td);
8533 * avail_len could be zero if we didn't get enough data back from
8534 * thet target to determine
8536 if ((avail_len != 0)
8537 && (avail_len > valid_len)) {
8538 alloc_len = avail_len;
8542 *fill_len = valid_len;
8554 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
8555 int req_sa, uint8_t *buf, uint32_t valid_len)
8557 struct scsi_report_supported_opcodes_one *one;
8558 struct scsi_report_supported_opcodes_timeout *td;
8559 uint32_t cdb_len = 0, td_len = 0;
8560 const char *op_desc = NULL;
8564 one = (struct scsi_report_supported_opcodes_one *)buf;
8567 * If we don't have the full single opcode descriptor, no point in
8570 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8572 warnx("Only %u bytes returned, not enough to verify support",
8578 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
8580 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
8583 printf(", SA 0x%x", req_sa);
8586 switch (one->support & RSO_ONE_SUP_MASK) {
8587 case RSO_ONE_SUP_UNAVAIL:
8588 printf("No command support information currently available\n");
8590 case RSO_ONE_SUP_NOT_SUP:
8591 printf("Command not supported\n");
8594 break; /*NOTREACHED*/
8595 case RSO_ONE_SUP_AVAIL:
8596 printf("Command is supported, complies with a SCSI standard\n");
8598 case RSO_ONE_SUP_VENDOR:
8599 printf("Command is supported, vendor-specific "
8600 "implementation\n");
8603 printf("Unknown command support flags 0x%#x\n",
8604 one->support & RSO_ONE_SUP_MASK);
8609 * If we don't have the CDB length, it isn't exactly an error, the
8610 * command probably isn't supported.
8612 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8616 cdb_len = scsi_2btoul(one->cdb_length);
8619 * If our valid data doesn't include the full reported length,
8620 * return. The caller should have detected this and adjusted his
8621 * allocation length to get all of the available data.
8623 if (valid_len < sizeof(*one) + cdb_len) {
8629 * If all we have is the opcode, there is no point in printing out
8637 printf("CDB usage bitmap:");
8638 for (i = 0; i < cdb_len; i++) {
8639 printf(" %02x", one->cdb_usage[i]);
8644 * If we don't have a timeout descriptor, we're done.
8646 if ((one->support & RSO_ONE_CTDP) == 0)
8650 * If we don't have enough valid length to include the timeout
8651 * descriptor length, we're done.
8653 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
8656 td = (struct scsi_report_supported_opcodes_timeout *)
8657 &buf[sizeof(*one) + cdb_len];
8658 td_len = scsi_2btoul(td->length);
8659 td_len += sizeof(td->length);
8662 * If we don't have the full timeout descriptor, we're done.
8664 if (td_len < sizeof(*td))
8668 * If we don't have enough valid length to contain the full timeout
8669 * descriptor, we're done.
8671 if (valid_len < (sizeof(*one) + cdb_len + td_len))
8674 printf("Timeout information:\n");
8675 printf("Command-specific: 0x%02x\n", td->cmd_specific);
8676 printf("Nominal timeout: %u seconds\n",
8677 scsi_4btoul(td->nominal_time));
8678 printf("Recommended timeout: %u seconds\n",
8679 scsi_4btoul(td->recommended_time));
8686 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
8689 struct scsi_report_supported_opcodes_all *hdr;
8690 struct scsi_report_supported_opcodes_descr *desc;
8691 uint32_t avail_len = 0, used_len = 0;
8695 if (valid_len < sizeof(*hdr)) {
8696 warnx("%s: not enough returned data (%u bytes) opcode list",
8697 __func__, valid_len);
8701 hdr = (struct scsi_report_supported_opcodes_all *)buf;
8702 avail_len = scsi_4btoul(hdr->length);
8703 avail_len += sizeof(hdr->length);
8705 * Take the lesser of the amount of data the drive claims is
8706 * available, and the amount of data the HBA says was returned.
8708 avail_len = MIN(avail_len, valid_len);
8710 used_len = sizeof(hdr->length);
8712 printf("%-6s %4s %8s ",
8713 "Opcode", "SA", "CDB len" );
8716 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
8717 printf(" Description\n");
8719 while ((avail_len - used_len) > sizeof(*desc)) {
8720 struct scsi_report_supported_opcodes_timeout *td;
8722 const char *op_desc = NULL;
8724 cur_ptr = &buf[used_len];
8725 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
8727 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
8728 if (op_desc == NULL)
8729 op_desc = "UNKNOWN";
8731 printf("0x%02x %#4x %8u ", desc->opcode,
8732 scsi_2btoul(desc->service_action),
8733 scsi_2btoul(desc->cdb_length));
8735 used_len += sizeof(*desc);
8737 if ((desc->flags & RSO_CTDP) == 0) {
8738 printf(" %s\n", op_desc);
8743 * If we don't have enough space to fit a timeout
8744 * descriptor, then we're done.
8746 if (avail_len - used_len < sizeof(*td)) {
8747 used_len = avail_len;
8748 printf(" %s\n", op_desc);
8751 cur_ptr = &buf[used_len];
8752 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
8753 td_len = scsi_2btoul(td->length);
8754 td_len += sizeof(td->length);
8758 * If the given timeout descriptor length is less than what
8759 * we understand, skip it.
8761 if (td_len < sizeof(*td)) {
8762 printf(" %s\n", op_desc);
8766 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
8767 scsi_4btoul(td->nominal_time),
8768 scsi_4btoul(td->recommended_time), op_desc);
8775 scsiopcodes(struct cam_device *device, int argc, char **argv,
8776 char *combinedopt, int task_attr, int retry_count, int timeout,
8780 uint32_t opcode = 0, service_action = 0;
8781 int td_set = 0, opcode_set = 0, sa_set = 0;
8782 int show_sa_errors = 1;
8783 uint32_t valid_len = 0;
8784 uint8_t *buf = NULL;
8788 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8794 opcode = strtoul(optarg, &endptr, 0);
8795 if (*endptr != '\0') {
8796 warnx("Invalid opcode \"%s\", must be a number",
8801 if (opcode > 0xff) {
8802 warnx("Invalid opcode 0x%#x, must be between"
8803 "0 and 0xff inclusive", opcode);
8810 service_action = strtoul(optarg, &endptr, 0);
8811 if (*endptr != '\0') {
8812 warnx("Invalid service action \"%s\", must "
8813 "be a number", optarg);
8817 if (service_action > 0xffff) {
8818 warnx("Invalid service action 0x%#x, must "
8819 "be between 0 and 0xffff inclusive",
8834 && (opcode_set == 0)) {
8835 warnx("You must specify an opcode with -o if a service "
8840 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
8841 sa_set, service_action, td_set, task_attr,
8842 retry_count, timeout, verbosemode, &valid_len,
8847 if ((opcode_set != 0)
8849 retval = scsiprintoneopcode(device, opcode, sa_set,
8850 service_action, buf, valid_len);
8852 retval = scsiprintopcodes(device, td_set, buf, valid_len);
8861 #endif /* MINIMALISTIC */
8864 scsireprobe(struct cam_device *device)
8869 ccb = cam_getccb(device);
8872 warnx("%s: error allocating ccb", __func__);
8876 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8878 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
8880 if (cam_send_ccb(device, ccb) < 0) {
8881 warn("error sending XPT_REPROBE_LUN CCB");
8886 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8887 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
8899 usage(int printlong)
8902 fprintf(printlong ? stdout : stderr,
8903 "usage: camcontrol <command> [device id][generic args][command args]\n"
8904 " camcontrol devlist [-b] [-v]\n"
8905 #ifndef MINIMALISTIC
8906 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
8907 " camcontrol tur [dev_id][generic args]\n"
8908 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
8909 " camcontrol identify [dev_id][generic args] [-v]\n"
8910 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
8911 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
8913 " camcontrol start [dev_id][generic args]\n"
8914 " camcontrol stop [dev_id][generic args]\n"
8915 " camcontrol load [dev_id][generic args]\n"
8916 " camcontrol eject [dev_id][generic args]\n"
8917 " camcontrol reprobe [dev_id][generic args]\n"
8918 #endif /* MINIMALISTIC */
8919 " camcontrol rescan <all | bus[:target:lun]>\n"
8920 " camcontrol reset <all | bus[:target:lun]>\n"
8921 #ifndef MINIMALISTIC
8922 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
8923 " [-q][-s][-S offset][-X]\n"
8924 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
8925 " [-P pagectl][-e | -b][-d]\n"
8926 " camcontrol cmd [dev_id][generic args]\n"
8927 " <-a cmd [args] | -c cmd [args]>\n"
8928 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
8929 " camcontrol smpcmd [dev_id][generic args]\n"
8930 " <-r len fmt [args]> <-R len fmt [args]>\n"
8931 " camcontrol smprg [dev_id][generic args][-l]\n"
8932 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
8933 " [-o operation][-d name][-m rate][-M rate]\n"
8934 " [-T pp_timeout][-a enable|disable]\n"
8935 " [-A enable|disable][-s enable|disable]\n"
8936 " [-S enable|disable]\n"
8937 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
8938 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
8939 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
8940 " <all|bus[:target[:lun]]|off>\n"
8941 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
8942 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
8943 " [-D <enable|disable>][-M mode][-O offset]\n"
8944 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
8945 " [-U][-W bus_width]\n"
8946 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
8947 " camcontrol sanitize [dev_id][generic args]\n"
8948 " [-a overwrite|block|crypto|exitfailure]\n"
8949 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
8951 " camcontrol idle [dev_id][generic args][-t time]\n"
8952 " camcontrol standby [dev_id][generic args][-t time]\n"
8953 " camcontrol sleep [dev_id][generic args]\n"
8954 " camcontrol apm [dev_id][generic args][-l level]\n"
8955 " camcontrol aam [dev_id][generic args][-l level]\n"
8956 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
8958 " camcontrol security [dev_id][generic args]\n"
8959 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
8960 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
8961 " [-U <user|master>] [-y]\n"
8962 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
8963 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
8964 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
8965 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
8966 " [-s scope][-S][-T type][-U]\n"
8967 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
8968 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
8969 " [-p part][-s start][-T type][-V vol]\n"
8970 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
8972 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
8973 " [-o rep_opts] [-P print_opts]\n"
8974 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
8975 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
8976 " [-S power_src] [-T timer]\n"
8977 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
8978 " <-s <-f format -T time | -U >>\n"
8980 #endif /* MINIMALISTIC */
8981 " camcontrol help\n");
8984 #ifndef MINIMALISTIC
8986 "Specify one of the following options:\n"
8987 "devlist list all CAM devices\n"
8988 "periphlist list all CAM peripheral drivers attached to a device\n"
8989 "tur send a test unit ready to the named device\n"
8990 "inquiry send a SCSI inquiry command to the named device\n"
8991 "identify send a ATA identify command to the named device\n"
8992 "reportluns send a SCSI report luns command to the device\n"
8993 "readcap send a SCSI read capacity command to the device\n"
8994 "start send a Start Unit command to the device\n"
8995 "stop send a Stop Unit command to the device\n"
8996 "load send a Start Unit command to the device with the load bit set\n"
8997 "eject send a Stop Unit command to the device with the eject bit set\n"
8998 "reprobe update capacity information of the given device\n"
8999 "rescan rescan all buses, the given bus, or bus:target:lun\n"
9000 "reset reset all buses, the given bus, or bus:target:lun\n"
9001 "defects read the defect list of the specified device\n"
9002 "modepage display or edit (-e) the given mode page\n"
9003 "cmd send the given SCSI command, may need -i or -o as well\n"
9004 "smpcmd send the given SMP command, requires -o and -i\n"
9005 "smprg send the SMP Report General command\n"
9006 "smppc send the SMP PHY Control command, requires -p\n"
9007 "smpphylist display phys attached to a SAS expander\n"
9008 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9009 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9010 "tags report or set the number of transaction slots for a device\n"
9011 "negotiate report or set device negotiation parameters\n"
9012 "format send the SCSI FORMAT UNIT command to the named device\n"
9013 "sanitize send the SCSI SANITIZE command to the named device\n"
9014 "idle send the ATA IDLE command to the named device\n"
9015 "standby send the ATA STANDBY command to the named device\n"
9016 "sleep send the ATA SLEEP command to the named device\n"
9017 "fwdownload program firmware of the named device with the given image\n"
9018 "security report or send ATA security commands to the named device\n"
9019 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9020 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9021 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9022 "zone manage Zoned Block (Shingled) devices\n"
9023 "epc send ATA Extended Power Conditions commands\n"
9024 "timestamp report or set the device's timestamp\n"
9025 "help this message\n"
9026 "Device Identifiers:\n"
9027 "bus:target specify the bus and target, lun defaults to 0\n"
9028 "bus:target:lun specify the bus, target and lun\n"
9029 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
9030 "Generic arguments:\n"
9031 "-v be verbose, print out sense information\n"
9032 "-t timeout command timeout in seconds, overrides default timeout\n"
9033 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
9034 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
9035 "-E have the kernel attempt to perform SCSI error recovery\n"
9036 "-C count specify the SCSI command retry count (needs -E to work)\n"
9037 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
9038 "modepage arguments:\n"
9039 "-l list all available mode pages\n"
9040 "-m page specify the mode page to view or edit\n"
9041 "-e edit the specified mode page\n"
9042 "-b force view to binary mode\n"
9043 "-d disable block descriptors for mode sense\n"
9044 "-P pgctl page control field 0-3\n"
9045 "defects arguments:\n"
9046 "-f format specify defect list format (block, bfi or phys)\n"
9047 "-G get the grown defect list\n"
9048 "-P get the permanent defect list\n"
9049 "inquiry arguments:\n"
9050 "-D get the standard inquiry data\n"
9051 "-S get the serial number\n"
9052 "-R get the transfer rate, etc.\n"
9053 "reportluns arguments:\n"
9054 "-c only report a count of available LUNs\n"
9055 "-l only print out luns, and not a count\n"
9056 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
9057 "readcap arguments\n"
9058 "-b only report the blocksize\n"
9059 "-h human readable device size, base 2\n"
9060 "-H human readable device size, base 10\n"
9061 "-N print the number of blocks instead of last block\n"
9062 "-q quiet, print numbers only\n"
9063 "-s only report the last block/device size\n"
9065 "-c cdb [args] specify the SCSI CDB\n"
9066 "-i len fmt specify input data and input data format\n"
9067 "-o len fmt [args] specify output data and output data fmt\n"
9068 "smpcmd arguments:\n"
9069 "-r len fmt [args] specify the SMP command to be sent\n"
9070 "-R len fmt [args] specify SMP response format\n"
9071 "smprg arguments:\n"
9072 "-l specify the long response format\n"
9073 "smppc arguments:\n"
9074 "-p phy specify the PHY to operate on\n"
9075 "-l specify the long request/response format\n"
9076 "-o operation specify the phy control operation\n"
9077 "-d name set the attached device name\n"
9078 "-m rate set the minimum physical link rate\n"
9079 "-M rate set the maximum physical link rate\n"
9080 "-T pp_timeout set the partial pathway timeout value\n"
9081 "-a enable|disable enable or disable SATA slumber\n"
9082 "-A enable|disable enable or disable SATA partial phy power\n"
9083 "-s enable|disable enable or disable SAS slumber\n"
9084 "-S enable|disable enable or disable SAS partial phy power\n"
9085 "smpphylist arguments:\n"
9086 "-l specify the long response format\n"
9087 "-q only print phys with attached devices\n"
9088 "smpmaninfo arguments:\n"
9089 "-l specify the long response format\n"
9090 "debug arguments:\n"
9091 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
9092 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
9093 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
9094 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
9096 "-N tags specify the number of tags to use for this device\n"
9097 "-q be quiet, don't report the number of tags\n"
9098 "-v report a number of tag-related parameters\n"
9099 "negotiate arguments:\n"
9100 "-a send a test unit ready after negotiation\n"
9101 "-c report/set current negotiation settings\n"
9102 "-D <arg> \"enable\" or \"disable\" disconnection\n"
9103 "-M mode set ATA mode\n"
9104 "-O offset set command delay offset\n"
9105 "-q be quiet, don't report anything\n"
9106 "-R syncrate synchronization rate in MHz\n"
9107 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
9108 "-U report/set user negotiation settings\n"
9109 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
9110 "-v also print a Path Inquiry CCB for the controller\n"
9111 "format arguments:\n"
9112 "-q be quiet, don't print status messages\n"
9113 "-r run in report only mode\n"
9114 "-w don't send immediate format command\n"
9115 "-y don't ask any questions\n"
9116 "sanitize arguments:\n"
9117 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
9118 "-c passes overwrite passes to perform (1 to 31)\n"
9119 "-I invert overwrite pattern after each pass\n"
9120 "-P pattern path to overwrite pattern file\n"
9121 "-q be quiet, don't print status messages\n"
9122 "-r run in report only mode\n"
9123 "-U run operation in unrestricted completion exit mode\n"
9124 "-w don't send immediate sanitize command\n"
9125 "-y don't ask any questions\n"
9126 "idle/standby arguments:\n"
9127 "-t <arg> number of seconds before respective state.\n"
9128 "fwdownload arguments:\n"
9129 "-f fw_image path to firmware image file\n"
9130 "-q don't print informational messages, only errors\n"
9131 "-s run in simulation mode\n"
9132 "-v print info for every firmware segment sent to device\n"
9133 "-y don't ask any questions\n"
9134 "security arguments:\n"
9135 "-d pwd disable security using the given password for the selected\n"
9137 "-e pwd erase the device using the given pwd for the selected user\n"
9138 "-f freeze the security configuration of the specified device\n"
9139 "-h pwd enhanced erase the device using the given pwd for the\n"
9141 "-k pwd unlock the device using the given pwd for the selected\n"
9143 "-l <high|maximum> specifies which security level to set: high or maximum\n"
9144 "-q be quiet, do not print any status messages\n"
9145 "-s pwd password the device (enable security) using the given\n"
9146 " pwd for the selected user\n"
9147 "-T timeout overrides the timeout (seconds) used for erase operation\n"
9148 "-U <user|master> specifies which user to set: user or master\n"
9149 "-y don't ask any questions\n"
9151 "-f freeze the HPA configuration of the device\n"
9152 "-l lock the HPA configuration of the device\n"
9153 "-P make the HPA max sectors persist\n"
9154 "-p pwd Set the HPA configuration password required for unlock\n"
9156 "-q be quiet, do not print any status messages\n"
9157 "-s sectors configures the maximum user accessible sectors of the\n"
9159 "-U pwd unlock the HPA configuration of the device\n"
9160 "-y don't ask any questions\n"
9161 "persist arguments:\n"
9162 "-i action specify read_keys, read_reservation, report_cap, or\n"
9163 " read_full_status\n"
9164 "-o action specify register, register_ignore, reserve, release,\n"
9165 " clear, preempt, preempt_abort, register_move, replace_lost\n"
9166 "-a set the All Target Ports (ALL_TG_PT) bit\n"
9167 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
9168 "-k key specify the Reservation Key\n"
9169 "-K sa_key specify the Service Action Reservation Key\n"
9170 "-p set the Activate Persist Through Power Loss bit\n"
9171 "-R rtp specify the Relative Target Port\n"
9172 "-s scope specify the scope: lun, extent, element or a number\n"
9173 "-S specify Transport ID for register, requires -I\n"
9174 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
9175 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
9176 "-U unregister the current initiator for register_move\n"
9177 "attrib arguments:\n"
9178 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
9180 "-w attr specify an attribute to write, one -w argument per attr\n"
9181 "-a attr_num only display this attribute number\n"
9182 "-c get cached attributes\n"
9183 "-e elem_addr request attributes for the given element in a changer\n"
9184 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
9185 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
9186 " field_none, field_desc, field_num, field_size, field_rw\n"
9187 "-p partition request attributes for the given partition\n"
9188 "-s start_attr request attributes starting at the given number\n"
9189 "-T elem_type specify the element type (used with -e)\n"
9190 "-V logical_vol specify the logical volume ID\n"
9191 "opcodes arguments:\n"
9192 "-o opcode specify the individual opcode to list\n"
9193 "-s service_action specify the service action for the opcode\n"
9194 "-N do not return SCSI error for unsupported SA\n"
9195 "-T request nominal and recommended timeout values\n"
9197 "-c cmd required: rz, open, close, finish, or rwp\n"
9198 "-a apply the action to all zones\n"
9199 "-l LBA specify the zone starting LBA\n"
9200 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
9201 " closed, full, ro, offline, reset, nonseq, nonwp\n"
9202 "-P print_opt report zones printing: normal, summary, script\n"
9204 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
9205 " source, status, list\n"
9206 "-d disable power mode (timer, state)\n"
9207 "-D delayed entry (goto)\n"
9208 "-e enable power mode (timer, state)\n"
9209 "-H hold power mode (goto)\n"
9210 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
9212 "-P only display power mode (status)\n"
9213 "-r rst_src restore settings from: default, saved (restore)\n"
9214 "-s save mode (timer, state, restore)\n"
9215 "-S power_src set power source: battery, nonbattery (source)\n"
9216 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
9217 "timestamp arguments:\n"
9218 "-r report the timestamp of the device\n"
9219 "-f format report the timestamp of the device with the given\n"
9220 " strftime(3) format string\n"
9221 "-m report the timestamp of the device as milliseconds since\n"
9222 " January 1st, 1970\n"
9223 "-U report the time with UTC instead of the local time zone\n"
9224 "-s set the timestamp of the device\n"
9225 "-f format the format of the time string passed into strptime(3)\n"
9226 "-T time the time value passed into strptime(3)\n"
9227 "-U set the timestamp of the device to UTC time\n"
9229 #endif /* MINIMALISTIC */
9233 main(int argc, char **argv)
9236 char *device = NULL;
9238 struct cam_device *cam_dev = NULL;
9239 int timeout = 0, retry_count = 1;
9240 camcontrol_optret optreturn;
9242 const char *mainopt = "C:En:Q:t:u:v";
9243 const char *subopt = NULL;
9244 char combinedopt[256];
9245 int error = 0, optstart = 2;
9246 int task_attr = MSG_SIMPLE_Q_TAG;
9248 #ifndef MINIMALISTIC
9252 #endif /* MINIMALISTIC */
9254 cmdlist = CAM_CMD_NONE;
9255 arglist = CAM_ARG_NONE;
9263 * Get the base option.
9265 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
9267 if (optreturn == CC_OR_AMBIGUOUS) {
9268 warnx("ambiguous option %s", argv[1]);
9271 } else if (optreturn == CC_OR_NOT_FOUND) {
9272 warnx("option %s not found", argv[1]);
9278 * Ahh, getopt(3) is a pain.
9280 * This is a gross hack. There really aren't many other good
9281 * options (excuse the pun) for parsing options in a situation like
9282 * this. getopt is kinda braindead, so you end up having to run
9283 * through the options twice, and give each invocation of getopt
9284 * the option string for the other invocation.
9286 * You would think that you could just have two groups of options.
9287 * The first group would get parsed by the first invocation of
9288 * getopt, and the second group would get parsed by the second
9289 * invocation of getopt. It doesn't quite work out that way. When
9290 * the first invocation of getopt finishes, it leaves optind pointing
9291 * to the argument _after_ the first argument in the second group.
9292 * So when the second invocation of getopt comes around, it doesn't
9293 * recognize the first argument it gets and then bails out.
9295 * A nice alternative would be to have a flag for getopt that says
9296 * "just keep parsing arguments even when you encounter an unknown
9297 * argument", but there isn't one. So there's no real clean way to
9298 * easily parse two sets of arguments without having one invocation
9299 * of getopt know about the other.
9301 * Without this hack, the first invocation of getopt would work as
9302 * long as the generic arguments are first, but the second invocation
9303 * (in the subfunction) would fail in one of two ways. In the case
9304 * where you don't set optreset, it would fail because optind may be
9305 * pointing to the argument after the one it should be pointing at.
9306 * In the case where you do set optreset, and reset optind, it would
9307 * fail because getopt would run into the first set of options, which
9308 * it doesn't understand.
9310 * All of this would "sort of" work if you could somehow figure out
9311 * whether optind had been incremented one option too far. The
9312 * mechanics of that, however, are more daunting than just giving
9313 * both invocations all of the expect options for either invocation.
9315 * Needless to say, I wouldn't mind if someone invented a better
9316 * (non-GPL!) command line parsing interface than getopt. I
9317 * wouldn't mind if someone added more knobs to getopt to make it
9318 * work better. Who knows, I may talk myself into doing it someday,
9319 * if the standards weenies let me. As it is, it just leads to
9320 * hackery like this and causes people to avoid it in some cases.
9322 * KDM, September 8th, 1998
9325 sprintf(combinedopt, "%s%s", mainopt, subopt);
9327 sprintf(combinedopt, "%s", mainopt);
9330 * For these options we do not parse optional device arguments and
9331 * we do not open a passthrough device.
9333 if ((cmdlist == CAM_CMD_RESCAN)
9334 || (cmdlist == CAM_CMD_RESET)
9335 || (cmdlist == CAM_CMD_DEVTREE)
9336 || (cmdlist == CAM_CMD_USAGE)
9337 || (cmdlist == CAM_CMD_DEBUG))
9340 #ifndef MINIMALISTIC
9342 && (argc > 2 && argv[2][0] != '-')) {
9346 if (isdigit(argv[2][0])) {
9347 /* device specified as bus:target[:lun] */
9348 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9350 errx(1, "numeric device specification must "
9351 "be either bus:target, or "
9353 /* default to 0 if lun was not specified */
9354 if ((arglist & CAM_ARG_LUN) == 0) {
9356 arglist |= CAM_ARG_LUN;
9360 if (cam_get_device(argv[2], name, sizeof name, &unit)
9362 errx(1, "%s", cam_errbuf);
9363 device = strdup(name);
9364 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
9368 #endif /* MINIMALISTIC */
9370 * Start getopt processing at argv[2/3], since we've already
9371 * accepted argv[1..2] as the command name, and as a possible
9377 * Now we run through the argument list looking for generic
9378 * options, and ignoring options that possibly belong to
9381 while ((c = getopt(argc, argv, combinedopt))!= -1){
9384 retry_count = strtol(optarg, NULL, 0);
9385 if (retry_count < 0)
9386 errx(1, "retry count %d is < 0",
9388 arglist |= CAM_ARG_RETRIES;
9391 arglist |= CAM_ARG_ERR_RECOVER;
9394 arglist |= CAM_ARG_DEVICE;
9396 while (isspace(*tstr) && (*tstr != '\0'))
9398 device = (char *)strdup(tstr);
9402 int table_entry = 0;
9405 while (isspace(*tstr) && (*tstr != '\0'))
9407 if (isdigit(*tstr)) {
9408 task_attr = strtol(tstr, &endptr, 0);
9409 if (*endptr != '\0') {
9410 errx(1, "Invalid queue option "
9415 scsi_nv_status status;
9417 table_size = sizeof(task_attrs) /
9418 sizeof(task_attrs[0]);
9419 status = scsi_get_nv(task_attrs,
9420 table_size, tstr, &table_entry,
9421 SCSI_NV_FLAG_IG_CASE);
9422 if (status == SCSI_NV_FOUND)
9423 task_attr = task_attrs[
9426 errx(1, "%s option %s",
9427 (status == SCSI_NV_AMBIGUOUS)?
9428 "ambiguous" : "invalid",
9435 timeout = strtol(optarg, NULL, 0);
9437 errx(1, "invalid timeout %d", timeout);
9438 /* Convert the timeout from seconds to ms */
9440 arglist |= CAM_ARG_TIMEOUT;
9443 arglist |= CAM_ARG_UNIT;
9444 unit = strtol(optarg, NULL, 0);
9447 arglist |= CAM_ARG_VERBOSE;
9454 #ifndef MINIMALISTIC
9456 * For most commands we'll want to open the passthrough device
9457 * associated with the specified device. In the case of the rescan
9458 * commands, we don't use a passthrough device at all, just the
9459 * transport layer device.
9462 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
9463 && (((arglist & CAM_ARG_DEVICE) == 0)
9464 || ((arglist & CAM_ARG_UNIT) == 0))) {
9465 errx(1, "subcommand \"%s\" requires a valid device "
9466 "identifier", argv[1]);
9469 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
9470 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
9471 cam_open_spec_device(device,unit,O_RDWR,NULL)))
9473 errx(1,"%s", cam_errbuf);
9475 #endif /* MINIMALISTIC */
9478 * Reset optind to 2, and reset getopt, so these routines can parse
9479 * the arguments again.
9485 #ifndef MINIMALISTIC
9486 case CAM_CMD_DEVLIST:
9487 error = getdevlist(cam_dev);
9490 error = atahpa(cam_dev, retry_count, timeout,
9491 argc, argv, combinedopt);
9493 #endif /* MINIMALISTIC */
9494 case CAM_CMD_DEVTREE:
9495 error = getdevtree(argc, argv, combinedopt);
9497 #ifndef MINIMALISTIC
9499 error = testunitready(cam_dev, task_attr, retry_count,
9502 case CAM_CMD_INQUIRY:
9503 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
9504 task_attr, retry_count, timeout);
9506 case CAM_CMD_IDENTIFY:
9507 error = ataidentify(cam_dev, retry_count, timeout);
9509 case CAM_CMD_STARTSTOP:
9510 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
9511 arglist & CAM_ARG_EJECT, task_attr,
9512 retry_count, timeout);
9514 #endif /* MINIMALISTIC */
9515 case CAM_CMD_RESCAN:
9516 error = dorescan_or_reset(argc, argv, 1);
9519 error = dorescan_or_reset(argc, argv, 0);
9521 #ifndef MINIMALISTIC
9522 case CAM_CMD_READ_DEFECTS:
9523 error = readdefects(cam_dev, argc, argv, combinedopt,
9524 task_attr, retry_count, timeout);
9526 case CAM_CMD_MODE_PAGE:
9527 modepage(cam_dev, argc, argv, combinedopt,
9528 task_attr, retry_count, timeout);
9530 case CAM_CMD_SCSI_CMD:
9531 error = scsicmd(cam_dev, argc, argv, combinedopt,
9532 task_attr, retry_count, timeout);
9534 case CAM_CMD_SMP_CMD:
9535 error = smpcmd(cam_dev, argc, argv, combinedopt,
9536 retry_count, timeout);
9538 case CAM_CMD_SMP_RG:
9539 error = smpreportgeneral(cam_dev, argc, argv,
9540 combinedopt, retry_count,
9543 case CAM_CMD_SMP_PC:
9544 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
9545 retry_count, timeout);
9547 case CAM_CMD_SMP_PHYLIST:
9548 error = smpphylist(cam_dev, argc, argv, combinedopt,
9549 retry_count, timeout);
9551 case CAM_CMD_SMP_MANINFO:
9552 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
9553 retry_count, timeout);
9556 error = camdebug(argc, argv, combinedopt);
9559 error = tagcontrol(cam_dev, argc, argv, combinedopt);
9562 error = ratecontrol(cam_dev, task_attr, retry_count,
9563 timeout, argc, argv, combinedopt);
9565 case CAM_CMD_FORMAT:
9566 error = scsiformat(cam_dev, argc, argv,
9567 combinedopt, task_attr, retry_count,
9570 case CAM_CMD_REPORTLUNS:
9571 error = scsireportluns(cam_dev, argc, argv,
9572 combinedopt, task_attr,
9573 retry_count, timeout);
9575 case CAM_CMD_READCAP:
9576 error = scsireadcapacity(cam_dev, argc, argv,
9577 combinedopt, task_attr,
9578 retry_count, timeout);
9581 case CAM_CMD_STANDBY:
9583 error = atapm(cam_dev, argc, argv,
9584 combinedopt, retry_count, timeout);
9588 error = ataaxm(cam_dev, argc, argv,
9589 combinedopt, retry_count, timeout);
9591 case CAM_CMD_SECURITY:
9592 error = atasecurity(cam_dev, retry_count, timeout,
9593 argc, argv, combinedopt);
9595 case CAM_CMD_DOWNLOAD_FW:
9596 error = fwdownload(cam_dev, argc, argv, combinedopt,
9597 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
9600 case CAM_CMD_SANITIZE:
9601 error = scsisanitize(cam_dev, argc, argv,
9602 combinedopt, task_attr,
9603 retry_count, timeout);
9605 case CAM_CMD_PERSIST:
9606 error = scsipersist(cam_dev, argc, argv, combinedopt,
9607 task_attr, retry_count, timeout,
9608 arglist & CAM_ARG_VERBOSE,
9609 arglist & CAM_ARG_ERR_RECOVER);
9611 case CAM_CMD_ATTRIB:
9612 error = scsiattrib(cam_dev, argc, argv, combinedopt,
9613 task_attr, retry_count, timeout,
9614 arglist & CAM_ARG_VERBOSE,
9615 arglist & CAM_ARG_ERR_RECOVER);
9617 case CAM_CMD_OPCODES:
9618 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
9619 task_attr, retry_count, timeout,
9620 arglist & CAM_ARG_VERBOSE);
9622 case CAM_CMD_REPROBE:
9623 error = scsireprobe(cam_dev);
9626 error = zone(cam_dev, argc, argv, combinedopt,
9627 task_attr, retry_count, timeout,
9628 arglist & CAM_ARG_VERBOSE);
9631 error = epc(cam_dev, argc, argv, combinedopt,
9632 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9634 case CAM_CMD_TIMESTAMP:
9635 error = timestamp(cam_dev, argc, argv, combinedopt,
9636 task_attr, retry_count, timeout,
9637 arglist & CAM_ARG_VERBOSE);
9639 #endif /* MINIMALISTIC */
9649 if (cam_dev != NULL)
9650 cam_close_device(cam_dev);