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);
1394 printf("Zoned-Device Commands ");
1395 switch (parm->support3 & ATA_SUPPORT_ZONE_MASK) {
1396 case ATA_SUPPORT_ZONE_DEV_MANAGED:
1397 printf("device managed\n");
1399 case ATA_SUPPORT_ZONE_HOST_AWARE:
1400 printf("host aware\n");
1407 "Support Enabled Value Vendor\n");
1408 printf("read ahead %s %s\n",
1409 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
1410 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
1411 printf("write cache %s %s\n",
1412 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
1413 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
1414 printf("flush cache %s %s\n",
1415 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
1416 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
1417 printf("overlap %s\n",
1418 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no");
1419 printf("Tagged Command Queuing (TCQ) %s %s",
1420 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
1421 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no");
1422 if (parm->support.command2 & ATA_SUPPORT_QUEUED) {
1423 printf(" %d tags\n",
1424 ATA_QUEUE_LEN(parm->queue) + 1);
1427 printf("Native Command Queuing (NCQ) ");
1428 if (parm->satacapabilities != 0xffff &&
1429 (parm->satacapabilities & ATA_SUPPORT_NCQ)) {
1430 printf("yes %d tags\n",
1431 ATA_QUEUE_LEN(parm->queue) + 1);
1435 printf("NCQ Queue Management %s\n", atasata(parm) &&
1436 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ?
1438 printf("NCQ Streaming %s\n", atasata(parm) &&
1439 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ?
1441 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) &&
1442 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ?
1445 printf("SMART %s %s\n",
1446 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
1447 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
1448 printf("microcode download %s %s\n",
1449 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
1450 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
1451 printf("security %s %s\n",
1452 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
1453 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
1454 printf("power management %s %s\n",
1455 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
1456 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
1457 printf("advanced power management %s %s",
1458 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
1459 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no");
1460 if (parm->support.command2 & ATA_SUPPORT_APM) {
1461 printf(" %d/0x%02X\n",
1462 parm->apm_value & 0xff, parm->apm_value & 0xff);
1465 printf("automatic acoustic management %s %s",
1466 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
1467 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no");
1468 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) {
1469 printf(" %d/0x%02X %d/0x%02X\n",
1470 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1471 ATA_ACOUSTIC_CURRENT(parm->acoustic),
1472 ATA_ACOUSTIC_VENDOR(parm->acoustic),
1473 ATA_ACOUSTIC_VENDOR(parm->acoustic));
1476 printf("media status notification %s %s\n",
1477 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
1478 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
1479 printf("power-up in Standby %s %s\n",
1480 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
1481 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
1482 printf("write-read-verify %s %s",
1483 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
1484 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no");
1485 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) {
1486 printf(" %d/0x%x\n",
1487 parm->wrv_mode, parm->wrv_mode);
1490 printf("unload %s %s\n",
1491 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1492 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1493 printf("general purpose logging %s %s\n",
1494 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no",
1495 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no");
1496 printf("free-fall %s %s\n",
1497 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1498 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1499 printf("Data Set Management (DSM/TRIM) ");
1500 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1502 printf("DSM - max 512byte blocks ");
1503 if (parm->max_dsm_blocks == 0x00)
1504 printf("yes not specified\n");
1507 parm->max_dsm_blocks);
1509 printf("DSM - deterministic read ");
1510 if (parm->support3 & ATA_SUPPORT_DRAT) {
1511 if (parm->support3 & ATA_SUPPORT_RZAT)
1512 printf("yes zeroed\n");
1514 printf("yes any value\n");
1524 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1526 struct ata_pass_16 *ata_pass_16;
1527 struct ata_cmd ata_cmd;
1529 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1530 ata_cmd.command = ata_pass_16->command;
1531 ata_cmd.control = ata_pass_16->control;
1532 ata_cmd.features = ata_pass_16->features;
1534 if (arglist & CAM_ARG_VERBOSE) {
1535 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1536 ata_op_string(&ata_cmd),
1537 ccb->csio.ccb_h.timeout);
1540 /* Disable freezing the device queue */
1541 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1543 if (arglist & CAM_ARG_ERR_RECOVER)
1544 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1546 if (cam_send_ccb(device, ccb) < 0) {
1547 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1548 warn("error sending ATA %s via pass_16",
1549 ata_op_string(&ata_cmd));
1552 if (arglist & CAM_ARG_VERBOSE) {
1553 cam_error_print(device, ccb, CAM_ESF_ALL,
1554 CAM_EPF_ALL, stderr);
1560 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1561 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1562 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1563 warnx("ATA %s via pass_16 failed",
1564 ata_op_string(&ata_cmd));
1566 if (arglist & CAM_ARG_VERBOSE) {
1567 cam_error_print(device, ccb, CAM_ESF_ALL,
1568 CAM_EPF_ALL, stderr);
1579 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1581 if (arglist & CAM_ARG_VERBOSE) {
1582 warnx("sending ATA %s with timeout of %u msecs",
1583 ata_op_string(&(ccb->ataio.cmd)),
1584 ccb->ataio.ccb_h.timeout);
1587 /* Disable freezing the device queue */
1588 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1590 if (arglist & CAM_ARG_ERR_RECOVER)
1591 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1593 if (cam_send_ccb(device, ccb) < 0) {
1594 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1595 warn("error sending ATA %s",
1596 ata_op_string(&(ccb->ataio.cmd)));
1599 if (arglist & CAM_ARG_VERBOSE) {
1600 cam_error_print(device, ccb, CAM_ESF_ALL,
1601 CAM_EPF_ALL, stderr);
1607 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1608 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1609 warnx("ATA %s failed: %d",
1610 ata_op_string(&(ccb->ataio.cmd)), quiet);
1613 if (arglist & CAM_ARG_VERBOSE) {
1614 cam_error_print(device, ccb, CAM_ESF_ALL,
1615 CAM_EPF_ALL, stderr);
1625 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1626 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1627 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1628 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1629 u_int16_t dxfer_len, int timeout, int quiet)
1631 if (data_ptr != NULL) {
1632 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1633 AP_FLAG_TLEN_SECT_CNT;
1634 if (flags & CAM_DIR_OUT)
1635 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1637 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1639 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1642 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
1644 scsi_ata_pass_16(&ccb->csio,
1658 /*sense_len*/SSD_FULL_SIZE,
1661 return scsi_cam_pass_16_send(device, ccb, quiet);
1665 ata_try_pass_16(struct cam_device *device)
1667 struct ccb_pathinq cpi;
1669 if (get_cpi(device, &cpi) != 0) {
1670 warnx("couldn't get CPI");
1674 if (cpi.protocol == PROTO_SCSI) {
1675 /* possibly compatible with pass_16 */
1679 /* likely not compatible with pass_16 */
1684 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1685 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1686 u_int8_t command, u_int8_t features, u_int32_t lba,
1687 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1688 int timeout, int quiet)
1692 switch (ata_try_pass_16(device)) {
1696 /* Try using SCSI Passthrough */
1697 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1698 0, tag_action, command, features, lba,
1699 sector_count, data_ptr, dxfer_len,
1703 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1704 cam_fill_ataio(&ccb->ataio,
1713 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1714 return ata_cam_send(device, ccb, quiet);
1718 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries,
1719 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1720 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1721 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1722 u_int16_t dxfer_len, int timeout, int force48bit)
1726 retval = ata_try_pass_16(device);
1733 /* Try using SCSI Passthrough */
1734 error = ata_do_pass_16(device, ccb, retries, flags, protocol,
1735 ata_flags, tag_action, command, features,
1736 lba, sector_count, data_ptr, dxfer_len,
1739 if (ata_flags & AP_FLAG_CHK_COND) {
1740 /* Decode ata_res from sense data */
1741 struct ata_res_pass16 *res_pass16;
1742 struct ata_res *res;
1746 /* sense_data is 4 byte aligned */
1747 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data;
1748 for (i = 0; i < sizeof(*res_pass16) / 2; i++)
1749 ptr[i] = le16toh(ptr[i]);
1751 /* sense_data is 4 byte aligned */
1752 res_pass16 = (struct ata_res_pass16 *)(uintptr_t)
1753 &ccb->csio.sense_data;
1754 res = &ccb->ataio.res;
1755 res->flags = res_pass16->flags;
1756 res->status = res_pass16->status;
1757 res->error = res_pass16->error;
1758 res->lba_low = res_pass16->lba_low;
1759 res->lba_mid = res_pass16->lba_mid;
1760 res->lba_high = res_pass16->lba_high;
1761 res->device = res_pass16->device;
1762 res->lba_low_exp = res_pass16->lba_low_exp;
1763 res->lba_mid_exp = res_pass16->lba_mid_exp;
1764 res->lba_high_exp = res_pass16->lba_high_exp;
1765 res->sector_count = res_pass16->sector_count;
1766 res->sector_count_exp = res_pass16->sector_count_exp;
1772 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio);
1773 cam_fill_ataio(&ccb->ataio,
1782 if (force48bit || lba > ATA_MAX_28BIT_LBA)
1783 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1785 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1787 if (ata_flags & AP_FLAG_CHK_COND)
1788 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
1790 return ata_cam_send(device, ccb, 0);
1794 dump_data(uint16_t *ptr, uint32_t len)
1798 for (i = 0; i < len / 2; i++) {
1800 printf(" %3d: ", i);
1801 printf("%04hx ", ptr[i]);
1810 atahpa_proc_resp(struct cam_device *device, union ccb *ccb,
1811 int is48bit, u_int64_t *hpasize)
1813 struct ata_res *res;
1815 res = &ccb->ataio.res;
1816 if (res->status & ATA_STATUS_ERROR) {
1817 if (arglist & CAM_ARG_VERBOSE) {
1818 cam_error_print(device, ccb, CAM_ESF_ALL,
1819 CAM_EPF_ALL, stderr);
1820 printf("error = 0x%02x, sector_count = 0x%04x, "
1821 "device = 0x%02x, status = 0x%02x\n",
1822 res->error, res->sector_count,
1823 res->device, res->status);
1826 if (res->error & ATA_ERROR_ID_NOT_FOUND) {
1827 warnx("Max address has already been set since "
1828 "last power-on or hardware reset");
1834 if (arglist & CAM_ARG_VERBOSE) {
1835 fprintf(stdout, "%s%d: Raw native max data:\n",
1836 device->device_name, device->dev_unit_num);
1837 /* res is 4 byte aligned */
1838 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res));
1840 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, "
1841 "status = 0x%02x\n", res->error, res->sector_count,
1842 res->device, res->status);
1845 if (hpasize != NULL) {
1847 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) |
1848 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) |
1849 ((res->lba_high << 16) | (res->lba_mid << 8) |
1852 *hpasize = (((res->device & 0x0f) << 24) |
1853 (res->lba_high << 16) | (res->lba_mid << 8) |
1862 ata_read_native_max(struct cam_device *device, int retry_count,
1863 u_int32_t timeout, union ccb *ccb,
1864 struct ata_params *parm, u_int64_t *hpasize)
1870 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48;
1871 protocol = AP_PROTO_NON_DATA;
1874 cmd = ATA_READ_NATIVE_MAX_ADDRESS48;
1875 protocol |= AP_EXTEND;
1877 cmd = ATA_READ_NATIVE_MAX_ADDRESS;
1880 error = ata_do_cmd(device,
1883 /*flags*/CAM_DIR_NONE,
1884 /*protocol*/protocol,
1885 /*ata_flags*/AP_FLAG_CHK_COND,
1886 /*tag_action*/MSG_SIMPLE_Q_TAG,
1893 timeout ? timeout : 1000,
1899 return atahpa_proc_resp(device, ccb, is48bit, hpasize);
1903 atahpa_set_max(struct cam_device *device, int retry_count,
1904 u_int32_t timeout, union ccb *ccb,
1905 int is48bit, u_int64_t maxsize, int persist)
1911 protocol = AP_PROTO_NON_DATA;
1914 cmd = ATA_SET_MAX_ADDRESS48;
1915 protocol |= AP_EXTEND;
1917 cmd = ATA_SET_MAX_ADDRESS;
1920 /* lba's are zero indexed so the max lba is requested max - 1 */
1924 error = ata_do_cmd(device,
1927 /*flags*/CAM_DIR_NONE,
1928 /*protocol*/protocol,
1929 /*ata_flags*/AP_FLAG_CHK_COND,
1930 /*tag_action*/MSG_SIMPLE_Q_TAG,
1932 /*features*/ATA_HPA_FEAT_MAX_ADDR,
1934 /*sector_count*/persist,
1937 timeout ? timeout : 1000,
1943 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1947 atahpa_password(struct cam_device *device, int retry_count,
1948 u_int32_t timeout, union ccb *ccb,
1949 int is48bit, struct ata_set_max_pwd *pwd)
1955 protocol = AP_PROTO_PIO_OUT;
1956 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1958 error = ata_do_cmd(device,
1961 /*flags*/CAM_DIR_OUT,
1962 /*protocol*/protocol,
1963 /*ata_flags*/AP_FLAG_CHK_COND,
1964 /*tag_action*/MSG_SIMPLE_Q_TAG,
1966 /*features*/ATA_HPA_FEAT_SET_PWD,
1969 /*data_ptr*/(u_int8_t*)pwd,
1970 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
1971 timeout ? timeout : 1000,
1977 return atahpa_proc_resp(device, ccb, is48bit, NULL);
1981 atahpa_lock(struct cam_device *device, int retry_count,
1982 u_int32_t timeout, union ccb *ccb, int is48bit)
1988 protocol = AP_PROTO_NON_DATA;
1989 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
1991 error = ata_do_cmd(device,
1994 /*flags*/CAM_DIR_NONE,
1995 /*protocol*/protocol,
1996 /*ata_flags*/AP_FLAG_CHK_COND,
1997 /*tag_action*/MSG_SIMPLE_Q_TAG,
1999 /*features*/ATA_HPA_FEAT_LOCK,
2004 timeout ? timeout : 1000,
2010 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2014 atahpa_unlock(struct cam_device *device, int retry_count,
2015 u_int32_t timeout, union ccb *ccb,
2016 int is48bit, struct ata_set_max_pwd *pwd)
2022 protocol = AP_PROTO_PIO_OUT;
2023 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2025 error = ata_do_cmd(device,
2028 /*flags*/CAM_DIR_OUT,
2029 /*protocol*/protocol,
2030 /*ata_flags*/AP_FLAG_CHK_COND,
2031 /*tag_action*/MSG_SIMPLE_Q_TAG,
2033 /*features*/ATA_HPA_FEAT_UNLOCK,
2036 /*data_ptr*/(u_int8_t*)pwd,
2037 /*dxfer_len*/sizeof(struct ata_set_max_pwd),
2038 timeout ? timeout : 1000,
2044 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2048 atahpa_freeze_lock(struct cam_device *device, int retry_count,
2049 u_int32_t timeout, union ccb *ccb, int is48bit)
2055 protocol = AP_PROTO_NON_DATA;
2056 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS;
2058 error = ata_do_cmd(device,
2061 /*flags*/CAM_DIR_NONE,
2062 /*protocol*/protocol,
2063 /*ata_flags*/AP_FLAG_CHK_COND,
2064 /*tag_action*/MSG_SIMPLE_Q_TAG,
2066 /*features*/ATA_HPA_FEAT_FREEZE,
2071 timeout ? timeout : 1000,
2077 return atahpa_proc_resp(device, ccb, is48bit, NULL);
2082 ata_do_identify(struct cam_device *device, int retry_count, int timeout,
2083 union ccb *ccb, struct ata_params** ident_bufp)
2085 struct ata_params *ident_buf;
2086 struct ccb_pathinq cpi;
2087 struct ccb_getdev cgd;
2090 u_int8_t command, retry_command;
2092 if (get_cpi(device, &cpi) != 0) {
2093 warnx("couldn't get CPI");
2097 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
2098 if (cpi.protocol == PROTO_ATA) {
2099 if (get_cgd(device, &cgd) != 0) {
2100 warnx("couldn't get CGD");
2104 command = (cgd.protocol == PROTO_ATA) ?
2105 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
2108 /* We don't know which for sure so try both */
2109 command = ATA_ATA_IDENTIFY;
2110 retry_command = ATA_ATAPI_IDENTIFY;
2113 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
2115 warnx("can't calloc memory for identify\n");
2119 error = ata_do_28bit_cmd(device,
2121 /*retries*/retry_count,
2122 /*flags*/CAM_DIR_IN,
2123 /*protocol*/AP_PROTO_PIO_IN,
2124 /*tag_action*/MSG_SIMPLE_Q_TAG,
2128 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
2129 /*data_ptr*/(u_int8_t *)ptr,
2130 /*dxfer_len*/sizeof(struct ata_params),
2131 /*timeout*/timeout ? timeout : 30 * 1000,
2135 if (retry_command == 0) {
2139 error = ata_do_28bit_cmd(device,
2141 /*retries*/retry_count,
2142 /*flags*/CAM_DIR_IN,
2143 /*protocol*/AP_PROTO_PIO_IN,
2144 /*tag_action*/MSG_SIMPLE_Q_TAG,
2145 /*command*/retry_command,
2148 /*sector_count*/(u_int8_t)
2149 sizeof(struct ata_params),
2150 /*data_ptr*/(u_int8_t *)ptr,
2151 /*dxfer_len*/sizeof(struct ata_params),
2152 /*timeout*/timeout ? timeout : 30 * 1000,
2162 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
2163 ptr[i] = le16toh(ptr[i]);
2168 if (arglist & CAM_ARG_VERBOSE) {
2169 fprintf(stdout, "%s%d: Raw identify data:\n",
2170 device->device_name, device->dev_unit_num);
2171 dump_data(ptr, sizeof(struct ata_params));
2174 /* check for invalid (all zero) response */
2176 warnx("Invalid identify response detected");
2181 ident_buf = (struct ata_params *)ptr;
2182 if (strncmp(ident_buf->model, "FX", 2) &&
2183 strncmp(ident_buf->model, "NEC", 3) &&
2184 strncmp(ident_buf->model, "Pioneer", 7) &&
2185 strncmp(ident_buf->model, "SHARP", 5)) {
2186 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
2187 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
2188 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
2189 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2191 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
2192 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
2193 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
2194 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
2195 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
2196 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
2197 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
2198 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
2199 sizeof(ident_buf->media_serial));
2201 *ident_bufp = ident_buf;
2208 ataidentify(struct cam_device *device, int retry_count, int timeout)
2211 struct ata_params *ident_buf;
2214 if ((ccb = cam_getccb(device)) == NULL) {
2215 warnx("couldn't allocate CCB");
2219 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
2224 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) {
2225 if (ata_read_native_max(device, retry_count, timeout, ccb,
2226 ident_buf, &hpasize) != 0) {
2234 printf("%s%d: ", device->device_name, device->dev_unit_num);
2235 ata_print_ident(ident_buf);
2236 camxferrate(device);
2237 atacapprint(ident_buf);
2238 atahpa_print(ident_buf, hpasize, 0);
2245 #endif /* MINIMALISTIC */
2248 #ifndef MINIMALISTIC
2250 ATA_SECURITY_ACTION_PRINT,
2251 ATA_SECURITY_ACTION_FREEZE,
2252 ATA_SECURITY_ACTION_UNLOCK,
2253 ATA_SECURITY_ACTION_DISABLE,
2254 ATA_SECURITY_ACTION_ERASE,
2255 ATA_SECURITY_ACTION_ERASE_ENHANCED,
2256 ATA_SECURITY_ACTION_SET_PASSWORD
2260 atasecurity_print_time(u_int16_t tw)
2264 printf("unspecified");
2266 printf("> 508 min");
2268 printf("%i min", 2 * tw);
2272 atasecurity_erase_timeout_msecs(u_int16_t timeout)
2276 return 2 * 3600 * 1000; /* default: two hours */
2277 else if (timeout > 255)
2278 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
2280 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
2285 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
2289 bzero(&cmd, sizeof(cmd));
2290 cmd.command = command;
2291 printf("Issuing %s", ata_op_string(&cmd));
2294 char pass[sizeof(pwd->password)+1];
2296 /* pwd->password may not be null terminated */
2297 pass[sizeof(pwd->password)] = '\0';
2298 strncpy(pass, pwd->password, sizeof(pwd->password));
2299 printf(" password='%s', user='%s'",
2301 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2304 if (command == ATA_SECURITY_SET_PASSWORD) {
2305 printf(", mode='%s'",
2306 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2307 "maximum" : "high");
2315 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2316 int retry_count, u_int32_t timeout, int quiet)
2320 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2322 return ata_do_28bit_cmd(device,
2325 /*flags*/CAM_DIR_NONE,
2326 /*protocol*/AP_PROTO_NON_DATA,
2327 /*tag_action*/MSG_SIMPLE_Q_TAG,
2328 /*command*/ATA_SECURITY_FREEZE_LOCK,
2339 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2340 int retry_count, u_int32_t timeout,
2341 struct ata_security_password *pwd, int quiet)
2345 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2347 return ata_do_28bit_cmd(device,
2350 /*flags*/CAM_DIR_OUT,
2351 /*protocol*/AP_PROTO_PIO_OUT,
2352 /*tag_action*/MSG_SIMPLE_Q_TAG,
2353 /*command*/ATA_SECURITY_UNLOCK,
2357 /*data_ptr*/(u_int8_t *)pwd,
2358 /*dxfer_len*/sizeof(*pwd),
2364 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2365 int retry_count, u_int32_t timeout,
2366 struct ata_security_password *pwd, int quiet)
2370 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2371 return ata_do_28bit_cmd(device,
2374 /*flags*/CAM_DIR_OUT,
2375 /*protocol*/AP_PROTO_PIO_OUT,
2376 /*tag_action*/MSG_SIMPLE_Q_TAG,
2377 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2381 /*data_ptr*/(u_int8_t *)pwd,
2382 /*dxfer_len*/sizeof(*pwd),
2389 atasecurity_erase_confirm(struct cam_device *device,
2390 struct ata_params* ident_buf)
2393 printf("\nYou are about to ERASE ALL DATA from the following"
2394 " device:\n%s%d,%s%d: ", device->device_name,
2395 device->dev_unit_num, device->given_dev_name,
2396 device->given_unit_number);
2397 ata_print_ident(ident_buf);
2401 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2403 if (fgets(str, sizeof(str), stdin) != NULL) {
2404 if (strncasecmp(str, "yes", 3) == 0) {
2406 } else if (strncasecmp(str, "no", 2) == 0) {
2409 printf("Please answer \"yes\" or "
2420 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2421 int retry_count, u_int32_t timeout,
2422 u_int32_t erase_timeout,
2423 struct ata_security_password *pwd, int quiet)
2428 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2430 error = ata_do_28bit_cmd(device,
2433 /*flags*/CAM_DIR_NONE,
2434 /*protocol*/AP_PROTO_NON_DATA,
2435 /*tag_action*/MSG_SIMPLE_Q_TAG,
2436 /*command*/ATA_SECURITY_ERASE_PREPARE,
2449 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2451 error = ata_do_28bit_cmd(device,
2454 /*flags*/CAM_DIR_OUT,
2455 /*protocol*/AP_PROTO_PIO_OUT,
2456 /*tag_action*/MSG_SIMPLE_Q_TAG,
2457 /*command*/ATA_SECURITY_ERASE_UNIT,
2461 /*data_ptr*/(u_int8_t *)pwd,
2462 /*dxfer_len*/sizeof(*pwd),
2463 /*timeout*/erase_timeout,
2466 if (error == 0 && quiet == 0)
2467 printf("\nErase Complete\n");
2473 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2474 int retry_count, u_int32_t timeout,
2475 struct ata_security_password *pwd, int quiet)
2479 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2481 return ata_do_28bit_cmd(device,
2484 /*flags*/CAM_DIR_OUT,
2485 /*protocol*/AP_PROTO_PIO_OUT,
2486 /*tag_action*/MSG_SIMPLE_Q_TAG,
2487 /*command*/ATA_SECURITY_SET_PASSWORD,
2491 /*data_ptr*/(u_int8_t *)pwd,
2492 /*dxfer_len*/sizeof(*pwd),
2498 atasecurity_print(struct ata_params *parm)
2501 printf("\nSecurity Option Value\n");
2502 if (arglist & CAM_ARG_VERBOSE) {
2503 printf("status %04x\n",
2504 parm->security_status);
2506 printf("supported %s\n",
2507 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2508 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2510 printf("enabled %s\n",
2511 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2512 printf("drive locked %s\n",
2513 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2514 printf("security config frozen %s\n",
2515 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2516 printf("count expired %s\n",
2517 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2518 printf("security level %s\n",
2519 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2520 printf("enhanced erase supported %s\n",
2521 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2522 printf("erase time ");
2523 atasecurity_print_time(parm->erase_time);
2525 printf("enhanced erase time ");
2526 atasecurity_print_time(parm->enhanced_erase_time);
2528 printf("master password rev %04x%s\n",
2529 parm->master_passwd_revision,
2530 parm->master_passwd_revision == 0x0000 ||
2531 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2535 * Validates and copies the password in optarg to the passed buffer.
2536 * If the password in optarg is the same length as the buffer then
2537 * the data will still be copied but no null termination will occur.
2540 ata_getpwd(u_int8_t *passwd, int max, char opt)
2544 len = strlen(optarg);
2546 warnx("-%c password is too long", opt);
2548 } else if (len == 0) {
2549 warnx("-%c password is missing", opt);
2551 } else if (optarg[0] == '-'){
2552 warnx("-%c password starts with '-' (generic arg?)", opt);
2554 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2555 warnx("-%c password conflicts with existing password from -%c",
2560 /* Callers pass in a buffer which does NOT need to be terminated */
2561 strncpy(passwd, optarg, max);
2568 ATA_HPA_ACTION_PRINT,
2569 ATA_HPA_ACTION_SET_MAX,
2570 ATA_HPA_ACTION_SET_PWD,
2571 ATA_HPA_ACTION_LOCK,
2572 ATA_HPA_ACTION_UNLOCK,
2573 ATA_HPA_ACTION_FREEZE_LOCK
2577 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2578 u_int64_t maxsize, int persist)
2580 printf("\nYou are about to configure HPA to limit the user accessible\n"
2581 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2582 persist ? "persistently" : "temporarily",
2583 device->device_name, device->dev_unit_num,
2584 device->given_dev_name, device->given_unit_number);
2585 ata_print_ident(ident_buf);
2589 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2591 if (NULL != fgets(str, sizeof(str), stdin)) {
2592 if (0 == strncasecmp(str, "yes", 3)) {
2594 } else if (0 == strncasecmp(str, "no", 2)) {
2597 printf("Please answer \"yes\" or "
2608 atahpa(struct cam_device *device, int retry_count, int timeout,
2609 int argc, char **argv, char *combinedopt)
2612 struct ata_params *ident_buf;
2613 struct ccb_getdev cgd;
2614 struct ata_set_max_pwd pwd;
2615 int error, confirm, quiet, c, action, actions, persist;
2616 int security, is48bit, pwdsize;
2617 u_int64_t hpasize, maxsize;
2626 memset(&pwd, 0, sizeof(pwd));
2628 /* default action is to print hpa information */
2629 action = ATA_HPA_ACTION_PRINT;
2630 pwdsize = sizeof(pwd.password);
2632 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2635 action = ATA_HPA_ACTION_SET_MAX;
2636 maxsize = strtoumax(optarg, NULL, 0);
2641 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2643 action = ATA_HPA_ACTION_SET_PWD;
2649 action = ATA_HPA_ACTION_LOCK;
2655 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2657 action = ATA_HPA_ACTION_UNLOCK;
2663 action = ATA_HPA_ACTION_FREEZE_LOCK;
2683 warnx("too many hpa actions specified");
2687 if (get_cgd(device, &cgd) != 0) {
2688 warnx("couldn't get CGD");
2692 ccb = cam_getccb(device);
2694 warnx("couldn't allocate CCB");
2698 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2705 printf("%s%d: ", device->device_name, device->dev_unit_num);
2706 ata_print_ident(ident_buf);
2707 camxferrate(device);
2710 if (action == ATA_HPA_ACTION_PRINT) {
2711 error = ata_read_native_max(device, retry_count, timeout, ccb,
2712 ident_buf, &hpasize);
2714 atahpa_print(ident_buf, hpasize, 1);
2721 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2722 warnx("HPA is not supported by this device");
2728 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) {
2729 warnx("HPA Security is not supported by this device");
2735 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2738 * The ATA spec requires:
2739 * 1. Read native max addr is called directly before set max addr
2740 * 2. Read native max addr is NOT called before any other set max call
2743 case ATA_HPA_ACTION_SET_MAX:
2745 atahpa_set_confirm(device, ident_buf, maxsize,
2752 error = ata_read_native_max(device, retry_count, timeout,
2753 ccb, ident_buf, &hpasize);
2755 error = atahpa_set_max(device, retry_count, timeout,
2756 ccb, is48bit, maxsize, persist);
2758 /* redo identify to get new lba values */
2759 error = ata_do_identify(device, retry_count,
2762 atahpa_print(ident_buf, hpasize, 1);
2767 case ATA_HPA_ACTION_SET_PWD:
2768 error = atahpa_password(device, retry_count, timeout,
2769 ccb, is48bit, &pwd);
2771 printf("HPA password has been set\n");
2774 case ATA_HPA_ACTION_LOCK:
2775 error = atahpa_lock(device, retry_count, timeout,
2778 printf("HPA has been locked\n");
2781 case ATA_HPA_ACTION_UNLOCK:
2782 error = atahpa_unlock(device, retry_count, timeout,
2783 ccb, is48bit, &pwd);
2785 printf("HPA has been unlocked\n");
2788 case ATA_HPA_ACTION_FREEZE_LOCK:
2789 error = atahpa_freeze_lock(device, retry_count, timeout,
2792 printf("HPA has been frozen\n");
2796 errx(1, "Option currently not supported");
2806 atasecurity(struct cam_device *device, int retry_count, int timeout,
2807 int argc, char **argv, char *combinedopt)
2810 struct ata_params *ident_buf;
2811 int error, confirm, quiet, c, action, actions, setpwd;
2812 int security_enabled, erase_timeout, pwdsize;
2813 struct ata_security_password pwd;
2821 memset(&pwd, 0, sizeof(pwd));
2823 /* default action is to print security information */
2824 action = ATA_SECURITY_ACTION_PRINT;
2826 /* user is master by default as its safer that way */
2827 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2828 pwdsize = sizeof(pwd.password);
2830 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2833 action = ATA_SECURITY_ACTION_FREEZE;
2838 if (strcasecmp(optarg, "user") == 0) {
2839 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2840 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2841 } else if (strcasecmp(optarg, "master") == 0) {
2842 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2843 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2845 warnx("-U argument '%s' is invalid (must be "
2846 "'user' or 'master')", optarg);
2852 if (strcasecmp(optarg, "high") == 0) {
2853 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2854 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2855 } else if (strcasecmp(optarg, "maximum") == 0) {
2856 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2857 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2859 warnx("-l argument '%s' is unknown (must be "
2860 "'high' or 'maximum')", optarg);
2866 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2868 action = ATA_SECURITY_ACTION_UNLOCK;
2873 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2875 action = ATA_SECURITY_ACTION_DISABLE;
2880 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2882 action = ATA_SECURITY_ACTION_ERASE;
2887 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2889 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2890 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2895 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2898 if (action == ATA_SECURITY_ACTION_PRINT)
2899 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2901 * Don't increment action as this can be combined
2902 * with other actions.
2915 erase_timeout = atoi(optarg) * 1000;
2921 warnx("too many security actions specified");
2925 if ((ccb = cam_getccb(device)) == NULL) {
2926 warnx("couldn't allocate CCB");
2930 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2937 printf("%s%d: ", device->device_name, device->dev_unit_num);
2938 ata_print_ident(ident_buf);
2939 camxferrate(device);
2942 if (action == ATA_SECURITY_ACTION_PRINT) {
2943 atasecurity_print(ident_buf);
2949 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2950 warnx("Security not supported");
2956 /* default timeout 15 seconds the same as linux hdparm */
2957 timeout = timeout ? timeout : 15 * 1000;
2959 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2961 /* first set the password if requested */
2963 /* confirm we can erase before setting the password if erasing */
2965 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2966 action == ATA_SECURITY_ACTION_ERASE) &&
2967 atasecurity_erase_confirm(device, ident_buf) == 0) {
2973 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2974 pwd.revision = ident_buf->master_passwd_revision;
2975 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2976 --pwd.revision == 0) {
2977 pwd.revision = 0xfffe;
2980 error = atasecurity_set_password(device, ccb, retry_count,
2981 timeout, &pwd, quiet);
2987 security_enabled = 1;
2991 case ATA_SECURITY_ACTION_FREEZE:
2992 error = atasecurity_freeze(device, ccb, retry_count,
2996 case ATA_SECURITY_ACTION_UNLOCK:
2997 if (security_enabled) {
2998 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2999 error = atasecurity_unlock(device, ccb,
3000 retry_count, timeout, &pwd, quiet);
3002 warnx("Can't unlock, drive is not locked");
3006 warnx("Can't unlock, security is disabled");
3011 case ATA_SECURITY_ACTION_DISABLE:
3012 if (security_enabled) {
3013 /* First unlock the drive if its locked */
3014 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3015 error = atasecurity_unlock(device, ccb,
3023 error = atasecurity_disable(device,
3031 warnx("Can't disable security (already disabled)");
3036 case ATA_SECURITY_ACTION_ERASE:
3037 if (security_enabled) {
3038 if (erase_timeout == 0) {
3039 erase_timeout = atasecurity_erase_timeout_msecs(
3040 ident_buf->erase_time);
3043 error = atasecurity_erase(device, ccb, retry_count,
3044 timeout, erase_timeout, &pwd,
3047 warnx("Can't secure erase (security is disabled)");
3052 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3053 if (security_enabled) {
3054 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3055 if (erase_timeout == 0) {
3057 atasecurity_erase_timeout_msecs(
3058 ident_buf->enhanced_erase_time);
3061 error = atasecurity_erase(device, ccb,
3062 retry_count, timeout,
3063 erase_timeout, &pwd,
3066 warnx("Enhanced erase is not supported");
3070 warnx("Can't secure erase (enhanced), "
3071 "(security is disabled)");
3082 #endif /* MINIMALISTIC */
3085 * Parse out a bus, or a bus, target and lun in the following
3091 * Returns the number of parsed components, or 0.
3094 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3095 cam_argmask *arglst)
3100 while (isspace(*tstr) && (*tstr != '\0'))
3103 tmpstr = (char *)strtok(tstr, ":");
3104 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3105 *bus = strtol(tmpstr, NULL, 0);
3106 *arglst |= CAM_ARG_BUS;
3108 tmpstr = (char *)strtok(NULL, ":");
3109 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3110 *target = strtol(tmpstr, NULL, 0);
3111 *arglst |= CAM_ARG_TARGET;
3113 tmpstr = (char *)strtok(NULL, ":");
3114 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3115 *lun = strtol(tmpstr, NULL, 0);
3116 *arglst |= CAM_ARG_LUN;
3126 dorescan_or_reset(int argc, char **argv, int rescan)
3128 static const char must[] =
3129 "you must specify \"all\", a bus, or a bus:target:lun to %s";
3131 path_id_t bus = CAM_BUS_WILDCARD;
3132 target_id_t target = CAM_TARGET_WILDCARD;
3133 lun_id_t lun = CAM_LUN_WILDCARD;
3137 warnx(must, rescan? "rescan" : "reset");
3141 tstr = argv[optind];
3142 while (isspace(*tstr) && (*tstr != '\0'))
3144 if (strncasecmp(tstr, "all", strlen("all")) == 0)
3145 arglist |= CAM_ARG_BUS;
3146 else if (isdigit(*tstr)) {
3147 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3148 if (rv != 1 && rv != 3) {
3149 warnx(must, rescan? "rescan" : "reset");
3159 * Note that resetting or rescanning a device used to
3160 * require a bus or bus:target:lun. This is because the
3161 * device in question may not exist and you're trying to
3162 * get the controller to rescan to find it. It may also be
3163 * because the device is hung / unresponsive, and opening
3164 * an unresponsive device is not desireable.
3166 * It can be more convenient to reference a device by
3167 * peripheral name and unit number, though, and it is
3168 * possible to get the bus:target:lun for devices that
3169 * currently exist in the EDT. So this can work for
3170 * devices that we want to reset, or devices that exist
3171 * that we want to rescan, but not devices that do not
3174 * So, we are careful here to look up the bus/target/lun
3175 * for the device the user wants to operate on, specified
3176 * by peripheral instance (e.g. da0, pass32) without
3177 * actually opening that device. The process is similar to
3178 * what cam_lookup_pass() does, except that we don't
3179 * actually open the passthrough driver instance in the end.
3182 if (cam_get_device(tstr, name, sizeof(name), &unit) == -1) {
3183 warnx("%s", cam_errbuf);
3188 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3189 warn("Unable to open %s", XPT_DEVICE);
3194 bzero(&ccb, sizeof(ccb));
3197 * The function code isn't strictly necessary for the
3198 * GETPASSTHRU ioctl.
3200 ccb.ccb_h.func_code = XPT_GDEVLIST;
3203 * These two are necessary for the GETPASSTHRU ioctl to
3206 strlcpy(ccb.cgdl.periph_name, name,
3207 sizeof(ccb.cgdl.periph_name));
3208 ccb.cgdl.unit_number = unit;
3211 * Attempt to get the passthrough device. This ioctl will
3212 * fail if the device name is null, if the device doesn't
3213 * exist, or if the passthrough driver isn't in the kernel.
3215 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3216 warn("Unable to find bus:target:lun for device %s%d",
3222 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3223 const struct cam_status_entry *entry;
3225 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3226 warnx("Unable to find bus:target_lun for device %s%d, "
3227 "CAM status: %s (%#x)", name, unit,
3228 entry ? entry->status_text : "Unknown",
3236 * The kernel fills in the bus/target/lun. We don't
3237 * need the passthrough device name and unit number since
3238 * we aren't going to open it.
3240 bus = ccb.ccb_h.path_id;
3241 target = ccb.ccb_h.target_id;
3242 lun = ccb.ccb_h.target_lun;
3244 arglist |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3249 if ((arglist & CAM_ARG_BUS)
3250 && (arglist & CAM_ARG_TARGET)
3251 && (arglist & CAM_ARG_LUN))
3252 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3254 error = rescan_or_reset_bus(bus, rescan);
3262 rescan_or_reset_bus(path_id_t bus, int rescan)
3264 union ccb *ccb = NULL, *matchccb = NULL;
3265 int fd = -1, retval;
3270 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3271 warnx("error opening transport layer device %s", XPT_DEVICE);
3272 warn("%s", XPT_DEVICE);
3276 ccb = malloc(sizeof(*ccb));
3278 warn("failed to allocate CCB");
3282 bzero(ccb, sizeof(*ccb));
3284 if (bus != CAM_BUS_WILDCARD) {
3285 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3286 ccb->ccb_h.path_id = bus;
3287 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3288 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3289 ccb->crcn.flags = CAM_FLAG_NONE;
3291 /* run this at a low priority */
3292 ccb->ccb_h.pinfo.priority = 5;
3294 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3295 warn("CAMIOCOMMAND ioctl failed");
3300 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3301 fprintf(stdout, "%s of bus %d was successful\n",
3302 rescan ? "Re-scan" : "Reset", bus);
3304 fprintf(stdout, "%s of bus %d returned error %#x\n",
3305 rescan ? "Re-scan" : "Reset", bus,
3306 ccb->ccb_h.status & CAM_STATUS_MASK);
3315 * The right way to handle this is to modify the xpt so that it can
3316 * handle a wildcarded bus in a rescan or reset CCB. At the moment
3317 * that isn't implemented, so instead we enumerate the busses and
3318 * send the rescan or reset to those busses in the case where the
3319 * given bus is -1 (wildcard). We don't send a rescan or reset
3320 * to the xpt bus; sending a rescan to the xpt bus is effectively a
3321 * no-op, sending a rescan to the xpt bus would result in a status of
3324 matchccb = malloc(sizeof(*matchccb));
3325 if (matchccb == NULL) {
3326 warn("failed to allocate CCB");
3330 bzero(matchccb, sizeof(*matchccb));
3331 matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3332 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3333 bufsize = sizeof(struct dev_match_result) * 20;
3334 matchccb->cdm.match_buf_len = bufsize;
3335 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3336 if (matchccb->cdm.matches == NULL) {
3337 warnx("can't malloc memory for matches");
3341 matchccb->cdm.num_matches = 0;
3343 matchccb->cdm.num_patterns = 1;
3344 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3346 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3347 matchccb->cdm.pattern_buf_len);
3348 if (matchccb->cdm.patterns == NULL) {
3349 warnx("can't malloc memory for patterns");
3353 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3354 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3359 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3360 warn("CAMIOCOMMAND ioctl failed");
3365 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3366 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3367 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3368 warnx("got CAM error %#x, CDM error %d\n",
3369 matchccb->ccb_h.status, matchccb->cdm.status);
3374 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3375 struct bus_match_result *bus_result;
3377 /* This shouldn't happen. */
3378 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3381 bus_result =&matchccb->cdm.matches[i].result.bus_result;
3384 * We don't want to rescan or reset the xpt bus.
3387 if (bus_result->path_id == CAM_XPT_PATH_ID)
3390 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3392 ccb->ccb_h.path_id = bus_result->path_id;
3393 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3394 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3395 ccb->crcn.flags = CAM_FLAG_NONE;
3397 /* run this at a low priority */
3398 ccb->ccb_h.pinfo.priority = 5;
3400 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3401 warn("CAMIOCOMMAND ioctl failed");
3406 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3407 fprintf(stdout, "%s of bus %d was successful\n",
3408 rescan? "Re-scan" : "Reset",
3409 bus_result->path_id);
3412 * Don't bail out just yet, maybe the other
3413 * rescan or reset commands will complete
3416 fprintf(stderr, "%s of bus %d returned error "
3417 "%#x\n", rescan? "Re-scan" : "Reset",
3418 bus_result->path_id,
3419 ccb->ccb_h.status & CAM_STATUS_MASK);
3423 } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3424 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3431 if (matchccb != NULL) {
3432 free(matchccb->cdm.patterns);
3433 free(matchccb->cdm.matches);
3442 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3445 struct cam_device *device;
3450 if (bus == CAM_BUS_WILDCARD) {
3451 warnx("invalid bus number %d", bus);
3455 if (target == CAM_TARGET_WILDCARD) {
3456 warnx("invalid target number %d", target);
3460 if (lun == CAM_LUN_WILDCARD) {
3461 warnx("invalid lun number %jx", (uintmax_t)lun);
3467 bzero(&ccb, sizeof(union ccb));
3470 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3471 warnx("error opening transport layer device %s\n",
3473 warn("%s", XPT_DEVICE);
3477 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3478 if (device == NULL) {
3479 warnx("%s", cam_errbuf);
3484 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3485 ccb.ccb_h.path_id = bus;
3486 ccb.ccb_h.target_id = target;
3487 ccb.ccb_h.target_lun = lun;
3488 ccb.ccb_h.timeout = 5000;
3489 ccb.crcn.flags = CAM_FLAG_NONE;
3491 /* run this at a low priority */
3492 ccb.ccb_h.pinfo.priority = 5;
3495 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3496 warn("CAMIOCOMMAND ioctl failed");
3501 if (cam_send_ccb(device, &ccb) < 0) {
3502 warn("error sending XPT_RESET_DEV CCB");
3503 cam_close_device(device);
3511 cam_close_device(device);
3514 * An error code of CAM_BDR_SENT is normal for a BDR request.
3516 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3518 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3519 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3520 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3523 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3524 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3525 ccb.ccb_h.status & CAM_STATUS_MASK);
3530 #ifndef MINIMALISTIC
3532 static struct scsi_nv defect_list_type_map[] = {
3533 { "block", SRDD10_BLOCK_FORMAT },
3534 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3535 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3536 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3537 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3538 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3542 readdefects(struct cam_device *device, int argc, char **argv,
3543 char *combinedopt, int task_attr, int retry_count, int timeout)
3545 union ccb *ccb = NULL;
3546 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3547 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3548 size_t hdr_size = 0, entry_size = 0;
3551 u_int8_t *defect_list = NULL;
3552 u_int8_t list_format = 0;
3553 int list_type_set = 0;
3554 u_int32_t dlist_length = 0;
3555 u_int32_t returned_length = 0, valid_len = 0;
3556 u_int32_t num_returned = 0, num_valid = 0;
3557 u_int32_t max_possible_size = 0, hdr_max = 0;
3558 u_int32_t starting_offset = 0;
3559 u_int8_t returned_format, returned_type;
3561 int summary = 0, quiet = 0;
3563 int lists_specified = 0;
3564 int get_length = 1, first_pass = 1;
3567 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3571 scsi_nv_status status;
3574 status = scsi_get_nv(defect_list_type_map,
3575 sizeof(defect_list_type_map) /
3576 sizeof(defect_list_type_map[0]), optarg,
3577 &entry_num, SCSI_NV_FLAG_IG_CASE);
3579 if (status == SCSI_NV_FOUND) {
3580 list_format = defect_list_type_map[
3584 warnx("%s: %s %s option %s", __func__,
3585 (status == SCSI_NV_AMBIGUOUS) ?
3586 "ambiguous" : "invalid", "defect list type",
3589 goto defect_bailout;
3594 arglist |= CAM_ARG_GLIST;
3597 arglist |= CAM_ARG_PLIST;
3608 starting_offset = strtoul(optarg, &endptr, 0);
3609 if (*endptr != '\0') {
3611 warnx("invalid starting offset %s", optarg);
3612 goto defect_bailout;
3624 if (list_type_set == 0) {
3626 warnx("no defect list format specified");
3627 goto defect_bailout;
3630 if (arglist & CAM_ARG_PLIST) {
3631 list_format |= SRDD10_PLIST;
3635 if (arglist & CAM_ARG_GLIST) {
3636 list_format |= SRDD10_GLIST;
3641 * This implies a summary, and was the previous behavior.
3643 if (lists_specified == 0)
3646 ccb = cam_getccb(device);
3651 * We start off asking for just the header to determine how much
3652 * defect data is available. Some Hitachi drives return an error
3653 * if you ask for more data than the drive has. Once we know the
3654 * length, we retry the command with the returned length.
3656 if (use_12byte == 0)
3657 dlist_length = sizeof(*hdr10);
3659 dlist_length = sizeof(*hdr12);
3662 if (defect_list != NULL) {
3666 defect_list = malloc(dlist_length);
3667 if (defect_list == NULL) {
3668 warnx("can't malloc memory for defect list");
3670 goto defect_bailout;
3674 bzero(defect_list, dlist_length);
3677 * cam_getccb() zeros the CCB header only. So we need to zero the
3678 * payload portion of the ccb.
3680 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3682 scsi_read_defects(&ccb->csio,
3683 /*retries*/ retry_count,
3685 /*tag_action*/ task_attr,
3686 /*list_format*/ list_format,
3687 /*addr_desc_index*/ starting_offset,
3688 /*data_ptr*/ defect_list,
3689 /*dxfer_len*/ dlist_length,
3690 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3691 /*sense_len*/ SSD_FULL_SIZE,
3692 /*timeout*/ timeout ? timeout : 5000);
3694 /* Disable freezing the device queue */
3695 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3697 if (cam_send_ccb(device, ccb) < 0) {
3698 perror("error reading defect list");
3700 if (arglist & CAM_ARG_VERBOSE) {
3701 cam_error_print(device, ccb, CAM_ESF_ALL,
3702 CAM_EPF_ALL, stderr);
3706 goto defect_bailout;
3709 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3711 if (use_12byte == 0) {
3712 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3713 hdr_size = sizeof(*hdr10);
3714 hdr_max = SRDDH10_MAX_LENGTH;
3716 if (valid_len >= hdr_size) {
3717 returned_length = scsi_2btoul(hdr10->length);
3718 returned_format = hdr10->format;
3720 returned_length = 0;
3721 returned_format = 0;
3724 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3725 hdr_size = sizeof(*hdr12);
3726 hdr_max = SRDDH12_MAX_LENGTH;
3728 if (valid_len >= hdr_size) {
3729 returned_length = scsi_4btoul(hdr12->length);
3730 returned_format = hdr12->format;
3732 returned_length = 0;
3733 returned_format = 0;
3737 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3738 switch (returned_type) {
3739 case SRDD10_BLOCK_FORMAT:
3740 entry_size = sizeof(struct scsi_defect_desc_block);
3742 case SRDD10_LONG_BLOCK_FORMAT:
3743 entry_size = sizeof(struct scsi_defect_desc_long_block);
3745 case SRDD10_EXT_PHYS_FORMAT:
3746 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3747 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3749 case SRDD10_EXT_BFI_FORMAT:
3750 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3751 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3754 warnx("Unknown defect format 0x%x\n", returned_type);
3756 goto defect_bailout;
3760 max_possible_size = (hdr_max / entry_size) * entry_size;
3761 num_returned = returned_length / entry_size;
3762 num_valid = min(returned_length, valid_len - hdr_size);
3763 num_valid /= entry_size;
3765 if (get_length != 0) {
3768 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3769 CAM_SCSI_STATUS_ERROR) {
3770 struct scsi_sense_data *sense;
3771 int error_code, sense_key, asc, ascq;
3773 sense = &ccb->csio.sense_data;
3774 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3775 ccb->csio.sense_resid, &error_code, &sense_key,
3776 &asc, &ascq, /*show_errors*/ 1);
3779 * If the drive is reporting that it just doesn't
3780 * support the defect list format, go ahead and use
3781 * the length it reported. Otherwise, the length
3782 * may not be valid, so use the maximum.
3784 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3785 && (asc == 0x1c) && (ascq == 0x00)
3786 && (returned_length > 0)) {
3787 if ((use_12byte == 0)
3788 && (returned_length >= max_possible_size)) {
3793 dlist_length = returned_length + hdr_size;
3794 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3795 && (asc == 0x1f) && (ascq == 0x00)
3796 && (returned_length > 0)) {
3797 /* Partial defect list transfer */
3799 * Hitachi drives return this error
3800 * along with a partial defect list if they
3801 * have more defects than the 10 byte
3802 * command can support. Retry with the 12
3805 if (use_12byte == 0) {
3810 dlist_length = returned_length + hdr_size;
3811 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
3812 && (asc == 0x24) && (ascq == 0x00)) {
3813 /* Invalid field in CDB */
3815 * SBC-3 says that if the drive has more
3816 * defects than can be reported with the
3817 * 10 byte command, it should return this
3818 * error and no data. Retry with the 12
3821 if (use_12byte == 0) {
3826 dlist_length = returned_length + hdr_size;
3829 * If we got a SCSI error and no valid length,
3830 * just use the 10 byte maximum. The 12
3831 * byte maximum is too large.
3833 if (returned_length == 0)
3834 dlist_length = SRDD10_MAX_LENGTH;
3836 if ((use_12byte == 0)
3837 && (returned_length >=
3838 max_possible_size)) {
3843 dlist_length = returned_length +
3847 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3850 warnx("Error reading defect header");
3851 if (arglist & CAM_ARG_VERBOSE)
3852 cam_error_print(device, ccb, CAM_ESF_ALL,
3853 CAM_EPF_ALL, stderr);
3854 goto defect_bailout;
3856 if ((use_12byte == 0)
3857 && (returned_length >= max_possible_size)) {
3862 dlist_length = returned_length + hdr_size;
3865 fprintf(stdout, "%u", num_returned);
3867 fprintf(stdout, " defect%s",
3868 (num_returned != 1) ? "s" : "");
3870 fprintf(stdout, "\n");
3872 goto defect_bailout;
3876 * We always limit the list length to the 10-byte maximum
3877 * length (0xffff). The reason is that some controllers
3878 * can't handle larger I/Os, and we can transfer the entire
3879 * 10 byte list in one shot. For drives that support the 12
3880 * byte read defects command, we'll step through the list
3881 * by specifying a starting offset. For drives that don't
3882 * support the 12 byte command's starting offset, we'll
3883 * just display the first 64K.
3885 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3891 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3892 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3893 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3894 struct scsi_sense_data *sense;
3895 int error_code, sense_key, asc, ascq;
3897 sense = &ccb->csio.sense_data;
3898 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3899 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3900 &ascq, /*show_errors*/ 1);
3903 * According to the SCSI spec, if the disk doesn't support
3904 * the requested format, it will generally return a sense
3905 * key of RECOVERED ERROR, and an additional sense code
3906 * of "DEFECT LIST NOT FOUND". HGST drives also return
3907 * Primary/Grown defect list not found errors. So just
3908 * check for an ASC of 0x1c.
3910 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3912 const char *format_str;
3914 format_str = scsi_nv_to_str(defect_list_type_map,
3915 sizeof(defect_list_type_map) /
3916 sizeof(defect_list_type_map[0]),
3917 list_format & SRDD10_DLIST_FORMAT_MASK);
3918 warnx("requested defect format %s not available",
3919 format_str ? format_str : "unknown");
3921 format_str = scsi_nv_to_str(defect_list_type_map,
3922 sizeof(defect_list_type_map) /
3923 sizeof(defect_list_type_map[0]), returned_type);
3924 if (format_str != NULL) {
3925 warnx("Device returned %s format",
3929 warnx("Device returned unknown defect"
3930 " data format %#x", returned_type);
3931 goto defect_bailout;
3935 warnx("Error returned from read defect data command");
3936 if (arglist & CAM_ARG_VERBOSE)
3937 cam_error_print(device, ccb, CAM_ESF_ALL,
3938 CAM_EPF_ALL, stderr);
3939 goto defect_bailout;
3941 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3943 warnx("Error returned from read defect data command");
3944 if (arglist & CAM_ARG_VERBOSE)
3945 cam_error_print(device, ccb, CAM_ESF_ALL,
3946 CAM_EPF_ALL, stderr);
3947 goto defect_bailout;
3950 if (first_pass != 0) {
3951 fprintf(stderr, "Got %d defect", num_returned);
3953 if ((lists_specified == 0) || (num_returned == 0)) {
3954 fprintf(stderr, "s.\n");
3955 goto defect_bailout;
3956 } else if (num_returned == 1)
3957 fprintf(stderr, ":\n");
3959 fprintf(stderr, "s:\n");
3965 * XXX KDM I should probably clean up the printout format for the
3968 switch (returned_type) {
3969 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3970 case SRDD10_EXT_PHYS_FORMAT:
3972 struct scsi_defect_desc_phys_sector *dlist;
3974 dlist = (struct scsi_defect_desc_phys_sector *)
3975 (defect_list + hdr_size);
3977 for (i = 0; i < num_valid; i++) {
3980 sector = scsi_4btoul(dlist[i].sector);
3981 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
3982 mads = (sector & SDD_EXT_PHYS_MADS) ?
3984 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
3986 if (hex_format == 0)
3987 fprintf(stdout, "%d:%d:%d%s",
3988 scsi_3btoul(dlist[i].cylinder),
3990 scsi_4btoul(dlist[i].sector),
3991 mads ? " - " : "\n");
3993 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3994 scsi_3btoul(dlist[i].cylinder),
3996 scsi_4btoul(dlist[i].sector),
3997 mads ? " - " : "\n");
4000 if (num_valid < num_returned) {
4001 starting_offset += num_valid;
4006 case SRDD10_BYTES_FROM_INDEX_FORMAT:
4007 case SRDD10_EXT_BFI_FORMAT:
4009 struct scsi_defect_desc_bytes_from_index *dlist;
4011 dlist = (struct scsi_defect_desc_bytes_from_index *)
4012 (defect_list + hdr_size);
4014 for (i = 0; i < num_valid; i++) {
4017 bfi = scsi_4btoul(dlist[i].bytes_from_index);
4018 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4019 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4020 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4022 if (hex_format == 0)
4023 fprintf(stdout, "%d:%d:%d%s",
4024 scsi_3btoul(dlist[i].cylinder),
4026 scsi_4btoul(dlist[i].bytes_from_index),
4027 mads ? " - " : "\n");
4029 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4030 scsi_3btoul(dlist[i].cylinder),
4032 scsi_4btoul(dlist[i].bytes_from_index),
4033 mads ? " - " : "\n");
4037 if (num_valid < num_returned) {
4038 starting_offset += num_valid;
4043 case SRDDH10_BLOCK_FORMAT:
4045 struct scsi_defect_desc_block *dlist;
4047 dlist = (struct scsi_defect_desc_block *)
4048 (defect_list + hdr_size);
4050 for (i = 0; i < num_valid; i++) {
4051 if (hex_format == 0)
4052 fprintf(stdout, "%u\n",
4053 scsi_4btoul(dlist[i].address));
4055 fprintf(stdout, "0x%x\n",
4056 scsi_4btoul(dlist[i].address));
4059 if (num_valid < num_returned) {
4060 starting_offset += num_valid;
4066 case SRDD10_LONG_BLOCK_FORMAT:
4068 struct scsi_defect_desc_long_block *dlist;
4070 dlist = (struct scsi_defect_desc_long_block *)
4071 (defect_list + hdr_size);
4073 for (i = 0; i < num_valid; i++) {
4074 if (hex_format == 0)
4075 fprintf(stdout, "%ju\n",
4076 (uintmax_t)scsi_8btou64(
4079 fprintf(stdout, "0x%jx\n",
4080 (uintmax_t)scsi_8btou64(
4084 if (num_valid < num_returned) {
4085 starting_offset += num_valid;
4091 fprintf(stderr, "Unknown defect format 0x%x\n",
4098 if (defect_list != NULL)
4106 #endif /* MINIMALISTIC */
4110 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4114 ccb = cam_getccb(device);
4120 #ifndef MINIMALISTIC
4122 mode_sense(struct cam_device *device, int dbd, int pc, int page, int subpage,
4123 int task_attr, int retry_count, int timeout, u_int8_t *data,
4129 ccb = cam_getccb(device);
4132 errx(1, "mode_sense: couldn't allocate CCB");
4134 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4136 scsi_mode_sense_subpage(&ccb->csio,
4137 /* retries */ retry_count,
4139 /* tag_action */ task_attr,
4143 /* subpage */ subpage,
4144 /* param_buf */ data,
4145 /* param_len */ datalen,
4146 /* minimum_cmd_size */ 0,
4147 /* sense_len */ SSD_FULL_SIZE,
4148 /* timeout */ timeout ? timeout : 5000);
4150 if (arglist & CAM_ARG_ERR_RECOVER)
4151 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4153 /* Disable freezing the device queue */
4154 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4156 if (((retval = cam_send_ccb(device, ccb)) < 0)
4157 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4158 if (arglist & CAM_ARG_VERBOSE) {
4159 cam_error_print(device, ccb, CAM_ESF_ALL,
4160 CAM_EPF_ALL, stderr);
4163 cam_close_device(device);
4165 err(1, "error sending mode sense command");
4167 errx(1, "error sending mode sense command");
4174 mode_select(struct cam_device *device, int save_pages, int task_attr,
4175 int retry_count, int timeout, u_int8_t *data, int datalen)
4180 ccb = cam_getccb(device);
4183 errx(1, "mode_select: couldn't allocate CCB");
4185 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4187 scsi_mode_select(&ccb->csio,
4188 /* retries */ retry_count,
4190 /* tag_action */ task_attr,
4191 /* scsi_page_fmt */ 1,
4192 /* save_pages */ save_pages,
4193 /* param_buf */ data,
4194 /* param_len */ datalen,
4195 /* sense_len */ SSD_FULL_SIZE,
4196 /* timeout */ timeout ? timeout : 5000);
4198 if (arglist & CAM_ARG_ERR_RECOVER)
4199 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4201 /* Disable freezing the device queue */
4202 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4204 if (((retval = cam_send_ccb(device, ccb)) < 0)
4205 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4206 if (arglist & CAM_ARG_VERBOSE) {
4207 cam_error_print(device, ccb, CAM_ESF_ALL,
4208 CAM_EPF_ALL, stderr);
4211 cam_close_device(device);
4214 err(1, "error sending mode select command");
4216 errx(1, "error sending mode select command");
4224 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4225 int task_attr, int retry_count, int timeout)
4228 int c, page = -1, subpage = -1, pc = 0;
4229 int binary = 0, dbd = 0, edit = 0, list = 0;
4231 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4246 str_subpage = optarg;
4247 strsep(&str_subpage, ",");
4248 page = strtol(optarg, NULL, 0);
4250 subpage = strtol(str_subpage, NULL, 0);
4254 errx(1, "invalid mode page %d", page);
4256 errx(1, "invalid mode subpage %d", subpage);
4259 pc = strtol(optarg, NULL, 0);
4260 if ((pc < 0) || (pc > 3))
4261 errx(1, "invalid page control field %d", pc);
4268 if (page == -1 && list == 0)
4269 errx(1, "you must specify a mode page!");
4272 mode_list(device, dbd, pc, list > 1, task_attr, retry_count,
4275 mode_edit(device, dbd, pc, page, subpage, edit, binary,
4276 task_attr, retry_count, timeout);
4281 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4282 int task_attr, int retry_count, int timeout)
4285 u_int32_t flags = CAM_DIR_NONE;
4286 u_int8_t *data_ptr = NULL;
4288 u_int8_t atacmd[12];
4289 struct get_hook hook;
4290 int c, data_bytes = 0, valid_bytes;
4296 char *datastr = NULL, *tstr, *resstr = NULL;
4298 int fd_data = 0, fd_res = 0;
4301 ccb = cam_getccb(device);
4304 warnx("scsicmd: error allocating ccb");
4308 CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4310 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4314 while (isspace(*tstr) && (*tstr != '\0'))
4316 hook.argc = argc - optind;
4317 hook.argv = argv + optind;
4319 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4322 * Increment optind by the number of arguments the
4323 * encoding routine processed. After each call to
4324 * getopt(3), optind points to the argument that
4325 * getopt should process _next_. In this case,
4326 * that means it points to the first command string
4327 * argument, if there is one. Once we increment
4328 * this, it should point to either the next command
4329 * line argument, or it should be past the end of
4336 while (isspace(*tstr) && (*tstr != '\0'))
4338 hook.argc = argc - optind;
4339 hook.argv = argv + optind;
4341 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4344 * Increment optind by the number of arguments the
4345 * encoding routine processed. After each call to
4346 * getopt(3), optind points to the argument that
4347 * getopt should process _next_. In this case,
4348 * that means it points to the first command string
4349 * argument, if there is one. Once we increment
4350 * this, it should point to either the next command
4351 * line argument, or it should be past the end of
4363 if (arglist & CAM_ARG_CMD_OUT) {
4364 warnx("command must either be "
4365 "read or write, not both");
4367 goto scsicmd_bailout;
4369 arglist |= CAM_ARG_CMD_IN;
4371 data_bytes = strtol(optarg, NULL, 0);
4372 if (data_bytes <= 0) {
4373 warnx("invalid number of input bytes %d",
4376 goto scsicmd_bailout;
4378 hook.argc = argc - optind;
4379 hook.argv = argv + optind;
4382 datastr = cget(&hook, NULL);
4384 * If the user supplied "-" instead of a format, he
4385 * wants the data to be written to stdout.
4387 if ((datastr != NULL)
4388 && (datastr[0] == '-'))
4391 data_ptr = (u_int8_t *)malloc(data_bytes);
4392 if (data_ptr == NULL) {
4393 warnx("can't malloc memory for data_ptr");
4395 goto scsicmd_bailout;
4399 if (arglist & CAM_ARG_CMD_IN) {
4400 warnx("command must either be "
4401 "read or write, not both");
4403 goto scsicmd_bailout;
4405 arglist |= CAM_ARG_CMD_OUT;
4406 flags = CAM_DIR_OUT;
4407 data_bytes = strtol(optarg, NULL, 0);
4408 if (data_bytes <= 0) {
4409 warnx("invalid number of output bytes %d",
4412 goto scsicmd_bailout;
4414 hook.argc = argc - optind;
4415 hook.argv = argv + optind;
4417 datastr = cget(&hook, NULL);
4418 data_ptr = (u_int8_t *)malloc(data_bytes);
4419 if (data_ptr == NULL) {
4420 warnx("can't malloc memory for data_ptr");
4422 goto scsicmd_bailout;
4424 bzero(data_ptr, data_bytes);
4426 * If the user supplied "-" instead of a format, he
4427 * wants the data to be read from stdin.
4429 if ((datastr != NULL)
4430 && (datastr[0] == '-'))
4433 buff_encode_visit(data_ptr, data_bytes, datastr,
4439 hook.argc = argc - optind;
4440 hook.argv = argv + optind;
4442 resstr = cget(&hook, NULL);
4443 if ((resstr != NULL) && (resstr[0] == '-'))
4453 * If fd_data is set, and we're writing to the device, we need to
4454 * read the data the user wants written from stdin.
4456 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4458 int amt_to_read = data_bytes;
4459 u_int8_t *buf_ptr = data_ptr;
4461 for (amt_read = 0; amt_to_read > 0;
4462 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4463 if (amt_read == -1) {
4464 warn("error reading data from stdin");
4466 goto scsicmd_bailout;
4468 amt_to_read -= amt_read;
4469 buf_ptr += amt_read;
4473 if (arglist & CAM_ARG_ERR_RECOVER)
4474 flags |= CAM_PASS_ERR_RECOVER;
4476 /* Disable freezing the device queue */
4477 flags |= CAM_DEV_QFRZDIS;
4481 * This is taken from the SCSI-3 draft spec.
4482 * (T10/1157D revision 0.3)
4483 * The top 3 bits of an opcode are the group code.
4484 * The next 5 bits are the command code.
4485 * Group 0: six byte commands
4486 * Group 1: ten byte commands
4487 * Group 2: ten byte commands
4489 * Group 4: sixteen byte commands
4490 * Group 5: twelve byte commands
4491 * Group 6: vendor specific
4492 * Group 7: vendor specific
4494 switch((cdb[0] >> 5) & 0x7) {
4505 /* computed by buff_encode_visit */
4516 * We should probably use csio_build_visit or something like that
4517 * here, but it's easier to encode arguments as you go. The
4518 * alternative would be skipping the CDB argument and then encoding
4519 * it here, since we've got the data buffer argument by now.
4521 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4523 cam_fill_csio(&ccb->csio,
4524 /*retries*/ retry_count,
4527 /*tag_action*/ task_attr,
4528 /*data_ptr*/ data_ptr,
4529 /*dxfer_len*/ data_bytes,
4530 /*sense_len*/ SSD_FULL_SIZE,
4531 /*cdb_len*/ cdb_len,
4532 /*timeout*/ timeout ? timeout : 5000);
4535 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4537 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4539 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4541 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4543 cam_fill_ataio(&ccb->ataio,
4544 /*retries*/ retry_count,
4548 /*data_ptr*/ data_ptr,
4549 /*dxfer_len*/ data_bytes,
4550 /*timeout*/ timeout ? timeout : 5000);
4553 if (((retval = cam_send_ccb(device, ccb)) < 0)
4554 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4555 const char warnstr[] = "error sending command";
4562 if (arglist & CAM_ARG_VERBOSE) {
4563 cam_error_print(device, ccb, CAM_ESF_ALL,
4564 CAM_EPF_ALL, stderr);
4568 goto scsicmd_bailout;
4571 if (atacmd_len && need_res) {
4573 buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4575 fprintf(stdout, "\n");
4578 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4579 ccb->ataio.res.status,
4580 ccb->ataio.res.error,
4581 ccb->ataio.res.lba_low,
4582 ccb->ataio.res.lba_mid,
4583 ccb->ataio.res.lba_high,
4584 ccb->ataio.res.device,
4585 ccb->ataio.res.lba_low_exp,
4586 ccb->ataio.res.lba_mid_exp,
4587 ccb->ataio.res.lba_high_exp,
4588 ccb->ataio.res.sector_count,
4589 ccb->ataio.res.sector_count_exp);
4595 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4597 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4598 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4599 && (arglist & CAM_ARG_CMD_IN)
4600 && (valid_bytes > 0)) {
4602 buff_decode_visit(data_ptr, valid_bytes, datastr,
4604 fprintf(stdout, "\n");
4606 ssize_t amt_written;
4607 int amt_to_write = valid_bytes;
4608 u_int8_t *buf_ptr = data_ptr;
4610 for (amt_written = 0; (amt_to_write > 0) &&
4611 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4612 amt_to_write -= amt_written;
4613 buf_ptr += amt_written;
4615 if (amt_written == -1) {
4616 warn("error writing data to stdout");
4618 goto scsicmd_bailout;
4619 } else if ((amt_written == 0)
4620 && (amt_to_write > 0)) {
4621 warnx("only wrote %u bytes out of %u",
4622 valid_bytes - amt_to_write, valid_bytes);
4629 if ((data_bytes > 0) && (data_ptr != NULL))
4638 camdebug(int argc, char **argv, char *combinedopt)
4641 path_id_t bus = CAM_BUS_WILDCARD;
4642 target_id_t target = CAM_TARGET_WILDCARD;
4643 lun_id_t lun = CAM_LUN_WILDCARD;
4644 char *tstr, *tmpstr = NULL;
4648 bzero(&ccb, sizeof(union ccb));
4650 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4653 arglist |= CAM_ARG_DEBUG_INFO;
4654 ccb.cdbg.flags |= CAM_DEBUG_INFO;
4657 arglist |= CAM_ARG_DEBUG_PERIPH;
4658 ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4661 arglist |= CAM_ARG_DEBUG_SUBTRACE;
4662 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4665 arglist |= CAM_ARG_DEBUG_TRACE;
4666 ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4669 arglist |= CAM_ARG_DEBUG_XPT;
4670 ccb.cdbg.flags |= CAM_DEBUG_XPT;
4673 arglist |= CAM_ARG_DEBUG_CDB;
4674 ccb.cdbg.flags |= CAM_DEBUG_CDB;
4677 arglist |= CAM_ARG_DEBUG_PROBE;
4678 ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4685 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
4686 warnx("error opening transport layer device %s", XPT_DEVICE);
4687 warn("%s", XPT_DEVICE);
4694 warnx("you must specify \"off\", \"all\" or a bus,");
4695 warnx("bus:target, or bus:target:lun");
4702 while (isspace(*tstr) && (*tstr != '\0'))
4705 if (strncmp(tstr, "off", 3) == 0) {
4706 ccb.cdbg.flags = CAM_DEBUG_NONE;
4707 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
4708 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
4709 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
4710 } else if (strncmp(tstr, "all", 3) != 0) {
4711 tmpstr = (char *)strtok(tstr, ":");
4712 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4713 bus = strtol(tmpstr, NULL, 0);
4714 arglist |= CAM_ARG_BUS;
4715 tmpstr = (char *)strtok(NULL, ":");
4716 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4717 target = strtol(tmpstr, NULL, 0);
4718 arglist |= CAM_ARG_TARGET;
4719 tmpstr = (char *)strtok(NULL, ":");
4720 if ((tmpstr != NULL) && (*tmpstr != '\0')){
4721 lun = strtol(tmpstr, NULL, 0);
4722 arglist |= CAM_ARG_LUN;
4727 warnx("you must specify \"all\", \"off\", or a bus,");
4728 warnx("bus:target, or bus:target:lun to debug");
4734 ccb.ccb_h.func_code = XPT_DEBUG;
4735 ccb.ccb_h.path_id = bus;
4736 ccb.ccb_h.target_id = target;
4737 ccb.ccb_h.target_lun = lun;
4739 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
4740 warn("CAMIOCOMMAND ioctl failed");
4745 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
4746 CAM_FUNC_NOTAVAIL) {
4747 warnx("CAM debugging not available");
4748 warnx("you need to put options CAMDEBUG in"
4749 " your kernel config file!");
4751 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
4753 warnx("XPT_DEBUG CCB failed with status %#x",
4757 if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
4759 "Debugging turned off\n");
4762 "Debugging enabled for "
4764 bus, target, (uintmax_t)lun);
4775 tagcontrol(struct cam_device *device, int argc, char **argv,
4785 ccb = cam_getccb(device);
4788 warnx("tagcontrol: error allocating ccb");
4792 while ((c = getopt(argc, argv, combinedopt)) != -1) {
4795 numtags = strtol(optarg, NULL, 0);
4797 warnx("tag count %d is < 0", numtags);
4799 goto tagcontrol_bailout;
4810 cam_path_string(device, pathstr, sizeof(pathstr));
4813 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
4814 ccb->ccb_h.func_code = XPT_REL_SIMQ;
4815 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
4816 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
4817 ccb->crs.openings = numtags;
4820 if (cam_send_ccb(device, ccb) < 0) {
4821 perror("error sending XPT_REL_SIMQ CCB");
4823 goto tagcontrol_bailout;
4826 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4827 warnx("XPT_REL_SIMQ CCB failed");
4828 cam_error_print(device, ccb, CAM_ESF_ALL,
4829 CAM_EPF_ALL, stderr);
4831 goto tagcontrol_bailout;
4836 fprintf(stdout, "%stagged openings now %d\n",
4837 pathstr, ccb->crs.openings);
4840 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
4842 ccb->ccb_h.func_code = XPT_GDEV_STATS;
4844 if (cam_send_ccb(device, ccb) < 0) {
4845 perror("error sending XPT_GDEV_STATS CCB");
4847 goto tagcontrol_bailout;
4850 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4851 warnx("XPT_GDEV_STATS CCB failed");
4852 cam_error_print(device, ccb, CAM_ESF_ALL,
4853 CAM_EPF_ALL, stderr);
4855 goto tagcontrol_bailout;
4858 if (arglist & CAM_ARG_VERBOSE) {
4859 fprintf(stdout, "%s", pathstr);
4860 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings);
4861 fprintf(stdout, "%s", pathstr);
4862 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
4863 fprintf(stdout, "%s", pathstr);
4864 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
4865 fprintf(stdout, "%s", pathstr);
4866 fprintf(stdout, "queued %d\n", ccb->cgds.queued);
4867 fprintf(stdout, "%s", pathstr);
4868 fprintf(stdout, "held %d\n", ccb->cgds.held);
4869 fprintf(stdout, "%s", pathstr);
4870 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags);
4871 fprintf(stdout, "%s", pathstr);
4872 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags);
4875 fprintf(stdout, "%s", pathstr);
4876 fprintf(stdout, "device openings: ");
4878 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
4879 ccb->cgds.dev_active);
4889 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
4893 cam_path_string(device, pathstr, sizeof(pathstr));
4895 if (cts->transport == XPORT_SPI) {
4896 struct ccb_trans_settings_spi *spi =
4897 &cts->xport_specific.spi;
4899 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
4901 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
4904 if (spi->sync_offset != 0) {
4907 freq = scsi_calc_syncsrate(spi->sync_period);
4908 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
4909 pathstr, freq / 1000, freq % 1000);
4913 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
4914 fprintf(stdout, "%soffset: %d\n", pathstr,
4918 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
4919 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
4920 (0x01 << spi->bus_width) * 8);
4923 if (spi->valid & CTS_SPI_VALID_DISC) {
4924 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
4925 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
4926 "enabled" : "disabled");
4929 if (cts->transport == XPORT_FC) {
4930 struct ccb_trans_settings_fc *fc =
4931 &cts->xport_specific.fc;
4933 if (fc->valid & CTS_FC_VALID_WWNN)
4934 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
4935 (long long) fc->wwnn);
4936 if (fc->valid & CTS_FC_VALID_WWPN)
4937 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
4938 (long long) fc->wwpn);
4939 if (fc->valid & CTS_FC_VALID_PORT)
4940 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
4941 if (fc->valid & CTS_FC_VALID_SPEED)
4942 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4943 pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
4945 if (cts->transport == XPORT_SAS) {
4946 struct ccb_trans_settings_sas *sas =
4947 &cts->xport_specific.sas;
4949 if (sas->valid & CTS_SAS_VALID_SPEED)
4950 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
4951 pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
4953 if (cts->transport == XPORT_ATA) {
4954 struct ccb_trans_settings_pata *pata =
4955 &cts->xport_specific.ata;
4957 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
4958 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4959 ata_mode2string(pata->mode));
4961 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
4962 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4965 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
4966 fprintf(stdout, "%sPIO transaction length: %d\n",
4967 pathstr, pata->bytecount);
4970 if (cts->transport == XPORT_SATA) {
4971 struct ccb_trans_settings_sata *sata =
4972 &cts->xport_specific.sata;
4974 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
4975 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
4978 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
4979 fprintf(stdout, "%sATA mode: %s\n", pathstr,
4980 ata_mode2string(sata->mode));
4982 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
4983 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
4986 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
4987 fprintf(stdout, "%sPIO transaction length: %d\n",
4988 pathstr, sata->bytecount);
4990 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
4991 fprintf(stdout, "%sPMP presence: %d\n", pathstr,
4994 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
4995 fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
4998 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
4999 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5003 if (cts->protocol == PROTO_ATA) {
5004 struct ccb_trans_settings_ata *ata=
5005 &cts->proto_specific.ata;
5007 if (ata->valid & CTS_ATA_VALID_TQ) {
5008 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5009 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5010 "enabled" : "disabled");
5013 if (cts->protocol == PROTO_SCSI) {
5014 struct ccb_trans_settings_scsi *scsi=
5015 &cts->proto_specific.scsi;
5017 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5018 fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5019 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5020 "enabled" : "disabled");
5027 * Get a path inquiry CCB for the specified device.
5030 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5035 ccb = cam_getccb(device);
5037 warnx("get_cpi: couldn't allocate CCB");
5040 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5041 ccb->ccb_h.func_code = XPT_PATH_INQ;
5042 if (cam_send_ccb(device, ccb) < 0) {
5043 warn("get_cpi: error sending Path Inquiry CCB");
5044 if (arglist & CAM_ARG_VERBOSE)
5045 cam_error_print(device, ccb, CAM_ESF_ALL,
5046 CAM_EPF_ALL, stderr);
5048 goto get_cpi_bailout;
5050 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5051 if (arglist & CAM_ARG_VERBOSE)
5052 cam_error_print(device, ccb, CAM_ESF_ALL,
5053 CAM_EPF_ALL, stderr);
5055 goto get_cpi_bailout;
5057 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5065 * Get a get device CCB for the specified device.
5068 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5073 ccb = cam_getccb(device);
5075 warnx("get_cgd: couldn't allocate CCB");
5078 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5079 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5080 if (cam_send_ccb(device, ccb) < 0) {
5081 warn("get_cgd: error sending Path Inquiry CCB");
5082 if (arglist & CAM_ARG_VERBOSE)
5083 cam_error_print(device, ccb, CAM_ESF_ALL,
5084 CAM_EPF_ALL, stderr);
5086 goto get_cgd_bailout;
5088 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5089 if (arglist & CAM_ARG_VERBOSE)
5090 cam_error_print(device, ccb, CAM_ESF_ALL,
5091 CAM_EPF_ALL, stderr);
5093 goto get_cgd_bailout;
5095 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5103 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5107 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5108 int timeout, int verbosemode)
5110 union ccb *ccb = NULL;
5111 struct scsi_vpd_supported_page_list sup_pages;
5115 ccb = cam_getccb(dev);
5117 warn("Unable to allocate CCB");
5122 /* cam_getccb cleans up the header, caller has to zero the payload */
5123 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5125 bzero(&sup_pages, sizeof(sup_pages));
5127 scsi_inquiry(&ccb->csio,
5128 /*retries*/ retry_count,
5130 /* tag_action */ MSG_SIMPLE_Q_TAG,
5131 /* inq_buf */ (u_int8_t *)&sup_pages,
5132 /* inq_len */ sizeof(sup_pages),
5134 /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5135 /* sense_len */ SSD_FULL_SIZE,
5136 /* timeout */ timeout ? timeout : 5000);
5138 /* Disable freezing the device queue */
5139 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5141 if (retry_count != 0)
5142 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5144 if (cam_send_ccb(dev, ccb) < 0) {
5151 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5152 if (verbosemode != 0)
5153 cam_error_print(dev, ccb, CAM_ESF_ALL,
5154 CAM_EPF_ALL, stderr);
5159 for (i = 0; i < sup_pages.length; i++) {
5160 if (sup_pages.list[i] == page_id) {
5173 * devtype is filled in with the type of device.
5174 * Returns 0 for success, non-zero for failure.
5177 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5178 int verbosemode, camcontrol_devtype *devtype)
5180 struct ccb_getdev cgd;
5183 retval = get_cgd(dev, &cgd);
5187 switch (cgd.protocol) {
5193 *devtype = CC_DT_ATA;
5195 break; /*NOTREACHED*/
5197 *devtype = CC_DT_UNKNOWN;
5199 break; /*NOTREACHED*/
5203 * Check for the ATA Information VPD page (0x89). If this is an
5204 * ATA device behind a SCSI to ATA translation layer, this VPD page
5205 * should be present.
5207 * If that VPD page isn't present, or we get an error back from the
5208 * INQUIRY command, we'll just treat it as a normal SCSI device.
5210 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5211 timeout, verbosemode);
5213 *devtype = CC_DT_ATA_BEHIND_SCSI;
5215 *devtype = CC_DT_SCSI;
5224 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5225 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5226 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5227 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5228 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5229 int is48bit, camcontrol_devtype devtype)
5233 if (devtype == CC_DT_ATA) {
5234 cam_fill_ataio(&ccb->ataio,
5235 /*retries*/ retry_count,
5238 /*tag_action*/ tag_action,
5239 /*data_ptr*/ data_ptr,
5240 /*dxfer_len*/ dxfer_len,
5241 /*timeout*/ timeout);
5242 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5243 ata_48bit_cmd(&ccb->ataio, command, features, lba,
5246 ata_28bit_cmd(&ccb->ataio, command, features, lba,
5249 if (auxiliary != 0) {
5250 ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5251 ccb->ataio.aux = auxiliary;
5254 if (ata_flags & AP_FLAG_CHK_COND)
5255 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5257 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5258 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5259 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5260 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5262 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5263 protocol |= AP_EXTEND;
5265 retval = scsi_ata_pass(&ccb->csio,
5266 /*retries*/ retry_count,
5269 /*tag_action*/ tag_action,
5270 /*protocol*/ protocol,
5271 /*ata_flags*/ ata_flags,
5272 /*features*/ features,
5273 /*sector_count*/ sector_count,
5275 /*command*/ command,
5278 /*auxiliary*/ auxiliary,
5280 /*data_ptr*/ data_ptr,
5281 /*dxfer_len*/ dxfer_len,
5282 /*cdb_storage*/ cdb_storage,
5283 /*cdb_storage_len*/ cdb_storage_len,
5284 /*minimum_cmd_size*/ 0,
5285 /*sense_len*/ sense_len,
5286 /*timeout*/ timeout);
5293 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5294 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5298 switch (ccb->ccb_h.func_code) {
5301 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5304 * In this case, we have SCSI ATA PASS-THROUGH command, 12
5305 * or 16 byte, and need to see what
5307 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5308 opcode = ccb->csio.cdb_io.cdb_ptr[0];
5310 opcode = ccb->csio.cdb_io.cdb_bytes[0];
5311 if ((opcode != ATA_PASS_12)
5312 && (opcode != ATA_PASS_16)) {
5314 warnx("%s: unsupported opcode %02x", __func__, opcode);
5318 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5320 /* Note: the _ccb() variant returns 0 for an error */
5327 switch (error_code) {
5328 case SSD_DESC_CURRENT_ERROR:
5329 case SSD_DESC_DEFERRED_ERROR: {
5330 struct scsi_sense_data_desc *sense;
5331 struct scsi_sense_ata_ret_desc *desc;
5334 sense = (struct scsi_sense_data_desc *)
5335 &ccb->csio.sense_data;
5337 desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len -
5338 ccb->csio.sense_resid, SSD_DESC_ATA);
5339 if (desc_ptr == NULL) {
5340 cam_error_print(dev, ccb, CAM_ESF_ALL,
5341 CAM_EPF_ALL, stderr);
5345 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5347 *error = desc->error;
5348 *count = (desc->count_15_8 << 8) |
5350 *lba = ((uint64_t)desc->lba_47_40 << 40) |
5351 ((uint64_t)desc->lba_39_32 << 32) |
5352 ((uint64_t)desc->lba_31_24 << 24) |
5353 (desc->lba_23_16 << 16) |
5354 (desc->lba_15_8 << 8) |
5356 *device = desc->device;
5357 *status = desc->status;
5360 * If the extend bit isn't set, the result is for a
5361 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5362 * command without the extend bit set. This means
5363 * that the device is supposed to return 28-bit
5364 * status. The count field is only 8 bits, and the
5365 * LBA field is only 8 bits.
5367 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5373 case SSD_CURRENT_ERROR:
5374 case SSD_DEFERRED_ERROR: {
5376 struct scsi_sense_data_fixed *sense;
5379 * XXX KDM need to support fixed sense data.
5381 warnx("%s: Fixed sense data not supported yet",
5385 break; /*NOTREACHED*/
5396 struct ata_res *res;
5399 * In this case, we have an ATA command, and we need to
5400 * fill in the requested values from the result register
5403 res = &ccb->ataio.res;
5404 *error = res->error;
5405 *status = res->status;
5406 *device = res->device;
5407 *count = res->sector_count;
5408 *lba = (res->lba_high << 16) |
5409 (res->lba_mid << 8) |
5411 if (res->flags & CAM_ATAIO_48BIT) {
5412 *count |= (res->sector_count_exp << 8);
5413 *lba |= ((uint64_t)res->lba_low_exp << 24) |
5414 ((uint64_t)res->lba_mid_exp << 32) |
5415 ((uint64_t)res->lba_high_exp << 40);
5417 *lba |= (res->device & 0xf) << 24;
5430 cpi_print(struct ccb_pathinq *cpi)
5432 char adapter_str[1024];
5435 snprintf(adapter_str, sizeof(adapter_str),
5436 "%s%d:", cpi->dev_name, cpi->unit_number);
5438 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5441 for (i = 1; i < UINT8_MAX; i = i << 1) {
5444 if ((i & cpi->hba_inquiry) == 0)
5447 fprintf(stdout, "%s supports ", adapter_str);
5451 str = "MDP message";
5454 str = "32 bit wide SCSI";
5457 str = "16 bit wide SCSI";
5460 str = "SDTR message";
5463 str = "linked CDBs";
5466 str = "tag queue messages";
5469 str = "soft reset alternative";
5472 str = "SATA Port Multiplier";
5475 str = "unknown PI bit set";
5478 fprintf(stdout, "%s\n", str);
5481 for (i = 1; i < UINT32_MAX; i = i << 1) {
5484 if ((i & cpi->hba_misc) == 0)
5487 fprintf(stdout, "%s ", adapter_str);
5491 str = "can understand ata_ext requests";
5494 str = "64bit extended LUNs supported";
5497 str = "bus scans from high ID to low ID";
5500 str = "removable devices not included in scan";
5502 case PIM_NOINITIATOR:
5503 str = "initiator role not supported";
5505 case PIM_NOBUSRESET:
5506 str = "user has disabled initial BUS RESET or"
5507 " controller is in target/mixed mode";
5510 str = "do not send 6-byte commands";
5513 str = "scan bus sequentially";
5516 str = "unmapped I/O supported";
5519 str = "does its own scanning";
5522 str = "unknown PIM bit set";
5525 fprintf(stdout, "%s\n", str);
5528 for (i = 1; i < UINT16_MAX; i = i << 1) {
5531 if ((i & cpi->target_sprt) == 0)
5534 fprintf(stdout, "%s supports ", adapter_str);
5537 str = "target mode processor mode";
5540 str = "target mode phase cog. mode";
5542 case PIT_DISCONNECT:
5543 str = "disconnects in target mode";
5546 str = "terminate I/O message in target mode";
5549 str = "group 6 commands in target mode";
5552 str = "group 7 commands in target mode";
5555 str = "unknown PIT bit set";
5559 fprintf(stdout, "%s\n", str);
5561 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5563 fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5565 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5567 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5568 adapter_str, cpi->hpath_id);
5569 fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5571 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5572 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5573 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5574 adapter_str, cpi->hba_vendor);
5575 fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5576 adapter_str, cpi->hba_device);
5577 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5578 adapter_str, cpi->hba_subvendor);
5579 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5580 adapter_str, cpi->hba_subdevice);
5581 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5582 fprintf(stdout, "%s base transfer speed: ", adapter_str);
5583 if (cpi->base_transfer_speed > 1000)
5584 fprintf(stdout, "%d.%03dMB/sec\n",
5585 cpi->base_transfer_speed / 1000,
5586 cpi->base_transfer_speed % 1000);
5588 fprintf(stdout, "%dKB/sec\n",
5589 (cpi->base_transfer_speed % 1000) * 1000);
5590 fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5591 adapter_str, cpi->maxio);
5595 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5596 struct ccb_trans_settings *cts)
5602 ccb = cam_getccb(device);
5605 warnx("get_print_cts: error allocating ccb");
5609 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5611 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5613 if (user_settings == 0)
5614 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5616 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5618 if (cam_send_ccb(device, ccb) < 0) {
5619 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
5620 if (arglist & CAM_ARG_VERBOSE)
5621 cam_error_print(device, ccb, CAM_ESF_ALL,
5622 CAM_EPF_ALL, stderr);
5624 goto get_print_cts_bailout;
5627 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5628 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5629 if (arglist & CAM_ARG_VERBOSE)
5630 cam_error_print(device, ccb, CAM_ESF_ALL,
5631 CAM_EPF_ALL, stderr);
5633 goto get_print_cts_bailout;
5637 cts_print(device, &ccb->cts);
5640 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5642 get_print_cts_bailout:
5650 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
5651 int timeout, int argc, char **argv, char *combinedopt)
5655 int user_settings = 0;
5657 int disc_enable = -1, tag_enable = -1;
5660 double syncrate = -1;
5663 int change_settings = 0, send_tur = 0;
5664 struct ccb_pathinq cpi;
5666 ccb = cam_getccb(device);
5668 warnx("ratecontrol: error allocating ccb");
5671 while ((c = getopt(argc, argv, combinedopt)) != -1) {
5680 if (strncasecmp(optarg, "enable", 6) == 0)
5682 else if (strncasecmp(optarg, "disable", 7) == 0)
5685 warnx("-D argument \"%s\" is unknown", optarg);
5687 goto ratecontrol_bailout;
5689 change_settings = 1;
5692 mode = ata_string2mode(optarg);
5694 warnx("unknown mode '%s'", optarg);
5696 goto ratecontrol_bailout;
5698 change_settings = 1;
5701 offset = strtol(optarg, NULL, 0);
5703 warnx("offset value %d is < 0", offset);
5705 goto ratecontrol_bailout;
5707 change_settings = 1;
5713 syncrate = atof(optarg);
5715 warnx("sync rate %f is < 0", syncrate);
5717 goto ratecontrol_bailout;
5719 change_settings = 1;
5722 if (strncasecmp(optarg, "enable", 6) == 0)
5724 else if (strncasecmp(optarg, "disable", 7) == 0)
5727 warnx("-T argument \"%s\" is unknown", optarg);
5729 goto ratecontrol_bailout;
5731 change_settings = 1;
5737 bus_width = strtol(optarg, NULL, 0);
5738 if (bus_width < 0) {
5739 warnx("bus width %d is < 0", bus_width);
5741 goto ratecontrol_bailout;
5743 change_settings = 1;
5749 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5751 * Grab path inquiry information, so we can determine whether
5752 * or not the initiator is capable of the things that the user
5755 ccb->ccb_h.func_code = XPT_PATH_INQ;
5756 if (cam_send_ccb(device, ccb) < 0) {
5757 perror("error sending XPT_PATH_INQ CCB");
5758 if (arglist & CAM_ARG_VERBOSE) {
5759 cam_error_print(device, ccb, CAM_ESF_ALL,
5760 CAM_EPF_ALL, stderr);
5763 goto ratecontrol_bailout;
5765 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5766 warnx("XPT_PATH_INQ CCB failed");
5767 if (arglist & CAM_ARG_VERBOSE) {
5768 cam_error_print(device, ccb, CAM_ESF_ALL,
5769 CAM_EPF_ALL, stderr);
5772 goto ratecontrol_bailout;
5774 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
5775 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5777 fprintf(stdout, "%s parameters:\n",
5778 user_settings ? "User" : "Current");
5780 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
5782 goto ratecontrol_bailout;
5784 if (arglist & CAM_ARG_VERBOSE)
5787 if (change_settings) {
5788 int didsettings = 0;
5789 struct ccb_trans_settings_spi *spi = NULL;
5790 struct ccb_trans_settings_pata *pata = NULL;
5791 struct ccb_trans_settings_sata *sata = NULL;
5792 struct ccb_trans_settings_ata *ata = NULL;
5793 struct ccb_trans_settings_scsi *scsi = NULL;
5795 if (ccb->cts.transport == XPORT_SPI)
5796 spi = &ccb->cts.xport_specific.spi;
5797 if (ccb->cts.transport == XPORT_ATA)
5798 pata = &ccb->cts.xport_specific.ata;
5799 if (ccb->cts.transport == XPORT_SATA)
5800 sata = &ccb->cts.xport_specific.sata;
5801 if (ccb->cts.protocol == PROTO_ATA)
5802 ata = &ccb->cts.proto_specific.ata;
5803 if (ccb->cts.protocol == PROTO_SCSI)
5804 scsi = &ccb->cts.proto_specific.scsi;
5805 ccb->cts.xport_specific.valid = 0;
5806 ccb->cts.proto_specific.valid = 0;
5807 if (spi && disc_enable != -1) {
5808 spi->valid |= CTS_SPI_VALID_DISC;
5809 if (disc_enable == 0)
5810 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
5812 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
5815 if (tag_enable != -1) {
5816 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
5817 warnx("HBA does not support tagged queueing, "
5818 "so you cannot modify tag settings");
5820 goto ratecontrol_bailout;
5823 ata->valid |= CTS_SCSI_VALID_TQ;
5824 if (tag_enable == 0)
5825 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
5827 ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
5830 scsi->valid |= CTS_SCSI_VALID_TQ;
5831 if (tag_enable == 0)
5832 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
5834 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
5838 if (spi && offset != -1) {
5839 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5840 warnx("HBA is not capable of changing offset");
5842 goto ratecontrol_bailout;
5844 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
5845 spi->sync_offset = offset;
5848 if (spi && syncrate != -1) {
5849 int prelim_sync_period;
5851 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5852 warnx("HBA is not capable of changing "
5855 goto ratecontrol_bailout;
5857 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
5859 * The sync rate the user gives us is in MHz.
5860 * We need to translate it into KHz for this
5865 * Next, we calculate a "preliminary" sync period
5866 * in tenths of a nanosecond.
5869 prelim_sync_period = 0;
5871 prelim_sync_period = 10000000 / syncrate;
5873 scsi_calc_syncparam(prelim_sync_period);
5876 if (sata && syncrate != -1) {
5877 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5878 warnx("HBA is not capable of changing "
5881 goto ratecontrol_bailout;
5883 if (!user_settings) {
5884 warnx("You can modify only user rate "
5885 "settings for SATA");
5887 goto ratecontrol_bailout;
5889 sata->revision = ata_speed2revision(syncrate * 100);
5890 if (sata->revision < 0) {
5891 warnx("Invalid rate %f", syncrate);
5893 goto ratecontrol_bailout;
5895 sata->valid |= CTS_SATA_VALID_REVISION;
5898 if ((pata || sata) && mode != -1) {
5899 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
5900 warnx("HBA is not capable of changing "
5903 goto ratecontrol_bailout;
5905 if (!user_settings) {
5906 warnx("You can modify only user mode "
5907 "settings for ATA/SATA");
5909 goto ratecontrol_bailout;
5913 pata->valid |= CTS_ATA_VALID_MODE;
5916 sata->valid |= CTS_SATA_VALID_MODE;
5921 * The bus_width argument goes like this:
5925 * Therefore, if you shift the number of bits given on the
5926 * command line right by 4, you should get the correct
5929 if (spi && bus_width != -1) {
5931 * We might as well validate things here with a
5932 * decipherable error message, rather than what
5933 * will probably be an indecipherable error message
5934 * by the time it gets back to us.
5936 if ((bus_width == 16)
5937 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
5938 warnx("HBA does not support 16 bit bus width");
5940 goto ratecontrol_bailout;
5941 } else if ((bus_width == 32)
5942 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
5943 warnx("HBA does not support 32 bit bus width");
5945 goto ratecontrol_bailout;
5946 } else if ((bus_width != 8)
5947 && (bus_width != 16)
5948 && (bus_width != 32)) {
5949 warnx("Invalid bus width %d", bus_width);
5951 goto ratecontrol_bailout;
5953 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
5954 spi->bus_width = bus_width >> 4;
5957 if (didsettings == 0) {
5958 goto ratecontrol_bailout;
5960 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
5961 if (cam_send_ccb(device, ccb) < 0) {
5962 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
5963 if (arglist & CAM_ARG_VERBOSE) {
5964 cam_error_print(device, ccb, CAM_ESF_ALL,
5965 CAM_EPF_ALL, stderr);
5968 goto ratecontrol_bailout;
5970 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5971 warnx("XPT_SET_TRANS_SETTINGS CCB failed");
5972 if (arglist & CAM_ARG_VERBOSE) {
5973 cam_error_print(device, ccb, CAM_ESF_ALL,
5974 CAM_EPF_ALL, stderr);
5977 goto ratecontrol_bailout;
5981 retval = testunitready(device, task_attr, retry_count, timeout,
5982 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
5984 * If the TUR didn't succeed, just bail.
5988 fprintf(stderr, "Test Unit Ready failed\n");
5989 goto ratecontrol_bailout;
5992 if ((change_settings || send_tur) && !quiet &&
5993 (ccb->cts.transport == XPORT_ATA ||
5994 ccb->cts.transport == XPORT_SATA || send_tur)) {
5995 fprintf(stdout, "New parameters:\n");
5996 retval = get_print_cts(device, user_settings, 0, NULL);
5999 ratecontrol_bailout:
6005 scsiformat(struct cam_device *device, int argc, char **argv,
6006 char *combinedopt, int task_attr, int retry_count, int timeout)
6010 int ycount = 0, quiet = 0;
6011 int error = 0, retval = 0;
6012 int use_timeout = 10800 * 1000;
6014 struct format_defect_list_header fh;
6015 u_int8_t *data_ptr = NULL;
6016 u_int32_t dxfer_len = 0;
6018 int num_warnings = 0;
6021 ccb = cam_getccb(device);
6024 warnx("scsiformat: error allocating ccb");
6028 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6030 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6051 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6052 "following device:\n");
6054 error = scsidoinquiry(device, argc, argv, combinedopt,
6055 task_attr, retry_count, timeout);
6058 warnx("scsiformat: error sending inquiry");
6059 goto scsiformat_bailout;
6064 if (!get_confirmation()) {
6066 goto scsiformat_bailout;
6071 use_timeout = timeout;
6074 fprintf(stdout, "Current format timeout is %d seconds\n",
6075 use_timeout / 1000);
6079 * If the user hasn't disabled questions and didn't specify a
6080 * timeout on the command line, ask them if they want the current
6084 && (timeout == 0)) {
6086 int new_timeout = 0;
6088 fprintf(stdout, "Enter new timeout in seconds or press\n"
6089 "return to keep the current timeout [%d] ",
6090 use_timeout / 1000);
6092 if (fgets(str, sizeof(str), stdin) != NULL) {
6094 new_timeout = atoi(str);
6097 if (new_timeout != 0) {
6098 use_timeout = new_timeout * 1000;
6099 fprintf(stdout, "Using new timeout value %d\n",
6100 use_timeout / 1000);
6105 * Keep this outside the if block below to silence any unused
6106 * variable warnings.
6108 bzero(&fh, sizeof(fh));
6111 * If we're in immediate mode, we've got to include the format
6114 if (immediate != 0) {
6115 fh.byte2 = FU_DLH_IMMED;
6116 data_ptr = (u_int8_t *)&fh;
6117 dxfer_len = sizeof(fh);
6118 byte2 = FU_FMT_DATA;
6119 } else if (quiet == 0) {
6120 fprintf(stdout, "Formatting...");
6124 scsi_format_unit(&ccb->csio,
6125 /* retries */ retry_count,
6127 /* tag_action */ task_attr,
6130 /* data_ptr */ data_ptr,
6131 /* dxfer_len */ dxfer_len,
6132 /* sense_len */ SSD_FULL_SIZE,
6133 /* timeout */ use_timeout);
6135 /* Disable freezing the device queue */
6136 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6138 if (arglist & CAM_ARG_ERR_RECOVER)
6139 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6141 if (((retval = cam_send_ccb(device, ccb)) < 0)
6142 || ((immediate == 0)
6143 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6144 const char errstr[] = "error sending format command";
6151 if (arglist & CAM_ARG_VERBOSE) {
6152 cam_error_print(device, ccb, CAM_ESF_ALL,
6153 CAM_EPF_ALL, stderr);
6156 goto scsiformat_bailout;
6160 * If we ran in non-immediate mode, we already checked for errors
6161 * above and printed out any necessary information. If we're in
6162 * immediate mode, we need to loop through and get status
6163 * information periodically.
6165 if (immediate == 0) {
6167 fprintf(stdout, "Format Complete\n");
6169 goto scsiformat_bailout;
6176 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6179 * There's really no need to do error recovery or
6180 * retries here, since we're just going to sit in a
6181 * loop and wait for the device to finish formatting.
6183 scsi_test_unit_ready(&ccb->csio,
6186 /* tag_action */ task_attr,
6187 /* sense_len */ SSD_FULL_SIZE,
6188 /* timeout */ 5000);
6190 /* Disable freezing the device queue */
6191 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6193 retval = cam_send_ccb(device, ccb);
6196 * If we get an error from the ioctl, bail out. SCSI
6197 * errors are expected.
6200 warn("error sending CAMIOCOMMAND ioctl");
6201 if (arglist & CAM_ARG_VERBOSE) {
6202 cam_error_print(device, ccb, CAM_ESF_ALL,
6203 CAM_EPF_ALL, stderr);
6206 goto scsiformat_bailout;
6209 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6211 if ((status != CAM_REQ_CMP)
6212 && (status == CAM_SCSI_STATUS_ERROR)
6213 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6214 struct scsi_sense_data *sense;
6215 int error_code, sense_key, asc, ascq;
6217 sense = &ccb->csio.sense_data;
6218 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6219 ccb->csio.sense_resid, &error_code, &sense_key,
6220 &asc, &ascq, /*show_errors*/ 1);
6223 * According to the SCSI-2 and SCSI-3 specs, a
6224 * drive that is in the middle of a format should
6225 * return NOT READY with an ASC of "logical unit
6226 * not ready, format in progress". The sense key
6227 * specific bytes will then be a progress indicator.
6229 if ((sense_key == SSD_KEY_NOT_READY)
6230 && (asc == 0x04) && (ascq == 0x04)) {
6233 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6234 ccb->csio.sense_resid, sks) == 0)
6237 u_int64_t percentage;
6239 val = scsi_2btoul(&sks[1]);
6240 percentage = 10000ull * val;
6243 "\rFormatting: %ju.%02u %% "
6245 (uintmax_t)(percentage /
6247 (unsigned)((percentage /
6251 } else if ((quiet == 0)
6252 && (++num_warnings <= 1)) {
6253 warnx("Unexpected SCSI Sense Key "
6254 "Specific value returned "
6256 scsi_sense_print(device, &ccb->csio,
6258 warnx("Unable to print status "
6259 "information, but format will "
6261 warnx("will exit when format is "
6266 warnx("Unexpected SCSI error during format");
6267 cam_error_print(device, ccb, CAM_ESF_ALL,
6268 CAM_EPF_ALL, stderr);
6270 goto scsiformat_bailout;
6273 } else if (status != CAM_REQ_CMP) {
6274 warnx("Unexpected CAM status %#x", status);
6275 if (arglist & CAM_ARG_VERBOSE)
6276 cam_error_print(device, ccb, CAM_ESF_ALL,
6277 CAM_EPF_ALL, stderr);
6279 goto scsiformat_bailout;
6282 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6285 fprintf(stdout, "\nFormat Complete\n");
6295 scsisanitize(struct cam_device *device, int argc, char **argv,
6296 char *combinedopt, int task_attr, int retry_count, int timeout)
6299 u_int8_t action = 0;
6301 int ycount = 0, quiet = 0;
6302 int error = 0, retval = 0;
6303 int use_timeout = 10800 * 1000;
6309 const char *pattern = NULL;
6310 u_int8_t *data_ptr = NULL;
6311 u_int32_t dxfer_len = 0;
6313 int num_warnings = 0;
6316 ccb = cam_getccb(device);
6319 warnx("scsisanitize: error allocating ccb");
6323 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6325 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6328 if (strcasecmp(optarg, "overwrite") == 0)
6329 action = SSZ_SERVICE_ACTION_OVERWRITE;
6330 else if (strcasecmp(optarg, "block") == 0)
6331 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6332 else if (strcasecmp(optarg, "crypto") == 0)
6333 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6334 else if (strcasecmp(optarg, "exitfailure") == 0)
6335 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6337 warnx("invalid service operation \"%s\"",
6340 goto scsisanitize_bailout;
6344 passes = strtol(optarg, NULL, 0);
6345 if (passes < 1 || passes > 31) {
6346 warnx("invalid passes value %d", passes);
6348 goto scsisanitize_bailout;
6379 warnx("an action is required");
6381 goto scsisanitize_bailout;
6382 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6383 struct scsi_sanitize_parameter_list *pl;
6387 if (pattern == NULL) {
6388 warnx("overwrite action requires -P argument");
6390 goto scsisanitize_bailout;
6392 fd = open(pattern, O_RDONLY);
6394 warn("cannot open pattern file %s", pattern);
6396 goto scsisanitize_bailout;
6398 if (fstat(fd, &sb) < 0) {
6399 warn("cannot stat pattern file %s", pattern);
6401 goto scsisanitize_bailout;
6404 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6405 warnx("pattern file size exceeds maximum value %d",
6406 SSZPL_MAX_PATTERN_LENGTH);
6408 goto scsisanitize_bailout;
6410 dxfer_len = sizeof(*pl) + sz;
6411 data_ptr = calloc(1, dxfer_len);
6412 if (data_ptr == NULL) {
6413 warnx("cannot allocate parameter list buffer");
6415 goto scsisanitize_bailout;
6418 amt = read(fd, data_ptr + sizeof(*pl), sz);
6420 warn("cannot read pattern file");
6422 goto scsisanitize_bailout;
6423 } else if (amt != sz) {
6424 warnx("short pattern file read");
6426 goto scsisanitize_bailout;
6429 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6435 pl->byte1 |= SSZPL_INVERT;
6436 scsi_ulto2b(sz, pl->length);
6442 else if (invert != 0)
6444 else if (pattern != NULL)
6449 warnx("%s argument only valid with overwrite "
6452 goto scsisanitize_bailout;
6457 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6458 "following device:\n");
6460 error = scsidoinquiry(device, argc, argv, combinedopt,
6461 task_attr, retry_count, timeout);
6464 warnx("scsisanitize: error sending inquiry");
6465 goto scsisanitize_bailout;
6470 if (!get_confirmation()) {
6472 goto scsisanitize_bailout;
6477 use_timeout = timeout;
6480 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
6481 use_timeout / 1000);
6485 * If the user hasn't disabled questions and didn't specify a
6486 * timeout on the command line, ask them if they want the current
6490 && (timeout == 0)) {
6492 int new_timeout = 0;
6494 fprintf(stdout, "Enter new timeout in seconds or press\n"
6495 "return to keep the current timeout [%d] ",
6496 use_timeout / 1000);
6498 if (fgets(str, sizeof(str), stdin) != NULL) {
6500 new_timeout = atoi(str);
6503 if (new_timeout != 0) {
6504 use_timeout = new_timeout * 1000;
6505 fprintf(stdout, "Using new timeout value %d\n",
6506 use_timeout / 1000);
6512 byte2 |= SSZ_UNRESTRICTED_EXIT;
6516 scsi_sanitize(&ccb->csio,
6517 /* retries */ retry_count,
6519 /* tag_action */ task_attr,
6522 /* data_ptr */ data_ptr,
6523 /* dxfer_len */ dxfer_len,
6524 /* sense_len */ SSD_FULL_SIZE,
6525 /* timeout */ use_timeout);
6527 /* Disable freezing the device queue */
6528 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6530 if (arglist & CAM_ARG_ERR_RECOVER)
6531 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6533 if (cam_send_ccb(device, ccb) < 0) {
6534 warn("error sending sanitize command");
6536 goto scsisanitize_bailout;
6539 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6540 struct scsi_sense_data *sense;
6541 int error_code, sense_key, asc, ascq;
6543 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
6544 CAM_SCSI_STATUS_ERROR) {
6545 sense = &ccb->csio.sense_data;
6546 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6547 ccb->csio.sense_resid, &error_code, &sense_key,
6548 &asc, &ascq, /*show_errors*/ 1);
6550 if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
6551 asc == 0x20 && ascq == 0x00)
6552 warnx("sanitize is not supported by "
6555 warnx("error sanitizing this device");
6557 warnx("error sanitizing this device");
6559 if (arglist & CAM_ARG_VERBOSE) {
6560 cam_error_print(device, ccb, CAM_ESF_ALL,
6561 CAM_EPF_ALL, stderr);
6564 goto scsisanitize_bailout;
6568 * If we ran in non-immediate mode, we already checked for errors
6569 * above and printed out any necessary information. If we're in
6570 * immediate mode, we need to loop through and get status
6571 * information periodically.
6573 if (immediate == 0) {
6575 fprintf(stdout, "Sanitize Complete\n");
6577 goto scsisanitize_bailout;
6584 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6587 * There's really no need to do error recovery or
6588 * retries here, since we're just going to sit in a
6589 * loop and wait for the device to finish sanitizing.
6591 scsi_test_unit_ready(&ccb->csio,
6594 /* tag_action */ task_attr,
6595 /* sense_len */ SSD_FULL_SIZE,
6596 /* timeout */ 5000);
6598 /* Disable freezing the device queue */
6599 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6601 retval = cam_send_ccb(device, ccb);
6604 * If we get an error from the ioctl, bail out. SCSI
6605 * errors are expected.
6608 warn("error sending CAMIOCOMMAND ioctl");
6609 if (arglist & CAM_ARG_VERBOSE) {
6610 cam_error_print(device, ccb, CAM_ESF_ALL,
6611 CAM_EPF_ALL, stderr);
6614 goto scsisanitize_bailout;
6617 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6619 if ((status != CAM_REQ_CMP)
6620 && (status == CAM_SCSI_STATUS_ERROR)
6621 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6622 struct scsi_sense_data *sense;
6623 int error_code, sense_key, asc, ascq;
6625 sense = &ccb->csio.sense_data;
6626 scsi_extract_sense_len(sense, ccb->csio.sense_len -
6627 ccb->csio.sense_resid, &error_code, &sense_key,
6628 &asc, &ascq, /*show_errors*/ 1);
6631 * According to the SCSI-3 spec, a drive that is in the
6632 * middle of a sanitize should return NOT READY with an
6633 * ASC of "logical unit not ready, sanitize in
6634 * progress". The sense key specific bytes will then
6635 * be a progress indicator.
6637 if ((sense_key == SSD_KEY_NOT_READY)
6638 && (asc == 0x04) && (ascq == 0x1b)) {
6641 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6642 ccb->csio.sense_resid, sks) == 0)
6645 u_int64_t percentage;
6647 val = scsi_2btoul(&sks[1]);
6648 percentage = 10000 * val;
6651 "\rSanitizing: %ju.%02u %% "
6653 (uintmax_t)(percentage /
6655 (unsigned)((percentage /
6659 } else if ((quiet == 0)
6660 && (++num_warnings <= 1)) {
6661 warnx("Unexpected SCSI Sense Key "
6662 "Specific value returned "
6663 "during sanitize:");
6664 scsi_sense_print(device, &ccb->csio,
6666 warnx("Unable to print status "
6667 "information, but sanitze will "
6669 warnx("will exit when sanitize is "
6674 warnx("Unexpected SCSI error during sanitize");
6675 cam_error_print(device, ccb, CAM_ESF_ALL,
6676 CAM_EPF_ALL, stderr);
6678 goto scsisanitize_bailout;
6681 } else if (status != CAM_REQ_CMP) {
6682 warnx("Unexpected CAM status %#x", status);
6683 if (arglist & CAM_ARG_VERBOSE)
6684 cam_error_print(device, ccb, CAM_ESF_ALL,
6685 CAM_EPF_ALL, stderr);
6687 goto scsisanitize_bailout;
6689 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6692 fprintf(stdout, "\nSanitize Complete\n");
6694 scsisanitize_bailout:
6697 if (data_ptr != NULL)
6705 scsireportluns(struct cam_device *device, int argc, char **argv,
6706 char *combinedopt, int task_attr, int retry_count, int timeout)
6709 int c, countonly, lunsonly;
6710 struct scsi_report_luns_data *lundata;
6712 uint8_t report_type;
6713 uint32_t list_len, i, j;
6718 report_type = RPL_REPORT_DEFAULT;
6719 ccb = cam_getccb(device);
6722 warnx("%s: error allocating ccb", __func__);
6726 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6731 while ((c = getopt(argc, argv, combinedopt)) != -1) {
6740 if (strcasecmp(optarg, "default") == 0)
6741 report_type = RPL_REPORT_DEFAULT;
6742 else if (strcasecmp(optarg, "wellknown") == 0)
6743 report_type = RPL_REPORT_WELLKNOWN;
6744 else if (strcasecmp(optarg, "all") == 0)
6745 report_type = RPL_REPORT_ALL;
6747 warnx("%s: invalid report type \"%s\"",
6758 if ((countonly != 0)
6759 && (lunsonly != 0)) {
6760 warnx("%s: you can only specify one of -c or -l", __func__);
6765 * According to SPC-4, the allocation length must be at least 16
6766 * bytes -- enough for the header and one LUN.
6768 alloc_len = sizeof(*lundata) + 8;
6772 lundata = malloc(alloc_len);
6774 if (lundata == NULL) {
6775 warn("%s: error mallocing %d bytes", __func__, alloc_len);
6780 scsi_report_luns(&ccb->csio,
6781 /*retries*/ retry_count,
6783 /*tag_action*/ task_attr,
6784 /*select_report*/ report_type,
6785 /*rpl_buf*/ lundata,
6786 /*alloc_len*/ alloc_len,
6787 /*sense_len*/ SSD_FULL_SIZE,
6788 /*timeout*/ timeout ? timeout : 5000);
6790 /* Disable freezing the device queue */
6791 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6793 if (arglist & CAM_ARG_ERR_RECOVER)
6794 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6796 if (cam_send_ccb(device, ccb) < 0) {
6797 warn("error sending REPORT LUNS command");
6799 if (arglist & CAM_ARG_VERBOSE)
6800 cam_error_print(device, ccb, CAM_ESF_ALL,
6801 CAM_EPF_ALL, stderr);
6807 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6808 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
6814 list_len = scsi_4btoul(lundata->length);
6817 * If we need to list the LUNs, and our allocation
6818 * length was too short, reallocate and retry.
6820 if ((countonly == 0)
6821 && (list_len > (alloc_len - sizeof(*lundata)))) {
6822 alloc_len = list_len + sizeof(*lundata);
6828 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
6829 ((list_len / 8) > 1) ? "s" : "");
6834 for (i = 0; i < (list_len / 8); i++) {
6838 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
6840 fprintf(stdout, ",");
6841 switch (lundata->luns[i].lundata[j] &
6842 RPL_LUNDATA_ATYP_MASK) {
6843 case RPL_LUNDATA_ATYP_PERIPH:
6844 if ((lundata->luns[i].lundata[j] &
6845 RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
6846 fprintf(stdout, "%d:",
6847 lundata->luns[i].lundata[j] &
6848 RPL_LUNDATA_PERIPH_BUS_MASK);
6850 && ((lundata->luns[i].lundata[j+2] &
6851 RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
6854 fprintf(stdout, "%d",
6855 lundata->luns[i].lundata[j+1]);
6857 case RPL_LUNDATA_ATYP_FLAT: {
6859 tmplun[0] = lundata->luns[i].lundata[j] &
6860 RPL_LUNDATA_FLAT_LUN_MASK;
6861 tmplun[1] = lundata->luns[i].lundata[j+1];
6863 fprintf(stdout, "%d", scsi_2btoul(tmplun));
6867 case RPL_LUNDATA_ATYP_LUN:
6868 fprintf(stdout, "%d:%d:%d",
6869 (lundata->luns[i].lundata[j+1] &
6870 RPL_LUNDATA_LUN_BUS_MASK) >> 5,
6871 lundata->luns[i].lundata[j] &
6872 RPL_LUNDATA_LUN_TARG_MASK,
6873 lundata->luns[i].lundata[j+1] &
6874 RPL_LUNDATA_LUN_LUN_MASK);
6876 case RPL_LUNDATA_ATYP_EXTLUN: {
6877 int field_len_code, eam_code;
6879 eam_code = lundata->luns[i].lundata[j] &
6880 RPL_LUNDATA_EXT_EAM_MASK;
6881 field_len_code = (lundata->luns[i].lundata[j] &
6882 RPL_LUNDATA_EXT_LEN_MASK) >> 4;
6884 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
6885 && (field_len_code == 0x00)) {
6886 fprintf(stdout, "%d",
6887 lundata->luns[i].lundata[j+1]);
6888 } else if ((eam_code ==
6889 RPL_LUNDATA_EXT_EAM_NOT_SPEC)
6890 && (field_len_code == 0x03)) {
6894 * This format takes up all 8 bytes.
6895 * If we aren't starting at offset 0,
6899 fprintf(stdout, "Invalid "
6902 "specified format", j);
6906 bzero(tmp_lun, sizeof(tmp_lun));
6907 bcopy(&lundata->luns[i].lundata[j+1],
6908 &tmp_lun[1], sizeof(tmp_lun) - 1);
6909 fprintf(stdout, "%#jx",
6910 (intmax_t)scsi_8btou64(tmp_lun));
6913 fprintf(stderr, "Unknown Extended LUN"
6914 "Address method %#x, length "
6915 "code %#x", eam_code,
6922 fprintf(stderr, "Unknown LUN address method "
6923 "%#x\n", lundata->luns[i].lundata[0] &
6924 RPL_LUNDATA_ATYP_MASK);
6928 * For the flat addressing method, there are no
6929 * other levels after it.
6934 fprintf(stdout, "\n");
6947 scsireadcapacity(struct cam_device *device, int argc, char **argv,
6948 char *combinedopt, int task_attr, int retry_count, int timeout)
6951 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten;
6952 struct scsi_read_capacity_data rcap;
6953 struct scsi_read_capacity_data_long rcaplong;
6967 ccb = cam_getccb(device);
6970 warnx("%s: error allocating ccb", __func__);
6974 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6976 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7003 if ((blocksizeonly != 0)
7004 && (numblocks != 0)) {
7005 warnx("%s: you can only specify one of -b or -N", __func__);
7010 if ((blocksizeonly != 0)
7011 && (sizeonly != 0)) {
7012 warnx("%s: you can only specify one of -b or -s", __func__);
7019 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7025 && (blocksizeonly != 0)) {
7026 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7031 scsi_read_capacity(&ccb->csio,
7032 /*retries*/ retry_count,
7034 /*tag_action*/ task_attr,
7037 /*timeout*/ timeout ? timeout : 5000);
7039 /* Disable freezing the device queue */
7040 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7042 if (arglist & CAM_ARG_ERR_RECOVER)
7043 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7045 if (cam_send_ccb(device, ccb) < 0) {
7046 warn("error sending READ CAPACITY command");
7048 if (arglist & CAM_ARG_VERBOSE)
7049 cam_error_print(device, ccb, CAM_ESF_ALL,
7050 CAM_EPF_ALL, stderr);
7056 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7057 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7062 maxsector = scsi_4btoul(rcap.addr);
7063 block_len = scsi_4btoul(rcap.length);
7066 * A last block of 2^32-1 means that the true capacity is over 2TB,
7067 * and we need to issue the long READ CAPACITY to get the real
7068 * capacity. Otherwise, we're all set.
7070 if (maxsector != 0xffffffff)
7073 scsi_read_capacity_16(&ccb->csio,
7074 /*retries*/ retry_count,
7076 /*tag_action*/ task_attr,
7080 /*rcap_buf*/ (uint8_t *)&rcaplong,
7081 /*rcap_buf_len*/ sizeof(rcaplong),
7082 /*sense_len*/ SSD_FULL_SIZE,
7083 /*timeout*/ timeout ? timeout : 5000);
7085 /* Disable freezing the device queue */
7086 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7088 if (arglist & CAM_ARG_ERR_RECOVER)
7089 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7091 if (cam_send_ccb(device, ccb) < 0) {
7092 warn("error sending READ CAPACITY (16) command");
7094 if (arglist & CAM_ARG_VERBOSE)
7095 cam_error_print(device, ccb, CAM_ESF_ALL,
7096 CAM_EPF_ALL, stderr);
7102 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7103 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7108 maxsector = scsi_8btou64(rcaplong.addr);
7109 block_len = scsi_4btoul(rcaplong.length);
7112 if (blocksizeonly == 0) {
7114 * Humanize implies !quiet, and also implies numblocks.
7116 if (humanize != 0) {
7121 tmpbytes = (maxsector + 1) * block_len;
7122 ret = humanize_number(tmpstr, sizeof(tmpstr),
7123 tmpbytes, "", HN_AUTOSCALE,
7126 HN_DIVISOR_1000 : 0));
7128 warnx("%s: humanize_number failed!", __func__);
7132 fprintf(stdout, "Device Size: %s%s", tmpstr,
7133 (sizeonly == 0) ? ", " : "\n");
7134 } else if (numblocks != 0) {
7135 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7136 "Blocks: " : "", (uintmax_t)maxsector + 1,
7137 (sizeonly == 0) ? ", " : "\n");
7139 fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7140 "Last Block: " : "", (uintmax_t)maxsector,
7141 (sizeonly == 0) ? ", " : "\n");
7145 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7146 "Block Length: " : "", block_len, (quiet == 0) ?
7155 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7156 int retry_count, int timeout)
7160 uint8_t *smp_request = NULL, *smp_response = NULL;
7161 int request_size = 0, response_size = 0;
7162 int fd_request = 0, fd_response = 0;
7163 char *datastr = NULL;
7164 struct get_hook hook;
7169 * Note that at the moment we don't support sending SMP CCBs to
7170 * devices that aren't probed by CAM.
7172 ccb = cam_getccb(device);
7174 warnx("%s: error allocating CCB", __func__);
7178 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7180 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7183 arglist |= CAM_ARG_CMD_IN;
7184 response_size = strtol(optarg, NULL, 0);
7185 if (response_size <= 0) {
7186 warnx("invalid number of response bytes %d",
7189 goto smpcmd_bailout;
7191 hook.argc = argc - optind;
7192 hook.argv = argv + optind;
7195 datastr = cget(&hook, NULL);
7197 * If the user supplied "-" instead of a format, he
7198 * wants the data to be written to stdout.
7200 if ((datastr != NULL)
7201 && (datastr[0] == '-'))
7204 smp_response = (u_int8_t *)malloc(response_size);
7205 if (smp_response == NULL) {
7206 warn("can't malloc memory for SMP response");
7208 goto smpcmd_bailout;
7212 arglist |= CAM_ARG_CMD_OUT;
7213 request_size = strtol(optarg, NULL, 0);
7214 if (request_size <= 0) {
7215 warnx("invalid number of request bytes %d",
7218 goto smpcmd_bailout;
7220 hook.argc = argc - optind;
7221 hook.argv = argv + optind;
7223 datastr = cget(&hook, NULL);
7224 smp_request = (u_int8_t *)malloc(request_size);
7225 if (smp_request == NULL) {
7226 warn("can't malloc memory for SMP request");
7228 goto smpcmd_bailout;
7230 bzero(smp_request, request_size);
7232 * If the user supplied "-" instead of a format, he
7233 * wants the data to be read from stdin.
7235 if ((datastr != NULL)
7236 && (datastr[0] == '-'))
7239 buff_encode_visit(smp_request, request_size,
7250 * If fd_data is set, and we're writing to the device, we need to
7251 * read the data the user wants written from stdin.
7253 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7255 int amt_to_read = request_size;
7256 u_int8_t *buf_ptr = smp_request;
7258 for (amt_read = 0; amt_to_read > 0;
7259 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7260 if (amt_read == -1) {
7261 warn("error reading data from stdin");
7263 goto smpcmd_bailout;
7265 amt_to_read -= amt_read;
7266 buf_ptr += amt_read;
7270 if (((arglist & CAM_ARG_CMD_IN) == 0)
7271 || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7272 warnx("%s: need both the request (-r) and response (-R) "
7273 "arguments", __func__);
7275 goto smpcmd_bailout;
7278 flags |= CAM_DEV_QFRZDIS;
7280 cam_fill_smpio(&ccb->smpio,
7281 /*retries*/ retry_count,
7284 /*smp_request*/ smp_request,
7285 /*smp_request_len*/ request_size,
7286 /*smp_response*/ smp_response,
7287 /*smp_response_len*/ response_size,
7288 /*timeout*/ timeout ? timeout : 5000);
7290 ccb->smpio.flags = SMP_FLAG_NONE;
7292 if (((retval = cam_send_ccb(device, ccb)) < 0)
7293 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7294 const char warnstr[] = "error sending command";
7301 if (arglist & CAM_ARG_VERBOSE) {
7302 cam_error_print(device, ccb, CAM_ESF_ALL,
7303 CAM_EPF_ALL, stderr);
7307 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7308 && (response_size > 0)) {
7309 if (fd_response == 0) {
7310 buff_decode_visit(smp_response, response_size,
7311 datastr, arg_put, NULL);
7312 fprintf(stdout, "\n");
7314 ssize_t amt_written;
7315 int amt_to_write = response_size;
7316 u_int8_t *buf_ptr = smp_response;
7318 for (amt_written = 0; (amt_to_write > 0) &&
7319 (amt_written = write(STDOUT_FILENO, buf_ptr,
7320 amt_to_write)) > 0;){
7321 amt_to_write -= amt_written;
7322 buf_ptr += amt_written;
7324 if (amt_written == -1) {
7325 warn("error writing data to stdout");
7327 goto smpcmd_bailout;
7328 } else if ((amt_written == 0)
7329 && (amt_to_write > 0)) {
7330 warnx("only wrote %u bytes out of %u",
7331 response_size - amt_to_write,
7340 if (smp_request != NULL)
7343 if (smp_response != NULL)
7350 smpreportgeneral(struct cam_device *device, int argc, char **argv,
7351 char *combinedopt, int retry_count, int timeout)
7354 struct smp_report_general_request *request = NULL;
7355 struct smp_report_general_response *response = NULL;
7356 struct sbuf *sb = NULL;
7358 int c, long_response = 0;
7362 * Note that at the moment we don't support sending SMP CCBs to
7363 * devices that aren't probed by CAM.
7365 ccb = cam_getccb(device);
7367 warnx("%s: error allocating CCB", __func__);
7371 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7373 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7382 request = malloc(sizeof(*request));
7383 if (request == NULL) {
7384 warn("%s: unable to allocate %zd bytes", __func__,
7390 response = malloc(sizeof(*response));
7391 if (response == NULL) {
7392 warn("%s: unable to allocate %zd bytes", __func__,
7399 smp_report_general(&ccb->smpio,
7403 /*request_len*/ sizeof(*request),
7404 (uint8_t *)response,
7405 /*response_len*/ sizeof(*response),
7406 /*long_response*/ long_response,
7409 if (((retval = cam_send_ccb(device, ccb)) < 0)
7410 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7411 const char warnstr[] = "error sending command";
7418 if (arglist & CAM_ARG_VERBOSE) {
7419 cam_error_print(device, ccb, CAM_ESF_ALL,
7420 CAM_EPF_ALL, stderr);
7427 * If the device supports the long response bit, try again and see
7428 * if we can get all of the data.
7430 if ((response->long_response & SMP_RG_LONG_RESPONSE)
7431 && (long_response == 0)) {
7432 ccb->ccb_h.status = CAM_REQ_INPROG;
7433 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7439 * XXX KDM detect and decode SMP errors here.
7441 sb = sbuf_new_auto();
7443 warnx("%s: error allocating sbuf", __func__);
7447 smp_report_general_sbuf(response, sizeof(*response), sb);
7449 if (sbuf_finish(sb) != 0) {
7450 warnx("%s: sbuf_finish", __func__);
7454 printf("%s", sbuf_data(sb));
7460 if (request != NULL)
7463 if (response != NULL)
7472 static struct camcontrol_opts phy_ops[] = {
7473 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
7474 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
7475 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
7476 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
7477 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
7478 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
7479 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
7480 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
7481 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
7486 smpphycontrol(struct cam_device *device, int argc, char **argv,
7487 char *combinedopt, int retry_count, int timeout)
7490 struct smp_phy_control_request *request = NULL;
7491 struct smp_phy_control_response *response = NULL;
7492 int long_response = 0;
7495 uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
7497 uint64_t attached_dev_name = 0;
7498 int dev_name_set = 0;
7499 uint32_t min_plr = 0, max_plr = 0;
7500 uint32_t pp_timeout_val = 0;
7501 int slumber_partial = 0;
7502 int set_pp_timeout_val = 0;
7506 * Note that at the moment we don't support sending SMP CCBs to
7507 * devices that aren't probed by CAM.
7509 ccb = cam_getccb(device);
7511 warnx("%s: error allocating CCB", __func__);
7515 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7517 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7525 if (strcasecmp(optarg, "enable") == 0)
7527 else if (strcasecmp(optarg, "disable") == 0)
7530 warnx("%s: Invalid argument %s", __func__,
7537 slumber_partial |= enable <<
7538 SMP_PC_SAS_SLUMBER_SHIFT;
7541 slumber_partial |= enable <<
7542 SMP_PC_SAS_PARTIAL_SHIFT;
7545 slumber_partial |= enable <<
7546 SMP_PC_SATA_SLUMBER_SHIFT;
7549 slumber_partial |= enable <<
7550 SMP_PC_SATA_PARTIAL_SHIFT;
7553 warnx("%s: programmer error", __func__);
7556 break; /*NOTREACHED*/
7561 attached_dev_name = (uintmax_t)strtoumax(optarg,
7570 * We don't do extensive checking here, so this
7571 * will continue to work when new speeds come out.
7573 min_plr = strtoul(optarg, NULL, 0);
7575 || (min_plr > 0xf)) {
7576 warnx("%s: invalid link rate %x",
7584 * We don't do extensive checking here, so this
7585 * will continue to work when new speeds come out.
7587 max_plr = strtoul(optarg, NULL, 0);
7589 || (max_plr > 0xf)) {
7590 warnx("%s: invalid link rate %x",
7597 camcontrol_optret optreturn;
7598 cam_argmask argnums;
7601 if (phy_op_set != 0) {
7602 warnx("%s: only one phy operation argument "
7603 "(-o) allowed", __func__);
7611 * Allow the user to specify the phy operation
7612 * numerically, as well as with a name. This will
7613 * future-proof it a bit, so options that are added
7614 * in future specs can be used.
7616 if (isdigit(optarg[0])) {
7617 phy_operation = strtoul(optarg, NULL, 0);
7618 if ((phy_operation == 0)
7619 || (phy_operation > 0xff)) {
7620 warnx("%s: invalid phy operation %#x",
7621 __func__, phy_operation);
7627 optreturn = getoption(phy_ops, optarg, &phy_operation,
7630 if (optreturn == CC_OR_AMBIGUOUS) {
7631 warnx("%s: ambiguous option %s", __func__,
7636 } else if (optreturn == CC_OR_NOT_FOUND) {
7637 warnx("%s: option %s not found", __func__,
7649 pp_timeout_val = strtoul(optarg, NULL, 0);
7650 if (pp_timeout_val > 15) {
7651 warnx("%s: invalid partial pathway timeout "
7652 "value %u, need a value less than 16",
7653 __func__, pp_timeout_val);
7657 set_pp_timeout_val = 1;
7665 warnx("%s: a PHY (-p phy) argument is required",__func__);
7670 if (((dev_name_set != 0)
7671 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
7672 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
7673 && (dev_name_set == 0))) {
7674 warnx("%s: -d name and -o setdevname arguments both "
7675 "required to set device name", __func__);
7680 request = malloc(sizeof(*request));
7681 if (request == NULL) {
7682 warn("%s: unable to allocate %zd bytes", __func__,
7688 response = malloc(sizeof(*response));
7689 if (response == NULL) {
7690 warn("%s: unable to allocate %zd bytes", __func__,
7696 smp_phy_control(&ccb->smpio,
7701 (uint8_t *)response,
7704 /*expected_exp_change_count*/ 0,
7707 (set_pp_timeout_val != 0) ? 1 : 0,
7715 if (((retval = cam_send_ccb(device, ccb)) < 0)
7716 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7717 const char warnstr[] = "error sending command";
7724 if (arglist & CAM_ARG_VERBOSE) {
7726 * Use CAM_EPF_NORMAL so we only get one line of
7727 * SMP command decoding.
7729 cam_error_print(device, ccb, CAM_ESF_ALL,
7730 CAM_EPF_NORMAL, stderr);
7736 /* XXX KDM print out something here for success? */
7741 if (request != NULL)
7744 if (response != NULL)
7751 smpmaninfo(struct cam_device *device, int argc, char **argv,
7752 char *combinedopt, int retry_count, int timeout)
7755 struct smp_report_manuf_info_request request;
7756 struct smp_report_manuf_info_response response;
7757 struct sbuf *sb = NULL;
7758 int long_response = 0;
7763 * Note that at the moment we don't support sending SMP CCBs to
7764 * devices that aren't probed by CAM.
7766 ccb = cam_getccb(device);
7768 warnx("%s: error allocating CCB", __func__);
7772 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7774 while ((c = getopt(argc, argv, combinedopt)) != -1) {
7783 bzero(&request, sizeof(request));
7784 bzero(&response, sizeof(response));
7786 smp_report_manuf_info(&ccb->smpio,
7791 (uint8_t *)&response,
7796 if (((retval = cam_send_ccb(device, ccb)) < 0)
7797 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7798 const char warnstr[] = "error sending command";
7805 if (arglist & CAM_ARG_VERBOSE) {
7806 cam_error_print(device, ccb, CAM_ESF_ALL,
7807 CAM_EPF_ALL, stderr);
7813 sb = sbuf_new_auto();
7815 warnx("%s: error allocating sbuf", __func__);
7819 smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
7821 if (sbuf_finish(sb) != 0) {
7822 warnx("%s: sbuf_finish", __func__);
7826 printf("%s", sbuf_data(sb));
7840 getdevid(struct cam_devitem *item)
7843 union ccb *ccb = NULL;
7845 struct cam_device *dev;
7847 dev = cam_open_btl(item->dev_match.path_id,
7848 item->dev_match.target_id,
7849 item->dev_match.target_lun, O_RDWR, NULL);
7852 warnx("%s", cam_errbuf);
7857 item->device_id_len = 0;
7859 ccb = cam_getccb(dev);
7861 warnx("%s: error allocating CCB", __func__);
7866 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
7869 * On the first try, we just probe for the size of the data, and
7870 * then allocate that much memory and try again.
7873 ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
7874 ccb->ccb_h.flags = CAM_DIR_IN;
7875 ccb->cdai.flags = CDAI_FLAG_NONE;
7876 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
7877 ccb->cdai.bufsiz = item->device_id_len;
7878 if (item->device_id_len != 0)
7879 ccb->cdai.buf = (uint8_t *)item->device_id;
7881 if (cam_send_ccb(dev, ccb) < 0) {
7882 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
7887 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7888 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
7893 if (item->device_id_len == 0) {
7895 * This is our first time through. Allocate the buffer,
7896 * and then go back to get the data.
7898 if (ccb->cdai.provsiz == 0) {
7899 warnx("%s: invalid .provsiz field returned with "
7900 "XPT_GDEV_ADVINFO CCB", __func__);
7904 item->device_id_len = ccb->cdai.provsiz;
7905 item->device_id = malloc(item->device_id_len);
7906 if (item->device_id == NULL) {
7907 warn("%s: unable to allocate %d bytes", __func__,
7908 item->device_id_len);
7912 ccb->ccb_h.status = CAM_REQ_INPROG;
7918 cam_close_device(dev);
7927 * XXX KDM merge this code with getdevtree()?
7930 buildbusdevlist(struct cam_devlist *devlist)
7933 int bufsize, fd = -1;
7934 struct dev_match_pattern *patterns;
7935 struct cam_devitem *item = NULL;
7936 int skip_device = 0;
7939 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
7940 warn("couldn't open %s", XPT_DEVICE);
7944 bzero(&ccb, sizeof(union ccb));
7946 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
7947 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
7948 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
7950 ccb.ccb_h.func_code = XPT_DEV_MATCH;
7951 bufsize = sizeof(struct dev_match_result) * 100;
7952 ccb.cdm.match_buf_len = bufsize;
7953 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
7954 if (ccb.cdm.matches == NULL) {
7955 warnx("can't malloc memory for matches");
7959 ccb.cdm.num_matches = 0;
7960 ccb.cdm.num_patterns = 2;
7961 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
7962 ccb.cdm.num_patterns;
7964 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
7965 if (patterns == NULL) {
7966 warnx("can't malloc memory for patterns");
7971 ccb.cdm.patterns = patterns;
7972 bzero(patterns, ccb.cdm.pattern_buf_len);
7974 patterns[0].type = DEV_MATCH_DEVICE;
7975 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
7976 patterns[0].pattern.device_pattern.path_id = devlist->path_id;
7977 patterns[1].type = DEV_MATCH_PERIPH;
7978 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
7979 patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
7982 * We do the ioctl multiple times if necessary, in case there are
7983 * more than 100 nodes in the EDT.
7988 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
7989 warn("error sending CAMIOCOMMAND ioctl");
7994 if ((ccb.ccb_h.status != CAM_REQ_CMP)
7995 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
7996 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
7997 warnx("got CAM error %#x, CDM error %d\n",
7998 ccb.ccb_h.status, ccb.cdm.status);
8003 for (i = 0; i < ccb.cdm.num_matches; i++) {
8004 switch (ccb.cdm.matches[i].type) {
8005 case DEV_MATCH_DEVICE: {
8006 struct device_match_result *dev_result;
8009 &ccb.cdm.matches[i].result.device_result;
8011 if (dev_result->flags &
8012 DEV_RESULT_UNCONFIGURED) {
8018 item = malloc(sizeof(*item));
8020 warn("%s: unable to allocate %zd bytes",
8021 __func__, sizeof(*item));
8025 bzero(item, sizeof(*item));
8026 bcopy(dev_result, &item->dev_match,
8027 sizeof(*dev_result));
8028 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8031 if (getdevid(item) != 0) {
8037 case DEV_MATCH_PERIPH: {
8038 struct periph_match_result *periph_result;
8041 &ccb.cdm.matches[i].result.periph_result;
8043 if (skip_device != 0)
8045 item->num_periphs++;
8046 item->periph_matches = realloc(
8047 item->periph_matches,
8049 sizeof(struct periph_match_result));
8050 if (item->periph_matches == NULL) {
8051 warn("%s: error allocating periph "
8056 bcopy(periph_result, &item->periph_matches[
8057 item->num_periphs - 1],
8058 sizeof(*periph_result));
8062 fprintf(stderr, "%s: unexpected match "
8063 "type %d\n", __func__,
8064 ccb.cdm.matches[i].type);
8067 break; /*NOTREACHED*/
8070 } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8071 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8079 free(ccb.cdm.matches);
8082 freebusdevlist(devlist);
8088 freebusdevlist(struct cam_devlist *devlist)
8090 struct cam_devitem *item, *item2;
8092 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8093 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8095 free(item->device_id);
8096 free(item->periph_matches);
8101 static struct cam_devitem *
8102 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8104 struct cam_devitem *item;
8106 STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8107 struct scsi_vpd_id_descriptor *idd;
8110 * XXX KDM look for LUN IDs as well?
8112 idd = scsi_get_devid(item->device_id,
8113 item->device_id_len,
8114 scsi_devid_is_sas_target);
8118 if (scsi_8btou64(idd->identifier) == sasaddr)
8126 smpphylist(struct cam_device *device, int argc, char **argv,
8127 char *combinedopt, int retry_count, int timeout)
8129 struct smp_report_general_request *rgrequest = NULL;
8130 struct smp_report_general_response *rgresponse = NULL;
8131 struct smp_discover_request *disrequest = NULL;
8132 struct smp_discover_response *disresponse = NULL;
8133 struct cam_devlist devlist;
8135 int long_response = 0;
8142 * Note that at the moment we don't support sending SMP CCBs to
8143 * devices that aren't probed by CAM.
8145 ccb = cam_getccb(device);
8147 warnx("%s: error allocating CCB", __func__);
8151 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8152 STAILQ_INIT(&devlist.dev_queue);
8154 rgrequest = malloc(sizeof(*rgrequest));
8155 if (rgrequest == NULL) {
8156 warn("%s: unable to allocate %zd bytes", __func__,
8157 sizeof(*rgrequest));
8162 rgresponse = malloc(sizeof(*rgresponse));
8163 if (rgresponse == NULL) {
8164 warn("%s: unable to allocate %zd bytes", __func__,
8165 sizeof(*rgresponse));
8170 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8183 smp_report_general(&ccb->smpio,
8187 /*request_len*/ sizeof(*rgrequest),
8188 (uint8_t *)rgresponse,
8189 /*response_len*/ sizeof(*rgresponse),
8190 /*long_response*/ long_response,
8193 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8195 if (((retval = cam_send_ccb(device, ccb)) < 0)
8196 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8197 const char warnstr[] = "error sending command";
8204 if (arglist & CAM_ARG_VERBOSE) {
8205 cam_error_print(device, ccb, CAM_ESF_ALL,
8206 CAM_EPF_ALL, stderr);
8212 num_phys = rgresponse->num_phys;
8214 if (num_phys == 0) {
8216 fprintf(stdout, "%s: No Phys reported\n", __func__);
8221 devlist.path_id = device->path_id;
8223 retval = buildbusdevlist(&devlist);
8228 fprintf(stdout, "%d PHYs:\n", num_phys);
8229 fprintf(stdout, "PHY Attached SAS Address\n");
8232 disrequest = malloc(sizeof(*disrequest));
8233 if (disrequest == NULL) {
8234 warn("%s: unable to allocate %zd bytes", __func__,
8235 sizeof(*disrequest));
8240 disresponse = malloc(sizeof(*disresponse));
8241 if (disresponse == NULL) {
8242 warn("%s: unable to allocate %zd bytes", __func__,
8243 sizeof(*disresponse));
8248 for (i = 0; i < num_phys; i++) {
8249 struct cam_devitem *item;
8250 struct device_match_result *dev_match;
8251 char vendor[16], product[48], revision[16];
8255 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8257 ccb->ccb_h.status = CAM_REQ_INPROG;
8258 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8260 smp_discover(&ccb->smpio,
8264 sizeof(*disrequest),
8265 (uint8_t *)disresponse,
8266 sizeof(*disresponse),
8268 /*ignore_zone_group*/ 0,
8272 if (((retval = cam_send_ccb(device, ccb)) < 0)
8273 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
8274 && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
8275 const char warnstr[] = "error sending command";
8282 if (arglist & CAM_ARG_VERBOSE) {
8283 cam_error_print(device, ccb, CAM_ESF_ALL,
8284 CAM_EPF_ALL, stderr);
8290 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
8292 fprintf(stdout, "%3d <vacant>\n", i);
8296 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
8299 item = findsasdevice(&devlist,
8300 scsi_8btou64(disresponse->attached_sas_address));
8304 || (item != NULL)) {
8305 fprintf(stdout, "%3d 0x%016jx", i,
8306 (uintmax_t)scsi_8btou64(
8307 disresponse->attached_sas_address));
8309 fprintf(stdout, "\n");
8312 } else if (quiet != 0)
8315 dev_match = &item->dev_match;
8317 if (dev_match->protocol == PROTO_SCSI) {
8318 cam_strvis(vendor, dev_match->inq_data.vendor,
8319 sizeof(dev_match->inq_data.vendor),
8321 cam_strvis(product, dev_match->inq_data.product,
8322 sizeof(dev_match->inq_data.product),
8324 cam_strvis(revision, dev_match->inq_data.revision,
8325 sizeof(dev_match->inq_data.revision),
8327 sprintf(tmpstr, "<%s %s %s>", vendor, product,
8329 } else if ((dev_match->protocol == PROTO_ATA)
8330 || (dev_match->protocol == PROTO_SATAPM)) {
8331 cam_strvis(product, dev_match->ident_data.model,
8332 sizeof(dev_match->ident_data.model),
8334 cam_strvis(revision, dev_match->ident_data.revision,
8335 sizeof(dev_match->ident_data.revision),
8337 sprintf(tmpstr, "<%s %s>", product, revision);
8339 sprintf(tmpstr, "<>");
8341 fprintf(stdout, " %-33s ", tmpstr);
8344 * If we have 0 periphs, that's a bug...
8346 if (item->num_periphs == 0) {
8347 fprintf(stdout, "\n");
8351 fprintf(stdout, "(");
8352 for (j = 0; j < item->num_periphs; j++) {
8354 fprintf(stdout, ",");
8356 fprintf(stdout, "%s%d",
8357 item->periph_matches[j].periph_name,
8358 item->periph_matches[j].unit_number);
8361 fprintf(stdout, ")\n");
8375 freebusdevlist(&devlist);
8381 atapm(struct cam_device *device, int argc, char **argv,
8382 char *combinedopt, int retry_count, int timeout)
8390 ccb = cam_getccb(device);
8393 warnx("%s: error allocating ccb", __func__);
8397 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8406 if (strcmp(argv[1], "idle") == 0) {
8408 cmd = ATA_IDLE_IMMEDIATE;
8411 } else if (strcmp(argv[1], "standby") == 0) {
8413 cmd = ATA_STANDBY_IMMEDIATE;
8415 cmd = ATA_STANDBY_CMD;
8423 else if (t <= (240 * 5))
8425 else if (t <= (252 * 5))
8426 /* special encoding for 21 minutes */
8428 else if (t <= (11 * 30 * 60))
8429 sc = (t - 1) / (30 * 60) + 241;
8433 retval = ata_do_28bit_cmd(device,
8435 /*retries*/retry_count,
8436 /*flags*/CAM_DIR_NONE,
8437 /*protocol*/AP_PROTO_NON_DATA,
8438 /*tag_action*/MSG_SIMPLE_Q_TAG,
8445 /*timeout*/timeout ? timeout : 30 * 1000,
8453 ataaxm(struct cam_device *device, int argc, char **argv,
8454 char *combinedopt, int retry_count, int timeout)
8462 ccb = cam_getccb(device);
8465 warnx("%s: error allocating ccb", __func__);
8469 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8479 if (strcmp(argv[1], "apm") == 0) {
8495 retval = ata_do_28bit_cmd(device,
8497 /*retries*/retry_count,
8498 /*flags*/CAM_DIR_NONE,
8499 /*protocol*/AP_PROTO_NON_DATA,
8500 /*tag_action*/MSG_SIMPLE_Q_TAG,
8501 /*command*/ATA_SETFEATURES,
8507 /*timeout*/timeout ? timeout : 30 * 1000,
8515 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
8516 int show_sa_errors, int sa_set, int service_action,
8517 int timeout_desc, int task_attr, int retry_count, int timeout,
8518 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
8520 union ccb *ccb = NULL;
8521 uint8_t *buf = NULL;
8522 uint32_t alloc_len = 0, num_opcodes;
8523 uint32_t valid_len = 0;
8524 uint32_t avail_len = 0;
8525 struct scsi_report_supported_opcodes_all *all_hdr;
8526 struct scsi_report_supported_opcodes_one *one;
8531 * Make it clear that we haven't yet allocated or filled anything.
8536 ccb = cam_getccb(device);
8538 warnx("couldn't allocate CCB");
8543 /* cam_getccb cleans up the header, caller has to zero the payload */
8544 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8546 if (opcode_set != 0) {
8547 options |= RSO_OPTIONS_OC;
8549 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
8552 alloc_len = sizeof(*all_hdr) + (num_opcodes *
8553 sizeof(struct scsi_report_supported_opcodes_descr));
8556 if (timeout_desc != 0) {
8557 options |= RSO_RCTD;
8558 alloc_len += num_opcodes *
8559 sizeof(struct scsi_report_supported_opcodes_timeout);
8563 options |= RSO_OPTIONS_OC_SA;
8564 if (show_sa_errors != 0)
8565 options &= ~RSO_OPTIONS_OC;
8574 buf = malloc(alloc_len);
8576 warn("Unable to allocate %u bytes", alloc_len);
8580 bzero(buf, alloc_len);
8582 scsi_report_supported_opcodes(&ccb->csio,
8583 /*retries*/ retry_count,
8585 /*tag_action*/ task_attr,
8586 /*options*/ options,
8587 /*req_opcode*/ opcode,
8588 /*req_service_action*/ service_action,
8590 /*dxfer_len*/ alloc_len,
8591 /*sense_len*/ SSD_FULL_SIZE,
8592 /*timeout*/ timeout ? timeout : 10000);
8594 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8596 if (retry_count != 0)
8597 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
8599 if (cam_send_ccb(device, ccb) < 0) {
8600 perror("error sending REPORT SUPPORTED OPERATION CODES");
8605 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8606 if (verbosemode != 0)
8607 cam_error_print(device, ccb, CAM_ESF_ALL,
8608 CAM_EPF_ALL, stderr);
8614 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
8616 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
8617 && (valid_len >= sizeof(*all_hdr))) {
8618 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
8619 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
8620 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
8621 && (valid_len >= sizeof(*one))) {
8622 uint32_t cdb_length;
8624 one = (struct scsi_report_supported_opcodes_one *)buf;
8625 cdb_length = scsi_2btoul(one->cdb_length);
8626 avail_len = sizeof(*one) + cdb_length;
8627 if (one->support & RSO_ONE_CTDP) {
8628 struct scsi_report_supported_opcodes_timeout *td;
8630 td = (struct scsi_report_supported_opcodes_timeout *)
8632 if (valid_len >= (avail_len + sizeof(td->length))) {
8633 avail_len += scsi_2btoul(td->length) +
8636 avail_len += sizeof(*td);
8642 * avail_len could be zero if we didn't get enough data back from
8643 * thet target to determine
8645 if ((avail_len != 0)
8646 && (avail_len > valid_len)) {
8647 alloc_len = avail_len;
8651 *fill_len = valid_len;
8663 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
8664 int req_sa, uint8_t *buf, uint32_t valid_len)
8666 struct scsi_report_supported_opcodes_one *one;
8667 struct scsi_report_supported_opcodes_timeout *td;
8668 uint32_t cdb_len = 0, td_len = 0;
8669 const char *op_desc = NULL;
8673 one = (struct scsi_report_supported_opcodes_one *)buf;
8676 * If we don't have the full single opcode descriptor, no point in
8679 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8681 warnx("Only %u bytes returned, not enough to verify support",
8687 op_desc = scsi_op_desc(req_opcode, &device->inq_data);
8689 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
8692 printf(", SA 0x%x", req_sa);
8695 switch (one->support & RSO_ONE_SUP_MASK) {
8696 case RSO_ONE_SUP_UNAVAIL:
8697 printf("No command support information currently available\n");
8699 case RSO_ONE_SUP_NOT_SUP:
8700 printf("Command not supported\n");
8703 break; /*NOTREACHED*/
8704 case RSO_ONE_SUP_AVAIL:
8705 printf("Command is supported, complies with a SCSI standard\n");
8707 case RSO_ONE_SUP_VENDOR:
8708 printf("Command is supported, vendor-specific "
8709 "implementation\n");
8712 printf("Unknown command support flags 0x%#x\n",
8713 one->support & RSO_ONE_SUP_MASK);
8718 * If we don't have the CDB length, it isn't exactly an error, the
8719 * command probably isn't supported.
8721 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
8725 cdb_len = scsi_2btoul(one->cdb_length);
8728 * If our valid data doesn't include the full reported length,
8729 * return. The caller should have detected this and adjusted his
8730 * allocation length to get all of the available data.
8732 if (valid_len < sizeof(*one) + cdb_len) {
8738 * If all we have is the opcode, there is no point in printing out
8746 printf("CDB usage bitmap:");
8747 for (i = 0; i < cdb_len; i++) {
8748 printf(" %02x", one->cdb_usage[i]);
8753 * If we don't have a timeout descriptor, we're done.
8755 if ((one->support & RSO_ONE_CTDP) == 0)
8759 * If we don't have enough valid length to include the timeout
8760 * descriptor length, we're done.
8762 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
8765 td = (struct scsi_report_supported_opcodes_timeout *)
8766 &buf[sizeof(*one) + cdb_len];
8767 td_len = scsi_2btoul(td->length);
8768 td_len += sizeof(td->length);
8771 * If we don't have the full timeout descriptor, we're done.
8773 if (td_len < sizeof(*td))
8777 * If we don't have enough valid length to contain the full timeout
8778 * descriptor, we're done.
8780 if (valid_len < (sizeof(*one) + cdb_len + td_len))
8783 printf("Timeout information:\n");
8784 printf("Command-specific: 0x%02x\n", td->cmd_specific);
8785 printf("Nominal timeout: %u seconds\n",
8786 scsi_4btoul(td->nominal_time));
8787 printf("Recommended timeout: %u seconds\n",
8788 scsi_4btoul(td->recommended_time));
8795 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
8798 struct scsi_report_supported_opcodes_all *hdr;
8799 struct scsi_report_supported_opcodes_descr *desc;
8800 uint32_t avail_len = 0, used_len = 0;
8804 if (valid_len < sizeof(*hdr)) {
8805 warnx("%s: not enough returned data (%u bytes) opcode list",
8806 __func__, valid_len);
8810 hdr = (struct scsi_report_supported_opcodes_all *)buf;
8811 avail_len = scsi_4btoul(hdr->length);
8812 avail_len += sizeof(hdr->length);
8814 * Take the lesser of the amount of data the drive claims is
8815 * available, and the amount of data the HBA says was returned.
8817 avail_len = MIN(avail_len, valid_len);
8819 used_len = sizeof(hdr->length);
8821 printf("%-6s %4s %8s ",
8822 "Opcode", "SA", "CDB len" );
8825 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
8826 printf(" Description\n");
8828 while ((avail_len - used_len) > sizeof(*desc)) {
8829 struct scsi_report_supported_opcodes_timeout *td;
8831 const char *op_desc = NULL;
8833 cur_ptr = &buf[used_len];
8834 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
8836 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
8837 if (op_desc == NULL)
8838 op_desc = "UNKNOWN";
8840 printf("0x%02x %#4x %8u ", desc->opcode,
8841 scsi_2btoul(desc->service_action),
8842 scsi_2btoul(desc->cdb_length));
8844 used_len += sizeof(*desc);
8846 if ((desc->flags & RSO_CTDP) == 0) {
8847 printf(" %s\n", op_desc);
8852 * If we don't have enough space to fit a timeout
8853 * descriptor, then we're done.
8855 if (avail_len - used_len < sizeof(*td)) {
8856 used_len = avail_len;
8857 printf(" %s\n", op_desc);
8860 cur_ptr = &buf[used_len];
8861 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
8862 td_len = scsi_2btoul(td->length);
8863 td_len += sizeof(td->length);
8867 * If the given timeout descriptor length is less than what
8868 * we understand, skip it.
8870 if (td_len < sizeof(*td)) {
8871 printf(" %s\n", op_desc);
8875 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific,
8876 scsi_4btoul(td->nominal_time),
8877 scsi_4btoul(td->recommended_time), op_desc);
8884 scsiopcodes(struct cam_device *device, int argc, char **argv,
8885 char *combinedopt, int task_attr, int retry_count, int timeout,
8889 uint32_t opcode = 0, service_action = 0;
8890 int td_set = 0, opcode_set = 0, sa_set = 0;
8891 int show_sa_errors = 1;
8892 uint32_t valid_len = 0;
8893 uint8_t *buf = NULL;
8897 while ((c = getopt(argc, argv, combinedopt)) != -1) {
8903 opcode = strtoul(optarg, &endptr, 0);
8904 if (*endptr != '\0') {
8905 warnx("Invalid opcode \"%s\", must be a number",
8910 if (opcode > 0xff) {
8911 warnx("Invalid opcode 0x%#x, must be between"
8912 "0 and 0xff inclusive", opcode);
8919 service_action = strtoul(optarg, &endptr, 0);
8920 if (*endptr != '\0') {
8921 warnx("Invalid service action \"%s\", must "
8922 "be a number", optarg);
8926 if (service_action > 0xffff) {
8927 warnx("Invalid service action 0x%#x, must "
8928 "be between 0 and 0xffff inclusive",
8943 && (opcode_set == 0)) {
8944 warnx("You must specify an opcode with -o if a service "
8949 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
8950 sa_set, service_action, td_set, task_attr,
8951 retry_count, timeout, verbosemode, &valid_len,
8956 if ((opcode_set != 0)
8958 retval = scsiprintoneopcode(device, opcode, sa_set,
8959 service_action, buf, valid_len);
8961 retval = scsiprintopcodes(device, td_set, buf, valid_len);
8970 #endif /* MINIMALISTIC */
8973 scsireprobe(struct cam_device *device)
8978 ccb = cam_getccb(device);
8981 warnx("%s: error allocating ccb", __func__);
8985 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
8987 ccb->ccb_h.func_code = XPT_REPROBE_LUN;
8989 if (cam_send_ccb(device, ccb) < 0) {
8990 warn("error sending XPT_REPROBE_LUN CCB");
8995 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
8996 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9008 usage(int printlong)
9011 fprintf(printlong ? stdout : stderr,
9012 "usage: camcontrol <command> [device id][generic args][command args]\n"
9013 " camcontrol devlist [-b] [-v]\n"
9014 #ifndef MINIMALISTIC
9015 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9016 " camcontrol tur [dev_id][generic args]\n"
9017 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
9018 " camcontrol identify [dev_id][generic args] [-v]\n"
9019 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9020 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9022 " camcontrol start [dev_id][generic args]\n"
9023 " camcontrol stop [dev_id][generic args]\n"
9024 " camcontrol load [dev_id][generic args]\n"
9025 " camcontrol eject [dev_id][generic args]\n"
9026 " camcontrol reprobe [dev_id][generic args]\n"
9027 #endif /* MINIMALISTIC */
9028 " camcontrol rescan <all | bus[:target:lun] | dev_id>\n"
9029 " camcontrol reset <all | bus[:target:lun] | dev_id>\n"
9030 #ifndef MINIMALISTIC
9031 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
9032 " [-q][-s][-S offset][-X]\n"
9033 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
9034 " [-P pagectl][-e | -b][-d]\n"
9035 " camcontrol cmd [dev_id][generic args]\n"
9036 " <-a cmd [args] | -c cmd [args]>\n"
9037 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9038 " camcontrol smpcmd [dev_id][generic args]\n"
9039 " <-r len fmt [args]> <-R len fmt [args]>\n"
9040 " camcontrol smprg [dev_id][generic args][-l]\n"
9041 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n"
9042 " [-o operation][-d name][-m rate][-M rate]\n"
9043 " [-T pp_timeout][-a enable|disable]\n"
9044 " [-A enable|disable][-s enable|disable]\n"
9045 " [-S enable|disable]\n"
9046 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9047 " camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9048 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
9049 " <all|bus[:target[:lun]]|off>\n"
9050 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
9051 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
9052 " [-D <enable|disable>][-M mode][-O offset]\n"
9053 " [-q][-R syncrate][-v][-T <enable|disable>]\n"
9054 " [-U][-W bus_width]\n"
9055 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
9056 " camcontrol sanitize [dev_id][generic args]\n"
9057 " [-a overwrite|block|crypto|exitfailure]\n"
9058 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9060 " camcontrol idle [dev_id][generic args][-t time]\n"
9061 " camcontrol standby [dev_id][generic args][-t time]\n"
9062 " camcontrol sleep [dev_id][generic args]\n"
9063 " camcontrol apm [dev_id][generic args][-l level]\n"
9064 " camcontrol aam [dev_id][generic args][-l level]\n"
9065 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9067 " camcontrol security [dev_id][generic args]\n"
9068 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9069 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9070 " [-U <user|master>] [-y]\n"
9071 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9072 " [-q] [-s max_sectors] [-U pwd] [-y]\n"
9073 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n"
9074 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9075 " [-s scope][-S][-T type][-U]\n"
9076 " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n"
9077 " [-a attr_num][-c][-e elem][-F form1,form1]\n"
9078 " [-p part][-s start][-T type][-V vol]\n"
9079 " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n"
9081 " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9082 " [-o rep_opts] [-P print_opts]\n"
9083 " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9084 " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9085 " [-S power_src] [-T timer]\n"
9086 " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9087 " <-s <-f format -T time | -U >>\n"
9089 #endif /* MINIMALISTIC */
9090 " camcontrol help\n");
9093 #ifndef MINIMALISTIC
9095 "Specify one of the following options:\n"
9096 "devlist list all CAM devices\n"
9097 "periphlist list all CAM peripheral drivers attached to a device\n"
9098 "tur send a test unit ready to the named device\n"
9099 "inquiry send a SCSI inquiry command to the named device\n"
9100 "identify send a ATA identify command to the named device\n"
9101 "reportluns send a SCSI report luns command to the device\n"
9102 "readcap send a SCSI read capacity command to the device\n"
9103 "start send a Start Unit command to the device\n"
9104 "stop send a Stop Unit command to the device\n"
9105 "load send a Start Unit command to the device with the load bit set\n"
9106 "eject send a Stop Unit command to the device with the eject bit set\n"
9107 "reprobe update capacity information of the given device\n"
9108 "rescan rescan all buses, the given bus, bus:target:lun or device\n"
9109 "reset reset all buses, the given bus, bus:target:lun or device\n"
9110 "defects read the defect list of the specified device\n"
9111 "modepage display or edit (-e) the given mode page\n"
9112 "cmd send the given SCSI command, may need -i or -o as well\n"
9113 "smpcmd send the given SMP command, requires -o and -i\n"
9114 "smprg send the SMP Report General command\n"
9115 "smppc send the SMP PHY Control command, requires -p\n"
9116 "smpphylist display phys attached to a SAS expander\n"
9117 "smpmaninfo send the SMP Report Manufacturer Info command\n"
9118 "debug turn debugging on/off for a bus, target, or lun, or all devices\n"
9119 "tags report or set the number of transaction slots for a device\n"
9120 "negotiate report or set device negotiation parameters\n"
9121 "format send the SCSI FORMAT UNIT command to the named device\n"
9122 "sanitize send the SCSI SANITIZE command to the named device\n"
9123 "idle send the ATA IDLE command to the named device\n"
9124 "standby send the ATA STANDBY command to the named device\n"
9125 "sleep send the ATA SLEEP command to the named device\n"
9126 "fwdownload program firmware of the named device with the given image\n"
9127 "security report or send ATA security commands to the named device\n"
9128 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9129 "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n"
9130 "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n"
9131 "zone manage Zoned Block (Shingled) devices\n"
9132 "epc send ATA Extended Power Conditions commands\n"
9133 "timestamp report or set the device's timestamp\n"
9134 "help this message\n"
9135 "Device Identifiers:\n"
9136 "bus:target specify the bus and target, lun defaults to 0\n"
9137 "bus:target:lun specify the bus, target and lun\n"
9138 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
9139 "Generic arguments:\n"
9140 "-v be verbose, print out sense information\n"
9141 "-t timeout command timeout in seconds, overrides default timeout\n"
9142 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n"
9143 "-u unit specify unit number, e.g. \"0\", \"5\"\n"
9144 "-E have the kernel attempt to perform SCSI error recovery\n"
9145 "-C count specify the SCSI command retry count (needs -E to work)\n"
9146 "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n"
9147 "modepage arguments:\n"
9148 "-l list all available mode pages\n"
9149 "-m page specify the mode page to view or edit\n"
9150 "-e edit the specified mode page\n"
9151 "-b force view to binary mode\n"
9152 "-d disable block descriptors for mode sense\n"
9153 "-P pgctl page control field 0-3\n"
9154 "defects arguments:\n"
9155 "-f format specify defect list format (block, bfi or phys)\n"
9156 "-G get the grown defect list\n"
9157 "-P get the permanent defect list\n"
9158 "inquiry arguments:\n"
9159 "-D get the standard inquiry data\n"
9160 "-S get the serial number\n"
9161 "-R get the transfer rate, etc.\n"
9162 "reportluns arguments:\n"
9163 "-c only report a count of available LUNs\n"
9164 "-l only print out luns, and not a count\n"
9165 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n"
9166 "readcap arguments\n"
9167 "-b only report the blocksize\n"
9168 "-h human readable device size, base 2\n"
9169 "-H human readable device size, base 10\n"
9170 "-N print the number of blocks instead of last block\n"
9171 "-q quiet, print numbers only\n"
9172 "-s only report the last block/device size\n"
9174 "-c cdb [args] specify the SCSI CDB\n"
9175 "-i len fmt specify input data and input data format\n"
9176 "-o len fmt [args] specify output data and output data fmt\n"
9177 "smpcmd arguments:\n"
9178 "-r len fmt [args] specify the SMP command to be sent\n"
9179 "-R len fmt [args] specify SMP response format\n"
9180 "smprg arguments:\n"
9181 "-l specify the long response format\n"
9182 "smppc arguments:\n"
9183 "-p phy specify the PHY to operate on\n"
9184 "-l specify the long request/response format\n"
9185 "-o operation specify the phy control operation\n"
9186 "-d name set the attached device name\n"
9187 "-m rate set the minimum physical link rate\n"
9188 "-M rate set the maximum physical link rate\n"
9189 "-T pp_timeout set the partial pathway timeout value\n"
9190 "-a enable|disable enable or disable SATA slumber\n"
9191 "-A enable|disable enable or disable SATA partial phy power\n"
9192 "-s enable|disable enable or disable SAS slumber\n"
9193 "-S enable|disable enable or disable SAS partial phy power\n"
9194 "smpphylist arguments:\n"
9195 "-l specify the long response format\n"
9196 "-q only print phys with attached devices\n"
9197 "smpmaninfo arguments:\n"
9198 "-l specify the long response format\n"
9199 "debug arguments:\n"
9200 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
9201 "-T CAM_DEBUG_TRACE -- routine flow tracking\n"
9202 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
9203 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
9205 "-N tags specify the number of tags to use for this device\n"
9206 "-q be quiet, don't report the number of tags\n"
9207 "-v report a number of tag-related parameters\n"
9208 "negotiate arguments:\n"
9209 "-a send a test unit ready after negotiation\n"
9210 "-c report/set current negotiation settings\n"
9211 "-D <arg> \"enable\" or \"disable\" disconnection\n"
9212 "-M mode set ATA mode\n"
9213 "-O offset set command delay offset\n"
9214 "-q be quiet, don't report anything\n"
9215 "-R syncrate synchronization rate in MHz\n"
9216 "-T <arg> \"enable\" or \"disable\" tagged queueing\n"
9217 "-U report/set user negotiation settings\n"
9218 "-W bus_width set the bus width in bits (8, 16 or 32)\n"
9219 "-v also print a Path Inquiry CCB for the controller\n"
9220 "format arguments:\n"
9221 "-q be quiet, don't print status messages\n"
9222 "-r run in report only mode\n"
9223 "-w don't send immediate format command\n"
9224 "-y don't ask any questions\n"
9225 "sanitize arguments:\n"
9226 "-a operation operation mode: overwrite, block, crypto or exitfailure\n"
9227 "-c passes overwrite passes to perform (1 to 31)\n"
9228 "-I invert overwrite pattern after each pass\n"
9229 "-P pattern path to overwrite pattern file\n"
9230 "-q be quiet, don't print status messages\n"
9231 "-r run in report only mode\n"
9232 "-U run operation in unrestricted completion exit mode\n"
9233 "-w don't send immediate sanitize command\n"
9234 "-y don't ask any questions\n"
9235 "idle/standby arguments:\n"
9236 "-t <arg> number of seconds before respective state.\n"
9237 "fwdownload arguments:\n"
9238 "-f fw_image path to firmware image file\n"
9239 "-q don't print informational messages, only errors\n"
9240 "-s run in simulation mode\n"
9241 "-v print info for every firmware segment sent to device\n"
9242 "-y don't ask any questions\n"
9243 "security arguments:\n"
9244 "-d pwd disable security using the given password for the selected\n"
9246 "-e pwd erase the device using the given pwd for the selected user\n"
9247 "-f freeze the security configuration of the specified device\n"
9248 "-h pwd enhanced erase the device using the given pwd for the\n"
9250 "-k pwd unlock the device using the given pwd for the selected\n"
9252 "-l <high|maximum> specifies which security level to set: high or maximum\n"
9253 "-q be quiet, do not print any status messages\n"
9254 "-s pwd password the device (enable security) using the given\n"
9255 " pwd for the selected user\n"
9256 "-T timeout overrides the timeout (seconds) used for erase operation\n"
9257 "-U <user|master> specifies which user to set: user or master\n"
9258 "-y don't ask any questions\n"
9260 "-f freeze the HPA configuration of the device\n"
9261 "-l lock the HPA configuration of the device\n"
9262 "-P make the HPA max sectors persist\n"
9263 "-p pwd Set the HPA configuration password required for unlock\n"
9265 "-q be quiet, do not print any status messages\n"
9266 "-s sectors configures the maximum user accessible sectors of the\n"
9268 "-U pwd unlock the HPA configuration of the device\n"
9269 "-y don't ask any questions\n"
9270 "persist arguments:\n"
9271 "-i action specify read_keys, read_reservation, report_cap, or\n"
9272 " read_full_status\n"
9273 "-o action specify register, register_ignore, reserve, release,\n"
9274 " clear, preempt, preempt_abort, register_move, replace_lost\n"
9275 "-a set the All Target Ports (ALL_TG_PT) bit\n"
9276 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n"
9277 "-k key specify the Reservation Key\n"
9278 "-K sa_key specify the Service Action Reservation Key\n"
9279 "-p set the Activate Persist Through Power Loss bit\n"
9280 "-R rtp specify the Relative Target Port\n"
9281 "-s scope specify the scope: lun, extent, element or a number\n"
9282 "-S specify Transport ID for register, requires -I\n"
9283 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n"
9284 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
9285 "-U unregister the current initiator for register_move\n"
9286 "attrib arguments:\n"
9287 "-r action specify attr_values, attr_list, lv_list, part_list, or\n"
9289 "-w attr specify an attribute to write, one -w argument per attr\n"
9290 "-a attr_num only display this attribute number\n"
9291 "-c get cached attributes\n"
9292 "-e elem_addr request attributes for the given element in a changer\n"
9293 "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n"
9294 " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
9295 " field_none, field_desc, field_num, field_size, field_rw\n"
9296 "-p partition request attributes for the given partition\n"
9297 "-s start_attr request attributes starting at the given number\n"
9298 "-T elem_type specify the element type (used with -e)\n"
9299 "-V logical_vol specify the logical volume ID\n"
9300 "opcodes arguments:\n"
9301 "-o opcode specify the individual opcode to list\n"
9302 "-s service_action specify the service action for the opcode\n"
9303 "-N do not return SCSI error for unsupported SA\n"
9304 "-T request nominal and recommended timeout values\n"
9306 "-c cmd required: rz, open, close, finish, or rwp\n"
9307 "-a apply the action to all zones\n"
9308 "-l LBA specify the zone starting LBA\n"
9309 "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n"
9310 " closed, full, ro, offline, reset, nonseq, nonwp\n"
9311 "-P print_opt report zones printing: normal, summary, script\n"
9313 "-c cmd required: restore, goto, timer, state, enable, disable,\n"
9314 " source, status, list\n"
9315 "-d disable power mode (timer, state)\n"
9316 "-D delayed entry (goto)\n"
9317 "-e enable power mode (timer, state)\n"
9318 "-H hold power mode (goto)\n"
9319 "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
9321 "-P only display power mode (status)\n"
9322 "-r rst_src restore settings from: default, saved (restore)\n"
9323 "-s save mode (timer, state, restore)\n"
9324 "-S power_src set power source: battery, nonbattery (source)\n"
9325 "-T timer set timer, seconds, .1 sec resolution (timer)\n"
9326 "timestamp arguments:\n"
9327 "-r report the timestamp of the device\n"
9328 "-f format report the timestamp of the device with the given\n"
9329 " strftime(3) format string\n"
9330 "-m report the timestamp of the device as milliseconds since\n"
9331 " January 1st, 1970\n"
9332 "-U report the time with UTC instead of the local time zone\n"
9333 "-s set the timestamp of the device\n"
9334 "-f format the format of the time string passed into strptime(3)\n"
9335 "-T time the time value passed into strptime(3)\n"
9336 "-U set the timestamp of the device to UTC time\n"
9338 #endif /* MINIMALISTIC */
9342 main(int argc, char **argv)
9345 char *device = NULL;
9347 struct cam_device *cam_dev = NULL;
9348 int timeout = 0, retry_count = 1;
9349 camcontrol_optret optreturn;
9351 const char *mainopt = "C:En:Q:t:u:v";
9352 const char *subopt = NULL;
9353 char combinedopt[256];
9354 int error = 0, optstart = 2;
9355 int task_attr = MSG_SIMPLE_Q_TAG;
9357 #ifndef MINIMALISTIC
9361 #endif /* MINIMALISTIC */
9363 cmdlist = CAM_CMD_NONE;
9364 arglist = CAM_ARG_NONE;
9372 * Get the base option.
9374 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
9376 if (optreturn == CC_OR_AMBIGUOUS) {
9377 warnx("ambiguous option %s", argv[1]);
9380 } else if (optreturn == CC_OR_NOT_FOUND) {
9381 warnx("option %s not found", argv[1]);
9387 * Ahh, getopt(3) is a pain.
9389 * This is a gross hack. There really aren't many other good
9390 * options (excuse the pun) for parsing options in a situation like
9391 * this. getopt is kinda braindead, so you end up having to run
9392 * through the options twice, and give each invocation of getopt
9393 * the option string for the other invocation.
9395 * You would think that you could just have two groups of options.
9396 * The first group would get parsed by the first invocation of
9397 * getopt, and the second group would get parsed by the second
9398 * invocation of getopt. It doesn't quite work out that way. When
9399 * the first invocation of getopt finishes, it leaves optind pointing
9400 * to the argument _after_ the first argument in the second group.
9401 * So when the second invocation of getopt comes around, it doesn't
9402 * recognize the first argument it gets and then bails out.
9404 * A nice alternative would be to have a flag for getopt that says
9405 * "just keep parsing arguments even when you encounter an unknown
9406 * argument", but there isn't one. So there's no real clean way to
9407 * easily parse two sets of arguments without having one invocation
9408 * of getopt know about the other.
9410 * Without this hack, the first invocation of getopt would work as
9411 * long as the generic arguments are first, but the second invocation
9412 * (in the subfunction) would fail in one of two ways. In the case
9413 * where you don't set optreset, it would fail because optind may be
9414 * pointing to the argument after the one it should be pointing at.
9415 * In the case where you do set optreset, and reset optind, it would
9416 * fail because getopt would run into the first set of options, which
9417 * it doesn't understand.
9419 * All of this would "sort of" work if you could somehow figure out
9420 * whether optind had been incremented one option too far. The
9421 * mechanics of that, however, are more daunting than just giving
9422 * both invocations all of the expect options for either invocation.
9424 * Needless to say, I wouldn't mind if someone invented a better
9425 * (non-GPL!) command line parsing interface than getopt. I
9426 * wouldn't mind if someone added more knobs to getopt to make it
9427 * work better. Who knows, I may talk myself into doing it someday,
9428 * if the standards weenies let me. As it is, it just leads to
9429 * hackery like this and causes people to avoid it in some cases.
9431 * KDM, September 8th, 1998
9434 sprintf(combinedopt, "%s%s", mainopt, subopt);
9436 sprintf(combinedopt, "%s", mainopt);
9439 * For these options we do not parse optional device arguments and
9440 * we do not open a passthrough device.
9442 if ((cmdlist == CAM_CMD_RESCAN)
9443 || (cmdlist == CAM_CMD_RESET)
9444 || (cmdlist == CAM_CMD_DEVTREE)
9445 || (cmdlist == CAM_CMD_USAGE)
9446 || (cmdlist == CAM_CMD_DEBUG))
9449 #ifndef MINIMALISTIC
9451 && (argc > 2 && argv[2][0] != '-')) {
9455 if (isdigit(argv[2][0])) {
9456 /* device specified as bus:target[:lun] */
9457 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
9459 errx(1, "numeric device specification must "
9460 "be either bus:target, or "
9462 /* default to 0 if lun was not specified */
9463 if ((arglist & CAM_ARG_LUN) == 0) {
9465 arglist |= CAM_ARG_LUN;
9469 if (cam_get_device(argv[2], name, sizeof name, &unit)
9471 errx(1, "%s", cam_errbuf);
9472 device = strdup(name);
9473 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
9477 #endif /* MINIMALISTIC */
9479 * Start getopt processing at argv[2/3], since we've already
9480 * accepted argv[1..2] as the command name, and as a possible
9486 * Now we run through the argument list looking for generic
9487 * options, and ignoring options that possibly belong to
9490 while ((c = getopt(argc, argv, combinedopt))!= -1){
9493 retry_count = strtol(optarg, NULL, 0);
9494 if (retry_count < 0)
9495 errx(1, "retry count %d is < 0",
9497 arglist |= CAM_ARG_RETRIES;
9500 arglist |= CAM_ARG_ERR_RECOVER;
9503 arglist |= CAM_ARG_DEVICE;
9505 while (isspace(*tstr) && (*tstr != '\0'))
9507 device = (char *)strdup(tstr);
9511 int table_entry = 0;
9514 while (isspace(*tstr) && (*tstr != '\0'))
9516 if (isdigit(*tstr)) {
9517 task_attr = strtol(tstr, &endptr, 0);
9518 if (*endptr != '\0') {
9519 errx(1, "Invalid queue option "
9524 scsi_nv_status status;
9526 table_size = sizeof(task_attrs) /
9527 sizeof(task_attrs[0]);
9528 status = scsi_get_nv(task_attrs,
9529 table_size, tstr, &table_entry,
9530 SCSI_NV_FLAG_IG_CASE);
9531 if (status == SCSI_NV_FOUND)
9532 task_attr = task_attrs[
9535 errx(1, "%s option %s",
9536 (status == SCSI_NV_AMBIGUOUS)?
9537 "ambiguous" : "invalid",
9544 timeout = strtol(optarg, NULL, 0);
9546 errx(1, "invalid timeout %d", timeout);
9547 /* Convert the timeout from seconds to ms */
9549 arglist |= CAM_ARG_TIMEOUT;
9552 arglist |= CAM_ARG_UNIT;
9553 unit = strtol(optarg, NULL, 0);
9556 arglist |= CAM_ARG_VERBOSE;
9563 #ifndef MINIMALISTIC
9565 * For most commands we'll want to open the passthrough device
9566 * associated with the specified device. In the case of the rescan
9567 * commands, we don't use a passthrough device at all, just the
9568 * transport layer device.
9571 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
9572 && (((arglist & CAM_ARG_DEVICE) == 0)
9573 || ((arglist & CAM_ARG_UNIT) == 0))) {
9574 errx(1, "subcommand \"%s\" requires a valid device "
9575 "identifier", argv[1]);
9578 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
9579 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
9580 cam_open_spec_device(device,unit,O_RDWR,NULL)))
9582 errx(1,"%s", cam_errbuf);
9584 #endif /* MINIMALISTIC */
9587 * Reset optind to 2, and reset getopt, so these routines can parse
9588 * the arguments again.
9594 #ifndef MINIMALISTIC
9595 case CAM_CMD_DEVLIST:
9596 error = getdevlist(cam_dev);
9599 error = atahpa(cam_dev, retry_count, timeout,
9600 argc, argv, combinedopt);
9602 #endif /* MINIMALISTIC */
9603 case CAM_CMD_DEVTREE:
9604 error = getdevtree(argc, argv, combinedopt);
9606 #ifndef MINIMALISTIC
9608 error = testunitready(cam_dev, task_attr, retry_count,
9611 case CAM_CMD_INQUIRY:
9612 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
9613 task_attr, retry_count, timeout);
9615 case CAM_CMD_IDENTIFY:
9616 error = ataidentify(cam_dev, retry_count, timeout);
9618 case CAM_CMD_STARTSTOP:
9619 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
9620 arglist & CAM_ARG_EJECT, task_attr,
9621 retry_count, timeout);
9623 #endif /* MINIMALISTIC */
9624 case CAM_CMD_RESCAN:
9625 error = dorescan_or_reset(argc, argv, 1);
9628 error = dorescan_or_reset(argc, argv, 0);
9630 #ifndef MINIMALISTIC
9631 case CAM_CMD_READ_DEFECTS:
9632 error = readdefects(cam_dev, argc, argv, combinedopt,
9633 task_attr, retry_count, timeout);
9635 case CAM_CMD_MODE_PAGE:
9636 modepage(cam_dev, argc, argv, combinedopt,
9637 task_attr, retry_count, timeout);
9639 case CAM_CMD_SCSI_CMD:
9640 error = scsicmd(cam_dev, argc, argv, combinedopt,
9641 task_attr, retry_count, timeout);
9643 case CAM_CMD_SMP_CMD:
9644 error = smpcmd(cam_dev, argc, argv, combinedopt,
9645 retry_count, timeout);
9647 case CAM_CMD_SMP_RG:
9648 error = smpreportgeneral(cam_dev, argc, argv,
9649 combinedopt, retry_count,
9652 case CAM_CMD_SMP_PC:
9653 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
9654 retry_count, timeout);
9656 case CAM_CMD_SMP_PHYLIST:
9657 error = smpphylist(cam_dev, argc, argv, combinedopt,
9658 retry_count, timeout);
9660 case CAM_CMD_SMP_MANINFO:
9661 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
9662 retry_count, timeout);
9665 error = camdebug(argc, argv, combinedopt);
9668 error = tagcontrol(cam_dev, argc, argv, combinedopt);
9671 error = ratecontrol(cam_dev, task_attr, retry_count,
9672 timeout, argc, argv, combinedopt);
9674 case CAM_CMD_FORMAT:
9675 error = scsiformat(cam_dev, argc, argv,
9676 combinedopt, task_attr, retry_count,
9679 case CAM_CMD_REPORTLUNS:
9680 error = scsireportluns(cam_dev, argc, argv,
9681 combinedopt, task_attr,
9682 retry_count, timeout);
9684 case CAM_CMD_READCAP:
9685 error = scsireadcapacity(cam_dev, argc, argv,
9686 combinedopt, task_attr,
9687 retry_count, timeout);
9690 case CAM_CMD_STANDBY:
9692 error = atapm(cam_dev, argc, argv,
9693 combinedopt, retry_count, timeout);
9697 error = ataaxm(cam_dev, argc, argv,
9698 combinedopt, retry_count, timeout);
9700 case CAM_CMD_SECURITY:
9701 error = atasecurity(cam_dev, retry_count, timeout,
9702 argc, argv, combinedopt);
9704 case CAM_CMD_DOWNLOAD_FW:
9705 error = fwdownload(cam_dev, argc, argv, combinedopt,
9706 arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
9709 case CAM_CMD_SANITIZE:
9710 error = scsisanitize(cam_dev, argc, argv,
9711 combinedopt, task_attr,
9712 retry_count, timeout);
9714 case CAM_CMD_PERSIST:
9715 error = scsipersist(cam_dev, argc, argv, combinedopt,
9716 task_attr, retry_count, timeout,
9717 arglist & CAM_ARG_VERBOSE,
9718 arglist & CAM_ARG_ERR_RECOVER);
9720 case CAM_CMD_ATTRIB:
9721 error = scsiattrib(cam_dev, argc, argv, combinedopt,
9722 task_attr, retry_count, timeout,
9723 arglist & CAM_ARG_VERBOSE,
9724 arglist & CAM_ARG_ERR_RECOVER);
9726 case CAM_CMD_OPCODES:
9727 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
9728 task_attr, retry_count, timeout,
9729 arglist & CAM_ARG_VERBOSE);
9731 case CAM_CMD_REPROBE:
9732 error = scsireprobe(cam_dev);
9735 error = zone(cam_dev, argc, argv, combinedopt,
9736 task_attr, retry_count, timeout,
9737 arglist & CAM_ARG_VERBOSE);
9740 error = epc(cam_dev, argc, argv, combinedopt,
9741 retry_count, timeout, arglist & CAM_ARG_VERBOSE);
9743 case CAM_CMD_TIMESTAMP:
9744 error = timestamp(cam_dev, argc, argv, combinedopt,
9745 task_attr, retry_count, timeout,
9746 arglist & CAM_ARG_VERBOSE);
9748 #endif /* MINIMALISTIC */
9758 if (cam_dev != NULL)
9759 cam_close_device(cam_dev);